Sign in →
Gateways1 min read

Kong Gateway Integration

Enable the Aforo metering sidecar on your existing Kong cluster. Zero application code changes required.

Updated 2026-06-15Suggest edits
Docs Gateways Kong

Task Overview#

JIRA-READY TASK
Enable the Aforo Metering Sidecar on your existing Kong cluster. Verify handshake with SRE team before promoting to production.
Estimated time: 15 minutes. Target: Platform Engineer + SRE Verification.
kong-deployment-architecture.flowLIVE
INGRESS
HTTP In
client request
TLS termination at Kong gateway. Headers parsed and route matched.
0ms
ACCESS
Entitlement
access phase
Local Redis lookup for tenant entitlement + L1-L3 margin check.
<2ms
PROXY
Backend
upstream call
Request forwarded to your origin service. Response streamed back.
passthrough
LOG
Metering
log_by phase
Async event capture after response sent. Zero latency added to client.
0ms added
BUFFER
Batch Flush
every 5s
100 events per batch. lz4 compressed. Disk spillover on failure.
5s window
EGRESS
Aforo Ingest
ingest.aforo.ai
HTTPS POST with retry. Acknowledged by ingest pipeline.
<50ms
kong → aforo metering pipeline · zero client-perceived latency// p95 < 5ms

Prerequisites#

REQUIRED
Kong Gateway
OSS 3.x+ or Enterprise 3.x+
REQUIRED
Admin API access
HTTP access to Kong Admin API (default: localhost:8001)
REQUIRED
Aforo API Key
sk_live_* key from Admin Panel → Settings → API Keys
OPTIONAL
Redis (optional)
For local edge cache. Falls back to in-memory LRU if unavailable.

Step 1: Download the Plugin#

Clone the Aforo Kong metering plugin into your Kong plugins directory:

terminal
# Clone the plugin repository
git clone https://github.com/aforoai/kong-plugin-aforo-metering.git

# Copy to Kong's plugin path
cp -r kong-plugin-aforo-metering/kong/plugins/aforo-metering \
  /usr/local/share/lua/5.1/kong/plugins/

# Verify the plugin is loadable
kong version -vv 2>&1 | grep aforo

Step 2: Configure#

Add the plugin to your kong.yml declarative config or apply via Admin API:

Option A: Declarative (kong.yml) — Production Ready

kong.yml
plugins:
  - name: aforo-metering
    config:
      # ── Core (required) ──────────────────────
      aforo_api_key: "{vault://env/AFORO_API_KEY}"    # env var injection
      aforo_ingest_url: "https://ingest.aforo.ai/v1/ingest"
      tenant_id_header: "X-Tenant-Id"

      # ── Catalog Discovery ────────────────────
      discovery_enabled: true                          # auto-index APIs
      discovery_interval_seconds: 300                  # re-scan every 5 min

      # ── Margin Enforcement ───────────────────
      margin_enforcement: "strict"                     # strict | warn | off
      margin_block_threshold: 0                        # margin % for L3 block

      # ── Batching & Performance ───────────────
      batch_size: 100                                  # events per flush
      flush_interval_ms: 5000                          # flush every 5s
      buffer_max_size: 10000                           # local buffer ceiling

      # ── Edge Cache (Redis) ───────────────────
      redis_host: "127.0.0.1"
      redis_port: 6379
      redis_db: 2                                      # dedicated DB index
      entitlement_cache_ttl: 30                        # seconds

      # ── Fallback & Resilience ────────────────
      fallback_on_error: "allow"                       # allow | block
      retry_count: 3                                   # retries on ingest failure
      retry_delay_ms: 1000                             # exponential backoff base
PRO TIP
The core configuration is 5 lines. Everything below is production hardening. discovery_enabled: true activates automated catalog indexing — Aforo discovers and versions your APIs without manual entry.

Option B: Admin API

terminal
curl -X POST http://localhost:8001/plugins \
  -H "Content-Type: application/json" \
  -d '{
    "name": "aforo-metering",
    "config": {
      "aforo_api_key": "sk_live_your_key_here",
      "aforo_ingest_url": "https://ingest.aforo.ai/v1/ingest",
      "tenant_id_header": "X-Tenant-Id",
      "batch_size": 100,
      "flush_interval_ms": 5000
    }
  }'
INFO
The Admin API method applies the plugin globally (all routes). To scope to a specific service or route, add service.id or route.id to the request.

Step 3: Deploy#

After configuration, reload Kong to activate the plugin:

terminal
# For traditional mode (database-backed)
kong reload

# For DB-less mode (declarative)
kong reload -c /etc/kong/kong.conf

# Verify the plugin is active
curl -s http://localhost:8001/plugins | jq '.data[] | select(.name == "aforo-metering")'

Performance: Zero Latency Impact#

The Aforo Kong plugin is designed for zero impact on your API response times:

<5ms
Entitlement Check
Local Redis lookup. No cross-network call.
0ms added
Usage Metering
Fires in Lua log_by phase — after response is sent.
Every 5s
Batch Flush
100 events per batch. lz4 compressed. Async HTTP.
30s TTL
Cache Refresh
Background sync. Stale cache serves until refresh.
<5ms
Kong Edge Decision
Local Redis lookup in access phase. Zero cross-network call.
MARGIN GUARD/ Kong
The plugin operates in Kong's log phase for metering and access phase for entitlement + margin checks. L1-L3 enforcement runs before the request reaches your upstream — unprofitable traffic is blocked at the gateway.

Fallback Behavior#

If the Aforo ingestion endpoint is temporarily unreachable, the plugin guarantees zero data loss:

RESILIENCE CHAIN
1. Normal → Events batched and flushed every 5s to ingest.aforo.ai
2. Ingest unreachable → Events buffered in local memory (up to buffer_max_size: 10000)
3. Retry → 3 retries with exponential backoff (1s, 2s, 4s)
4. Buffer full → Events spill to disk (/tmp/aforo-buffer/) — survives Kong restarts
5. Ingest recovered → Disk buffer drained first (FIFO), then memory buffer resumes
INFO
The fallback_on_error: "allow" setting controls what happens to API requests when entitlement checks fail. "allow" means your API continues serving traffic (fail-open). "block" means requests are rejected if Aforo can't verify entitlements (fail-closed). Most production deployments use "allow" to prioritize availability.

Verification#

Verify the handshake by checking Kong logs for a successful connection:

terminal
# Check Kong error log for Aforo handshake
tail -f /usr/local/kong/logs/error.log | grep aforo

# Expected output:
# [aforo-metering] Connected to ingest.aforo.ai (200 OK)
# [aforo-metering] Entitlement cache warmed: 47 tenants loaded
# [aforo-metering] Batch flush: 100 events sent (compressed: 2.4KB)

PaperPlaneTilt a Test Event

terminal
# Make an API call through Kong
curl -X GET http://localhost:8000/your-api/endpoint \
  -H "X-Tenant-Id: test_tenant_123" \
  -H "Authorization: Bearer sk_live_your_customer_key"

# Then verify the event arrived in Aforo
curl -s https://api.aforo.ai/v1/events?tenant_id=test_tenant_123&limit=1 \
  -H "Authorization: Bearer sk_live_your_admin_key" | jq .
PRO TIP
If events are not appearing, check the Kong error log for [aforo-metering] ERROR entries. Common issues: invalid API key (401), network timeout to ingest.aforo.ai, or missing X-Tenant-Id header on the request.