Apache APISIX

Open Sourced API Gateway

Apache APISIX is full featured yet fully open sourced. It is built on top of OpenResty, which in turn is built on top of Nginx.

Minimum free features required by Team Compute:

  1. OIDC for browser access
  2. Token for API access
  3. Call out to external APIs

1. References

APISIX Alternatives:

2. Phases

Apache APISIX, built on OpenResty (which in turn builds on Nginx), leverages a phase-based execution model for handling HTTP requests and executing plugins. These phases define distinct stages in the request lifecycle where specific actions or plugin logic can be applied. The primary APISIX phases are:

rewrite

This phase is typically used for request URI manipulation, such as rewriting paths, adding or modifying request headers, or performing redirects. Plugins in this phase can alter the request before it reaches the upstream service.

access

This phase is dedicated to access control and authentication. Plugins here can verify client credentials, enforce rate limits, or perform other authorization checks to determine if the request should be allowed to proceed to the upstream.

before_proxy

This phase is executed just before the request is proxied to the upstream server. It allows for final modifications to the request or for performing actions that need to happen immediately before the proxying action.

header_filter

This phase is executed after the upstream server responds but before the response headers are sent back to the client. Plugins in this phase can modify or add response headers.

body_filter

This phase is executed after the upstream server responds and allows for modification of the response body before it is sent back to the client. This is useful for tasks like compression or data transformation.

log

This final phase is used for logging and observability. Plugins here can record request and response details, send logs to external systems, or perform other post-processing tasks that do not affect the response content.

Plugins are executed within these phases, and their execution order within a specific phase can be further managed by defining a priority value in the plugin's metadata. Plugins with higher priority values are executed first within the same phase. The order of the phases themselves is fixed and follows the sequence described above.

Priorities

Within each phase above, the plugins are ran in sequence according to their "Priority".

Plugins

APISIX is plugin and lua driven

Features APISIX Plugins
OIDC Login Flow openid-connect plugin
JWT validation jwt-auth plugin
External webhook checks forward-auth plugin

The plugins are activated alone APISIX’s phases (init, rewrite, access, header_filter, body_filter, log) instead of having to modifying phases in nginx.conf.

Each plugin as a priroirty with each phases and can be turned on or off independently for each route.

Serverless Plugins

APISIX provides dedicated plugins like serverless-pre-function and serverless-post-function that allow the execution of custom code (e.g., Lua scripts) at specific phases of the request lifecycle. This enables dynamic behavior and custom logic within the API gateway itself, without managing separate serverless functions.

So we can write lua logic using these plugins e.g.

{
  "uri": "/test",
  "plugins": {
    "serverless-pre-function": {
      "phase": "rewrite",
      "functions": [
        "return function(conf, ctx) ngx.say('hello from Lua') end"
      ]
    }
  },
  "upstream": { "type": "roundrobin", "nodes": { "127.0.0.1:80": 1 } }
}

although writing a full plugin and put it inside config.yaml is not hard e.g.

-- apisix/plugins/myplugin.lua
local plugin_name = "myplugin"
local schema = { type = "object", properties = { msg = { type = "string" } } }

local _M = { version = 0.1, priority = 10, name = plugin_name, schema = schema }

function _M.access(conf, ctx)
    ngx.say("Message: ", conf.msg)
end

return _M

Good observation — at first glance, serverless plugins and custom Lua plugins in APISIX look very similar, since both let you run Lua code. The real difference is in scope, lifecycle, and maintenance.

Advantages of serverless plugins

  • Quick experiment
    Drop a Lua snippet straight into a route definition — no need to package, register, or restart APISIX. Great for testing logic, debugging, or trying out a new header rewrite.

  • Per-route logic
    You can attach tiny Lua functions only on the routes that need them, without introducing a new global plugin for every small case.

  • Hot updates
    Because it’s just config data, you can push an updated route with a new Lua snippet via the Admin API. No need to reload APISIX or redeploy custom plugins.

  • Lower barrier for “one-off” rules
    If all you want is “on this route, log X” or “add a header if query=foo”, a serverless-pre-function with a few lines of Lua is easier than scaffolding a plugin.

Disadvantages of serverless plugins

  • Messier for bigger logic
    If the snippet grows beyond a few lines, it quickly becomes unmaintainable. No schema validation, no clear lifecycle hooks, no code reuse.

  • Performance
    Custom plugins can be optimized, loaded once, and reused. Serverless code is parsed/loaded from config, so heavy use across many routes can be less efficient.

  • Observability & testing
    Serverless snippets don’t show up as first-class plugins in dashboards/logs. Harder to test or version-control cleanly compared to a proper plugin file.

  • Reusability
    A serverless snippet is tied to a route. A custom plugin can be enabled across many routes with consistent behavior.

References:

Mutual TLS

Besides checking standard TLS server certificates, APISIX can also check for mTLS client certificatec.

APISIX can be configured to check client certificates by enabling Mutual TLS (mTLS). This involves configuring APISIX to require and verify client certificates during the TLS handshake.

Steps to configure APISIX for client certificate checking:

Generate Certificates.

Generate a Certificate Authority (CA) certificate, a server certificate signed by the CA, and a client certificate also signed by the CA. This can be done using tools like OpenSSL. Configure SSL Object in APISIX.

Use the APISIX Admin API to create an SSL object. When creating this object, you need to provide:

  • sni: The domain name (CN) of the server certificate.

  • cert: The server certificate.

  • key: The private key of the server certificate.

  • client.ca: The CA certificate used to sign the client certificates. APISIX will use this to verify the client's presented certificate.

Example using curl to configure the SSL object:

Code

    curl -i http://127.0.0.1:9180/apisix/admin/ssls/1 \    -H 'X-API-KEY: <your_admin_key>' -X PUT -d '    {        "sni": "test.com",        "cert": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",        "key": "-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----",        "client": {            "ca": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----"        }    }'

Configure Routes.

Create or modify a route in APISIX to use the SSL object configured in the previous step. This ensures that requests matching this route will trigger the mTLS handshake and client certificate verification. Client Request with Certificate.

When a client makes a request to APISIX for a route protected by mTLS, it must present its own certificate and private key during the TLS handshake.

Example using curl to send a request with a client certificate:

Code

    curl -ikv --resolve "test.com:9443:127.0.0.1" "https://test.com:9443/ip" \    --cert client.crt --key client.key

Important Considerations:

  • Certificate Management: Ensure secure handling and storage of certificates and private keys.
  • CA Certificate: The client.ca specified in the SSL object is crucial for APISIX to trust and verify client certificates.
  • mTLS Bypass: APISIX allows configuring URI whitelists to bypass mTLS for specific paths, if needed. This can be useful for health checks or public endpoints that do not require client certificate authentication.

Keycloak

Safeline

Activity Marker

An APISIX Global Rule that always runs first a small plugin on every request. The plugin calls a scanner to scan the URL and take action (block/route/annotate) based on the scanner’s verdict.