Skip to content
Kong Docs are moving soon! Our docs are migrating to a new home. You'll be automatically redirected to the new site in the future. In the meantime, view this page on the new site!
Kong Logo | Kong Docs Logo
  • Docs
    • Explore the API Specs
      View all API Specs View all API Specs View all API Specs arrow image
    • Documentation
      API Specs
      Kong Gateway
      Lightweight, fast, and flexible cloud-native API gateway
      Kong Konnect
      Single platform for SaaS end-to-end connectivity
      Kong AI Gateway
      Multi-LLM AI Gateway for GenAI infrastructure
      Kong Mesh
      Enterprise service mesh based on Kuma and Envoy
      decK
      Helps manage Kong’s configuration in a declarative fashion
      Kong Ingress Controller
      Works inside a Kubernetes cluster and configures Kong to proxy traffic
      Kong Gateway Operator
      Manage your Kong deployments on Kubernetes using YAML Manifests
      Insomnia
      Collaborative API development platform
  • Plugin Hub
    • Explore the Plugin Hub
      View all plugins View all plugins View all plugins arrow image
    • Functionality View all View all arrow image
      View all plugins
      AI's icon
      AI
      Govern, secure, and control AI traffic with multi-LLM AI Gateway plugins
      Authentication's icon
      Authentication
      Protect your services with an authentication layer
      Security's icon
      Security
      Protect your services with additional security layer
      Traffic Control's icon
      Traffic Control
      Manage, throttle and restrict inbound and outbound API traffic
      Serverless's icon
      Serverless
      Invoke serverless functions in combination with other plugins
      Analytics & Monitoring's icon
      Analytics & Monitoring
      Visualize, inspect and monitor APIs and microservices traffic
      Transformations's icon
      Transformations
      Transform request and responses on the fly on Kong
      Logging's icon
      Logging
      Log request and response data using the best transport for your infrastructure
  • Support
  • Community
  • Kong Academy
Get a Demo Start Free Trial
Kong Gateway
2.8.x LTS
  • Home icon
  • Kong Gateway
  • Plugin Development
  • Plugin Development - Implementing Custom Logic
