Kong plugin — dynamo-gateway-kong

A Kong 3.x plugin (Lua, Apache-2.0) implementing the canonical Dynamo plugin contract: allowance credentials verify offline (JWS ES256K against pinned engine signers — pure-LuaJIT cryptography, no per-request network), denials answer x402-shaped 402s byte-identical to litellm-dynamo, units meter from the response payload and tick to the engine asynchronously, and per-stream caps enforce inline from the local headroom cache. Missing, stale, or revoked-at-last-sync state DENIES — fail closed, never guess.

Two surfaces, one guard core

Authorization: Bearer; the canonical decision table gates the request; units meter from the response — declared token counts, bytes, or calls, payload-neutral.

nonces; X-PAYMENT payments verify offline (streaming allowance + exact receipts) with replay rejection, idempotent consume records, voucher monotonicity, exposure bounds, and finality-aware access.

Every decision lives in kong/plugins/dynamo/core/* — byte-identical to the APISIX vendor copy, enforced by make audit-plugin-core. The handler only moves headers, bodies, and timers.

Config essentials

FieldDefaultMeaning
engine_url(required)Engine wire endpoint — the ASYNC leg only (cap sync + meter flush), never the request path
engine_signers(required)Pinned offline trust anchors: the engine signer address set
max_stale_seconds30Cache entries older than this DENY (fail closed)
sync_seconds5Cap-sync + meter-flush timer period
units_per_request / units_per_prompt_token / units_per_completion_token / units_per_byte0/1/1/0Payload-neutral unit metering (digit-string integer math)
pay_to, asset, resources[{path, price_units}]The x402 seller surface; unpriced routes run the guard flow
max_unsettled_exposureSeller exposure bound (free pre-check)
finality_threshold_unitsPrices above this require a settled voucher frontier

Money and units are decimal digit strings end to end, and the plugin is mode-agnostic by construction: control, escrow, and card credentials verify identically.

Deployment shape

DB-less: mount the package's kong/ tree, then

KONG_DATABASE=off  KONG_PLUGINS=bundled,dynamo
KONG_LUA_PACKAGE_PATH=/opt/dynamo/?.lua;;

with a declarative config carrying the plugin block. Pinned image: kong:3.9. The operator path ships a compose-based example.

Verify

cd /Users/steve/dpv1-aug26 && pwd
make test-gateways        # the core spec inside the PINNED kong:3.9 image
make audit-plugin-core    # core byte-identical across gateways
make conformance-kong     # full x402 catalog vs a LIVE Kong container
make p17                  # 10k-vector decision parity vs {reference, litellm, apisix}

Parity is doctrine, not aspiration: every gateway surface passes the identical conformance vector set — denial classes, ordering, and the 402 challenge schema never fork per gateway.