Appearance
APISIX Plugin Reference
Gatez uses Apache APISIX 3.11 as the L1 API Gateway. 37 plugins are enabled — 4 custom Gatez plugins and 33 built-in APISIX plugins.
Plugins are configured in layers/api-gateway/config/apisix.yaml and attached to routes either automatically (by the CP API) or manually (via the operator portal plugin catalog).
Plugin Tiers
| Tier | Count | Behavior |
|---|---|---|
| Auto-applied | 5 | Injected on every route by the CP API. Cannot be disabled. Provide observability and multi-tenancy. |
| User-selectable | 28 | Available in the operator portal route creation modal. Operator chooses which to enable per route. |
Auto-Applied Plugins
These plugins are automatically injected by the Control Plane API (default_route_plugins() in routes.rs) when any route is created. They ensure every request is logged, traced, and rate-limited.
clickhouse-logger (Custom)
Async batch logging of every request to ClickHouse. Powers the Analytics page in the operator portal.
Phase: log (runs after response is sent — zero latency impact)
| Field | Type | Default | Description |
|---|---|---|---|
clickhouse_url | string | http://clickhouse:8123 | ClickHouse HTTP endpoint |
database | string | gateway | Target database |
table | string | request_log | Target table (Buffer engine for high throughput) |
batch_max_size | integer | 100 | Number of entries before batch flush |
inactive_timeout | integer | 5 | Seconds before flush even if batch not full |
tenant_header | string | X-Tenant-ID | Header to extract tenant ID from |
Source: layers/api-gateway/plugins/clickhouse-logger/init.lua
request-id (Built-in)
Generates a unique X-Request-ID header for every request. Used for trace correlation across L1 -> L2 -> L3.
| Field | Type | Default | Description |
|---|---|---|---|
include_in_response | boolean | true | Include the generated ID in the response headers |
algorithm | string | uuid | ID generation algorithm (uuid or snowflake) |
opentelemetry (Built-in)
Sends distributed tracing spans to the OpenTelemetry Collector (and on to Jaeger). Enables the Traces page in the operator portal.
Configuration is global via plugin_attr in apisix.yaml:
yaml
plugin_attr:
opentelemetry:
resource:
service.name: apisix
collector:
address: otel-collector:4317No per-route config needed — attaching the plugin to a route enables tracing for that route.
tenant-rate-limit (Custom)
Per-tenant sliding window rate limiting via Redis. The core multi-tenancy enforcement at L1.
| Field | Type | Default | Description |
|---|---|---|---|
redis_host | string | gw-redis | Redis hostname |
redis_port | integer | 6379 | Redis port |
redis_password | string | (empty) | Redis authentication password |
default_count | integer | 1000 | Requests allowed per window (overridable per tenant in Redis) |
time_window | integer | 60 | Window size in seconds |
rejected_code | integer | 429 | HTTP status code when rate limited |
tenant_header | string | X-Tenant-ID | Header to extract tenant ID from |
allow_missing_tenant | boolean | false | Allow requests without tenant ID (uses __default__ bucket) |
show_limit_header | boolean | true | Include X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset in response |
Source: layers/api-gateway/plugins/tenant-rate-limit/init.lua
Rate limit headers returned:
X-RateLimit-Limit— configured limit for this tenantX-RateLimit-Remaining— requests remaining in current windowX-RateLimit-Reset— seconds until window resets
cors (Built-in)
Cross-origin resource sharing headers. Required for portal API calls from operator.gatez.dev to api.gatez.dev.
| Field | Type | Default | Description |
|---|---|---|---|
allow_origins | string | * | Allowed origins (comma-separated or *) |
allow_methods | string | * | Allowed HTTP methods |
allow_headers | string | * | Allowed request headers |
expose_headers | string | (empty) | Headers exposed to browser JS |
max_age | integer | 5 | Preflight cache duration in seconds |
Authentication Plugins
jwt-auth
Validates JWT tokens. Typically used with Keycloak-issued tokens.
Usage: Add to routes that require JWT authentication. Create consumers with JWT credentials via the APISIX Admin API.
key-auth
API key authentication via header or query parameter.
| Field | Type | Default | Description |
|---|---|---|---|
header | string | apikey | Header name to check for API key |
query | string | apikey | Query parameter name to check |
Usage: Create consumers with key-auth credentials. The approved API key from the key management workflow is stored here.
basic-auth
Standard HTTP Basic authentication (username:password base64 encoded).
openid-connect
Full OpenID Connect flow with IdP redirect. For use cases where JWT tokens aren't pre-obtained (browser-based flows that redirect to Keycloak).
group-auth (Custom)
Group-based access control. Extracts user groups from JWT claims or X-Userinfo header and checks against a required groups list.
| Field | Type | Default | Description |
|---|---|---|---|
required_groups | array[string] | (required) | Groups that grant access (any match = allowed) |
groups_claim | string | groups | JWT claim containing user groups |
reject_code | integer | 403 | HTTP status code when group check fails |
Source: layers/api-gateway/plugins/group-auth/init.lua
Security Plugins
ip-restriction
Allow or block requests by client IP address or CIDR range. Used for the per-tenant IP allowlist feature (EL-9).
| Field | Type | Default | Description |
|---|---|---|---|
whitelist | array[string] | (empty) | Allowed CIDRs (e.g., ["10.0.0.0/8", "203.0.113.0/24"]) |
blacklist | array[string] | (empty) | Blocked CIDRs |
message | string | Your IP address is not allowed | Custom rejection message |
response-pii-scrub (Custom)
Scans response bodies for PII patterns (SSN, credit card, email, phone) and redacts them. Designed for HIPAA compliance (healthcare routes).
| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Enable/disable the plugin |
patterns | array[object] | SSN, CC, email, phone | Custom patterns with name, pattern, replacement |
log_detections | boolean | true | Log detection metadata (not the PII itself) |
Sets X-PII-Scrubbed: true header when PII is detected and redacted.
Source: layers/api-gateway/plugins/response-pii-scrub/init.lua
csrf
Cross-site request forgery protection. Validates CSRF tokens on state-changing requests.
consumer-restriction
Restrict route access to specific APISIX consumers. Supplements tenant-rate-limit for fine-grained access control.
Traffic Control Plugins
limit-count
Fixed-window request count limiting. Alternative to tenant-rate-limit for non-tenant-scoped limits.
| Field | Type | Default | Description |
|---|---|---|---|
count | integer | (required) | Maximum requests per window |
time_window | integer | (required) | Window size in seconds |
rejected_code | integer | 429 | Rejection status code |
key_type | string | var | Key extraction type |
key | string | remote_addr | Key to rate limit by |
limit-req
Leaky bucket rate limiting. Smooths traffic bursts.
| Field | Type | Default | Description |
|---|---|---|---|
rate | number | (required) | Allowed requests per second |
burst | integer | (required) | Maximum burst size |
rejected_code | integer | 429 | Rejection status code |
limit-conn
Concurrent connection limiting.
| Field | Type | Default | Description |
|---|---|---|---|
conn | integer | (required) | Maximum concurrent connections |
burst | integer | (required) | Burst allowance |
default_conn_delay | number | (required) | Delay in seconds for connections exceeding conn |
api-breaker
Circuit breaker for upstream services. Opens the circuit after consecutive failures, returning a configured error code without forwarding requests.
| Field | Type | Default | Description |
|---|---|---|---|
break_response_code | integer | (required) | Status code returned when circuit is open |
unhealthy.http_statuses | array[integer] | [500] | Status codes that count as failures |
unhealthy.failures | integer | 3 | Failures before circuit opens |
healthy.successes | integer | 1 | Successes before circuit closes |
traffic-split
Weighted traffic splitting for canary/blue-green deployments. Used by the canary slider in the operator portal.
| Field | Type | Default | Description |
|---|---|---|---|
rules[].weighted_upstreams[].upstream | object | (required) | Upstream configuration |
rules[].weighted_upstreams[].weight | integer | (required) | Traffic weight (0-100) |
proxy-cache
HTTP response caching at the gateway level. Caches upstream responses to reduce backend load.
request-validation
JSON Schema validation for request bodies. Rejects malformed requests before they reach the backend.
Transform Plugins
proxy-rewrite
Rewrite the request URI and/or headers before proxying to upstream.
| Field | Type | Default | Description |
|---|---|---|---|
regex_uri | array[string] | (empty) | Regex URI rewrite: ["^/old/(.*)", "/new/$1"] |
headers.set | object | (empty) | Headers to add/override: {"X-Custom": "value"} |
headers.remove | array[string] | (empty) | Headers to remove |
response-rewrite
Modify response headers and status code.
| Field | Type | Default | Description |
|---|---|---|---|
status_code | integer | (none) | Override response status code |
headers.set | object | (empty) | Response headers to add: {"X-Powered-By": "Gatez"} |
redirect
HTTP redirect (301/302).
grpc-transcode
HTTP to gRPC protocol translation. Allows REST clients to call gRPC services through the gateway.
grpc-web
gRPC-Web protocol support for browser-based gRPC clients.
Observability Plugins (Additional)
prometheus
Exposes Prometheus metrics at /apisix/prometheus/metrics (port 9091).
Configured globally via plugin_attr:
yaml
plugin_attr:
prometheus:
export_uri: /apisix/prometheus/metrics
export_addr:
ip: 0.0.0.0
port: 9091http-logger
Forward request/response logs to an HTTP endpoint.
tcp-logger / udp-logger
Forward logs to TCP or UDP endpoints.
Serverless Plugins
serverless-pre-function / serverless-post-function
Run custom Lua code inline before or after proxying. Useful for quick transformations without creating a full plugin.
ext-plugin-pre-req / ext-plugin-post-resp
External plugin runner. Delegates plugin logic to an external process communicating via Unix socket. Supports plugins written in any language (Python, Go, Java).
Networking Plugins
real-ip
Extract the real client IP from proxy headers (X-Forwarded-For, X-Real-IP). Important when running behind Caddy or a load balancer.
Plugin Configuration in Routes
Plugins are attached to routes via the APISIX Admin API or through the operator portal. Example route with multiple plugins:
json
{
"uri": "/api/accounts/v2/*",
"upstream": {"type": "roundrobin", "nodes": {"backend:80": 1}},
"plugins": {
"tenant-rate-limit": {"default_count": 5000, "time_window": 60, "redis_host": "gw-redis"},
"clickhouse-logger": {"clickhouse_url": "http://clickhouse:8123"},
"request-id": {"include_in_response": true},
"opentelemetry": {},
"cors": {},
"key-auth": {},
"response-pii-scrub": {"enabled": true}
}
}The CP API auto-injects clickhouse-logger, request-id, opentelemetry, cors, and tenant-rate-limit on every route. Additional plugins are added by the operator via the portal's plugin catalog.