github-edit-pageEdit this page
report-issueReport an issue
  • Kong Gateway
  • Kong Konnect
  • Kong Mesh
  • Kong AI Gateway
  • Plugin Hub
  • decK
  • Kong Ingress Controller
  • Kong Gateway Operator
  • Insomnia
  • Kuma

  • Docs contribution guidelines
  • 3.10.x (latest)
  • 3.9.x
  • 3.8.x
  • 3.7.x
  • 3.6.x
  • 3.5.x
  • 3.4.x (LTS)
  • 3.3.x
  • 2.8.x (LTS)
  • Archive (3.0.x and pre-2.8.x)
  • Introduction
    • Overview of Kong Gateway
    • Version Support Policy
    • Stages of Software Availability
    • Changelog
  • Install and Run
    • Overview
    • Kubernetes
    • Helm
    • OpenShift with Helm
    • Docker
    • Amazon Linux
    • CentOS
    • Debian
    • RHEL
    • Ubuntu
    • Migrating from OSS to EE
    • Upgrade Kong Gateway
    • Upgrade Kong Gateway OSS
    • Upgrade from 2.8 LTS to 3.4 LTS
  • Get Started
    • Quickstart Guide
      • Configuring a Service
      • Configuring a gRPC Service
      • Enabling Plugins
      • Adding Consumers
    • Comprehensive Guide
      • Prepare to Administer
      • Expose your Services
      • Protect your Services
      • Improve Performance
      • Secure Services
      • Set Up Intelligent Load Balancing
      • Manage Administrative Teams
      • Publish, Locate, and Consume Services
  • Plan and Deploy
    • Running Kong as a Non-Root User
    • Resource Sizing Guidelines
    • Hybrid Mode
      • Deploy Kong Gateway in Hybrid Mode
    • Kubernetes Deployment Options
    • Control Kong Gateway through systemd
    • Performance Testing Framework
    • DNS Considerations
    • Default Ports
    • Licenses
      • Access Your License
      • Deploy Your License
      • Monitor License Usage
    • Security
      • Start Kong Gateway Securely
      • Keyring and Data Encryption
      • Kong Security Update Process
      • Secrets Management
        • Getting Started
        • Advanced Usage
        • Backends
          • Environment Variables
          • AWS Secrets Manager
          • GCP Secret Manager
          • HashiCorp Vault
        • Reference Format
  • Configure
    • Authentication and Authorization
      • Authentication Reference
      • OpenID Connect Plugin
        • OpenID Connect with Curity
        • OpenID Connect with Azure AD
        • OpenID Connect with Google
        • OpenID Connect with Okta
        • OpenID Connect with Auth0
        • OpenID Connect with Cognito
        • OpenID Connect Plugin Reference
      • Allowing Multiple Authentication Methods
      • Auth for Kong Manager
        • Create a Super Admin
        • Configure Networking
        • Configure Kong Manager to Send Email
        • Reset Passwords and RBAC Tokens
        • Configure Workspaces
        • Basic Auth
        • LDAP
        • OIDC
        • Sessions
      • Role-based Access Control (RBAC)
        • Add a Role
        • Add a User
        • Add an Admin
      • Mapping LDAP Service Directory Groups to Kong Roles
    • Configure gRPC Plugins
    • GraphQL Quickstart
    • Logging Reference
    • Network and Firewall
  • Dev Portal
    • Overview
    • Enable the Dev Portal
    • Structure and File Types
    • Portal API Documentation
    • Working with Templates
    • Using the Editor
    • Configuration
      • Authentication
        • Basic Auth
        • Key Auth
        • OIDC
        • Sessions
        • Adding Custom Registration Fields
      • SMTP
      • Workspaces
    • Administration
      • Manage Developers
      • Developer Roles and Content Permissions
      • Application Registration
        • Authorization Provider Strategy
        • Enable Application Registration
        • Enable Key Authentication for Application Registration
        • External OAuth2 Support
        • Set up Okta and Kong for external OAuth
        • Set Up Azure AD and Kong for External Authentication
        • Manage Applications
    • Customization
      • Easy Theme Editing
      • Migrating Templates Between Workspaces
      • Markdown Rendering Module
      • Customizing Portal Emails
      • Adding and Using JavaScript Assets
      • Single Page App in Dev Portal
      • Alternate OpenAPI Renderer
    • Helpers CLI
  • Monitor
    • Kong Vitals
      • Metrics
      • Reports
      • Vitals with InfluxDB
      • Vitals with Prometheus
      • Estimate Vitals Storage in PostgreSQL
    • Prometheus plugin
    • Zipkin plugin
  • Reference
    • Admin API
      • DB-less Mode
      • Declarative Configuration
      • Supported Content Types
      • Information Routes
      • Health Routes
      • Tags
      • Service Object
      • Route Object
      • Consumer Object
      • Plugin Object
      • Certificate Object
      • CA Certificate Object
      • SNI Object
      • Upstream Object
      • Target Object
      • Vaults Beta
      • Licenses
        • Licenses Reference
        • Licenses Examples
      • Workspaces
        • Workspaces Reference
        • Workspace Examples
      • RBAC
        • RBAC Reference
        • RBAC Examples
      • Admins
        • API Reference
        • Examples
      • Developers
      • Consumer Groups
        • API Reference
        • Examples
      • Event Hooks
        • Event Hooks Reference
        • Examples
      • Audit Logging
      • Keyring and Data Encryption
      • Securing the Admin API
    • DB-less and Declarative Configuration
    • Configuration Reference
    • CLI Reference
    • Load Balancing Reference
    • Proxy Reference
    • Rate Limiting Library
    • Health Checks and Circuit Breakers Reference
    • Clustering Reference
    • Plugin Development Kit
      • kong.client
      • kong.client.tls
      • kong.cluster
      • kong.ctx
      • kong.ip
      • kong.log
      • kong.nginx
      • kong.node
      • kong.request
      • kong.response
      • kong.router
      • kong.service
      • kong.service.request
      • kong.service.response
      • kong.table
      • kong.vault
    • Plugin Development Guide
      • Introduction
      • File structure
      • Implementing custom logic
      • Plugin configuration
      • Accessing the datastore
      • Storing custom entities
      • Caching custom entities
      • Extending the Admin API
      • Writing tests
      • (un)Installing your plugin
    • Plugins in Other Languages
    • File Permissions Reference
