Custom Plugin Development
One of Kong's biggest benefits is the ability to extend the platform. Any custom logic can be added during the lifecycle of a request or response as it is proxied through Kong. For this scenario, let's implement a custom plugin named "custom-auth." If you're new to Kong custom plugins, they are fairly straightforward to implement. A plugin requires minimally two files: schema.lua and handler.lua. You may optionally implement business logic in other Lua files, which can be loaded by handler.lua to make your code more modular and manageable. For the "custom-auth" plugin, let's create the following structure.
- schema.lua: Your plugin probably has to retain some configuration entered by the user. This module holds the schema of that configuration and defines rules on it so that the user can only enter valid configuration values.
- handler.lua: This is the core of your plugin. It is an interface to implement, in which each function will be run at the desired moment in the lifecycle of a request/connection.
Below are further code details and explanations for each.
Schema.lua:
In this case, we have defined three parameters to configure, including token introspection endpoint, permission checking endpoint and header name from where to get the JWT token. All three parameters are mandatory in this case (required = true). We have also added the logic to validate if the endpoints are entered in proper URL format.
handler.lua:
This file contains the actual logic to perform token introspection and permission check by interacting with the custom authentication service. The main function that will be executed first is access(conf). It will check if there is an Authorization token in the HTTP request header. If not, it will return an error; otherwise, it will continue to invoke the next function, introspect_access_token(conf, access_token, customer_id), where the authentication and authorization endpoints of the custom auth service will be executed in sequence to determine if the user has valid access token and correct access permission to view the customer's details.
Configuration and Testing
Let's now try to deploy the custom plugin to Kong Enterprise and test it. First, we will create a folder named "custom-auth" under the directory /usr/local/share/lua/5.1/kong/plugins. You can find other out-of-the-box plugins here, which serve as good reference implementations. Sometimes you may find it convenient to replicate one of the plugins and modify its behavior when necessary. The directory structure looks like the following:
Next, we will configure Kong Enterprise to load this plugin by setting the following property in /etc/kong/kong.conf file and then restart the Kong instance.
If you are running Kong Enterprise in a container environment, you can package the plugin and rebuild the docker image, and then configure the plugins setting via KONG_PLUGINS environment variable.
Now, you should be able to find the custom plugin at the bottom of the plugins page. You can enable this plugin on the service or route that you are trying to protect from unauthorized access.

Below are sample test results to verify this plugin is working properly.
- Query returns 200 status code if a valid token is provided in the header and the user access.
2. Query returns 401 unauthorized error if the token is not valid, which means the authentication check failed.
3. The query returns 401 unauthorized error if the user doesn't have access.
Conclusion
Kong's platform can be easily extended and integrated with custom, external systems by implementing custom plugins. This allows Kong to easily integrate with any existing systems to address current requirements as well as address future custom requirements that may arise. This benefit is one of the main reasons customers choose Kong. In this write up, we covered how Kong Enterprise can be integrated with a third-party access control system, but it's quite straightforward to integrate with any external system or have Kong perform any logic as part of the request/response lifecycle. I hope you have enjoyed reading this blog post. If you have any interesting ideas and use cases, we welcome your feedback.