enterprise-switcher-icon Switch to OSS
On this pageOn this page
  • Module
  • Available contexts
  • handler.lua specifications
    • Migrating from BasePlugin module
  • Plugin Development Kit
  • Plugins execution order
You are browsing documentation for an older version. See the latest documentation here.

Plugin Development - Implementing Custom Logic

Note: This chapter assumes that you are familiar with Lua.

A Kong Gateway plugin allows you to inject custom logic (in Lua) at several entry-points in the life-cycle of a request/response or a tcp stream connection as it is proxied by Kong Gateway. To do so, the file kong.plugins.<plugin_name>.handler must return a table with one or more functions with predetermined names. Those functions will be invoked by Kong Gateway at different phases when it processes traffic.

The first parameter they take is always self. All functions except init_worker can receive a second parameter which is a table with the plugin configuration.

Module

kong.plugins.<plugin_name>.handler

Available contexts

If you define any of the following functions in your handler.lua file you’ll implement custom logic at various entry-points of Kong Gateway’s execution life-cycle:

  • HTTP Module is used for plugins written for HTTP/HTTPS requests
Function name Phase Description
init_worker init_worker Executed upon every Nginx worker process’s startup.
certificate ssl_certificate Executed during the SSL certificate serving phase of the SSL handshake.
rewrite rewrite Executed for every request upon its reception from a client as a rewrite phase handler.
In this phase, neither the Service nor the Consumer have been identified, hence this handler will only be executed if the plugin was configured as a global plugin.
access access Executed for every request from a client and before it is being proxied to the upstream service.
response access Replaces both header_filter() and body_filter(). Executed after the whole response has been received from the upstream service, but before sending any part of it to the client.
header_filter header_filter Executed when all response headers bytes have been received from the upstream service.
body_filter body_filter Executed for each chunk of the response body received from the upstream service. Since the response is streamed back to the client, it can exceed the buffer size and be streamed chunk by chunk. This function can be called multiple times if the response is large. See the lua-nginx-module documentation for more details.
log log Executed when the last response byte has been sent to the client.

Note: If a module implements the response function, Kong Gateway will automatically activate the “buffered proxy” mode, as if the kong.service.request.enable_buffering() function had been called. Because of a current Nginx limitation, this doesn’t work for HTTP/2 or gRPC upstreams.

To reduce unexpected behaviour changes, Kong Gateway does not start if a plugin implements both response and either header_filter or body_filter.

  • Stream Module is used for Plugins written for TCP and UDP stream connections
Function name Phase Description
init_worker init_worker Executed upon every Nginx worker process’s startup.
preread preread Executed once for every connection.
log log Executed once for each connection after it has been closed.
certificate ssl_certificate Executed during the SSL certificate serving phase of the SSL handshake.

All of those functions, except init_worker, take one parameter which is given by Kong Gateway upon its invocation: the configuration of your plugin. This parameter is a Lua table, and contains values defined by your users, according to your plugin’s schema (described in the schema.lua module). More on plugins schemas in the next chapter.

Note that UDP streams don’t have real connections. Kong Gateway will consider all packets with the same origin and destination host and port as a single connection. After a configurable time without any packet, the connection is considered closed and the log function is executed.

handler.lua specifications

Kong Gateway processes requests in phases. A plugin is a piece of code that gets activated by Kong Gateway as each phase is executed while the request gets proxied.

Phases are limited in what they can do. For example, the init_worker phase does not have access to the config parameter because that information isn’t available when kong is initializing each worker.

A plugin’s handler.lua must return a table containing the functions it must execute on each phase.

Kong Gateway can process HTTP and stream traffic. Some phases are executed only when processing HTTP traffic, others when processing stream, and some (like init_worker and log) are invoked by both kinds of traffic.

In addition to functions, a plugin must define two fields:

  • VERSION is an informative field, not used by Kong Gateway directly. It usually matches the version defined in a plugin’s Rockspec version, when it exists.
  • PRIORITY is used to sort plugins before executing each of their phases. Plugins with a higher priority are executed first. See the plugin execution order below for more info about this field.

The following example handler.lua file defines custom functions for all the possible phases, in both http and stream traffic. It has no functionality besides writing a message to the log every time a phase is invoked. Note that a plugin doesn’t need to provide functions for all phases.

local CustomHandler = {
  VERSION  = "1.0.0",
  PRIORITY = 10,
}

function CustomHandler:init_worker()
  -- Implement logic for the init_worker phase here (http/stream)
  kong.log("init_worker")
end


function CustomHandler:preread(config)
  -- Implement logic for the preread phase here (stream)
  kong.log("preread")
end


function CustomHandler:certificate(config)
  -- Implement logic for the certificate phase here (http/stream)
  kong.log("certificate")
end

function CustomHandler:rewrite(config)
  -- Implement logic for the rewrite phase here (http)
  kong.log("rewrite")
end

function CustomHandler:access(config)
  -- Implement logic for the rewrite phase here (http)
  kong.log("access")
end

function CustomHandler:header_filter(config)
  -- Implement logic for the header_filter phase here (http)
  kong.log("header_filter")
end

function CustomHandler:body_filter(config)
  -- Implement logic for the body_filter phase here (http)
  kong.log("body_filter")
end

function CustomHandler:log(config)
  -- Implement logic for the log phase here (http/stream)
  kong.log("log")
end

-- return the created table, so that Kong can execute it
return CustomHandler

Note that in the example above we are using Lua’s : shorthand syntax for functions taking self as a first parameter. An equivalent unshortened version of the access function would be:

function CustomHandler.access(self, config)
  -- Implement logic for the rewrite phase here (http)
  kong.log("access")
end

Migrating from BasePlugin module

The BasePlugin module is deprecated and will be removed in a future version of Kong Gateway. If you have an old plugin that uses it, replace the initial part:

--  DEPRECATED --
local BasePlugin = require "kong.plugins.base_plugin"
local CustomHandler = BasePlugin:extend()
CustomHandler.VERSION  = "1.0.0"
CustomHandler.PRIORITY = 10

with the current equivalent:

local CustomHandler = {
  VERSION  = "1.0.0",
  PRIORITY = 10,
}

You don’t need to add a :new() method or call any of the CustomHandler.super.XXX:(self) methods.

The plugin’s logic doesn’t need to be all defined inside the handler.lua file. It can be split into several Lua files (also called modules). The handler.lua module can use require to include other modules in your plugin.

For example, the following plugin splits the functionality into three files. access.lua and body_filter.lua return functions. They are in the same folder as handler.lua, which requires and uses them to build the plugin:

-- handler.lua
local access = require "kong.plugins.my-custom-plugin.access"
local body_filter = require "kong.plugins.my-custom-plugin.body_filter"

local CustomHandler = {
  VERSION  = "1.0.0",
  PRIORITY = 10
}

CustomHandler.access = access
CustomHandler.body_filter = body_filter

return CustomHandler
-- access.lua
return function(self, config)
  kong.log("access phase")
end
-- body_filter.lua
return function(self, config)
  kong.log("body_filter phase")
end

See the source code of the Key-Auth Plugin for an example of a real-life handler code.

Plugin Development Kit

Logic implemented in those phases will most likely have to interact with the request/response objects or core components (e.g. access the cache, and database). Kong Gateway provides a Plugin Development Kit (or “PDK”) for such purposes: a set of Lua functions and variables that can be used by Plugins to execute various gateway operations in a way that is guaranteed to be forward-compatible with future releases of Kong Gateway.

When you are trying to implement some logic that needs to interact with Kong Gateway (e.g. retrieving request headers, producing a response from a plugin, logging some error or debug information), you should consult the Plugin Development Kit Reference.

Plugins execution order

Some plugins might depend on the execution of others to perform some operations. For example, plugins relying on the identity of the consumer have to run after authentication plugins. Considering this, Kong Gateway defines priorities between plugins execution to ensure that order is respected.

Your plugin’s priority can be configured via a property accepting a number in the returned handler table:

CustomHandler.PRIORITY = 10

The higher the priority, the sooner your plugin’s phases will be executed in regard to other plugins’ phases (such as :access(), :log(), etc.).

Open-source or Free mode
Enterprise

The following list includes all plugins bundled with open-source Kong Gateway or Kong Gateway running in Free mode.

Note: The correlation-id plugin’s execution order is different depending on whether you’re running Kong Gateway in Free mode or using the open-source package.

The current order of execution for the bundled plugins is:

Plugin Priority
pre-function +inf
correlation-id
Available in Enterprise Free mode (without a license)
100001
zipkin 100000
bot-detection 2500
cors 2000
session 1900
jwt 1005
oauth2 1004
key-auth 1003
ldap-auth 1002
basic-auth 1001
hmac-auth 1000
grpc-gateway 998
ip-restriction 990
request-size-limiting 951
acl 950
rate-limiting 901
response-ratelimiting 900
request-transformer 801
response-transformer 800
aws-lambda 750
azure-functions 749
prometheus 13
http-log 12
statsd 11
datadog 10
file-log 9
udp-log 8
tcp-log 7
loggly 6
syslog 4
grpc-web 3
request-termination 2
correlation-id
Free open-source plugin
1
post-function -1000

The following list includes all plugins bundled with a Kong Gateway Enterprise subscription.

The current order of execution for the bundled plugins is:

Plugin Priority
pre-function +inf
correlation-id 100001
zipkin 100000
exit-transformer 9999
bot-detection 2500
cors 2000
route-by-header 2000
session 1900
oauth2-introspection 1700
acme 1007
mtls-auth 1006
jwt 1005
degraphql 1005
oauth2 1004
vault-auth 1003
key-auth 1003
key-auth-enc 1003
ldap-auth 1002
ldap-auth-advanced 1002
basic-auth 1001
openid-connect 1000
hmac-auth 1000
request-validator 999
jwt-signer 999
grpc-gateway 998
application-registration 995
ip-restriction 990
request-size-limiting 951
acl 950
opa 920
rate-limiting-advanced 902
graphql-rate-limiting-advanced 902
rate-limiting 901
response-ratelimiting 900
jq 811
request-transformer-advanced 802
request-transformer 801
response-transformer-advanced 800
route-transformer-advanced 800
response-transformer 800
kafka-upstream 751
aws-lambda 750
azure-functions 749
graphql-proxy-cache-advanced 100
proxy-cache-advanced 100
proxy-cache 100
forward-proxy 50
prometheus 13
canary 13
http-log 12
statsd 11
statsd-advanced 11
datadog 10
file-log 9
udp-log 8
tcp-log 7
loggly 6
kafka-log 5
syslog 4
grpc-web 3
request-termination 2
mocking -1
post-function -1000

Previous Plugin Development - File Structure
Next Plugin Development - Plugin Configuration
Thank you for your feedback.
Was this page useful?
Too much on your plate? close cta icon
More features, less infrastructure with Kong Konnect. 1M requests per month for free.
Try it for Free
  • Kong
    Powering the API world

    Increase developer productivity, security, and performance at scale with the unified platform for API management, service mesh, and ingress controller.

    • Products
      • Kong Konnect
      • Kong Gateway Enterprise
      • Kong Gateway
      • Kong Mesh
      • Kong Ingress Controller
      • Kong Insomnia
      • Product Updates
      • Get Started
    • Documentation
      • Kong Konnect Docs
      • Kong Gateway Docs
      • Kong Mesh Docs
      • Kong Insomnia Docs
      • Kong Konnect Plugin Hub
    • Open Source
      • Kong Gateway
      • Kuma
      • Insomnia
      • Kong Community
    • Company
      • About Kong
      • Customers
      • Careers
      • Press
      • Events
      • Contact
  • Terms• Privacy• Trust and Compliance
© Kong Inc. 2025