Every Kong Gateway data plane enrolled with VeriKnox Hub holds an encrypted identity bundle on disk.
When the VeriKnox plugin is enabled on a Route, it decrypts this identity using the agent_passphrase Vault reference, then acts in the Kong Gateway request lifecycle access phase.
In the access phase, the plugin:
- Parses the request body according to the configured
endpoint.specification (OpenAI, Anthropic, MCP, A2A, and so on).
- Evaluates the request against VeriKnox Hub policy.
- If the policy blocks it, the plugin returns an error and nothing is forwarded upstream.
- If the policy allows it, the plugin signs a receipt with both ED25519 and ML-DSA-65 signatures and forwards it to VeriKnox Hub.
- Strips VeriKnox-specific agent headers (
x-veriknox-agent-id, x-veriknox-api-key, x-veriknox-agent-auth) before proxying the request upstream.
After the upstream responds, the plugin signs and forwards a response receipt to VeriKnox Hub as well.
sequenceDiagram
autonumber
participant A as AI Agent
participant K as Kong Gateway
VeriKnox plugin
participant H as VeriKnox Hub
participant U as Upstream
LLM / MCP / A2A
A->>K: Request with agent headers
Note over K: access phase
K->>H: Policy check + signed request receipt
alt If the policy blocks the request
H-->>K: Deny
K-->>A: 403 Forbidden
else If the policy allows the request
H-->>K: Allow
K->>U: Proxied request (agent headers stripped)
U-->>K: Response
K->>H: Signed response receipt
K-->>A: Response
end
The endpoint.specification field tells the plugin which protocol and API format to expect.
Set it to one of the following values:
|
Specification value
|
Protocol
|
Inference:OpenAI/Chat_Completions
|
OpenAI /v1/chat/completions
|
Inference:OpenAI/Responses
|
OpenAI /v1/responses
|
Inference:Claude/Messages
|
Anthropic Claude /v1/messages
|
Inference:OpenRouter/Chat_Completions
|
OpenRouter api/v1/chat/completions
|
Inference:Google/Gemini_Generate_Content
|
Google Gemini /v1beta/models/{model}:generateContent (and :streamGenerateContent)
|
MCP
|
Model Context Protocol tool-call requests (JSON-RPC v2)
|
A2A
|
Agent2Agent JSON-RPC operations, including streaming (text/event-stream)
|
Kong Gateway runs plugins in descending priority order (higher number runs first).
The VeriKnox plugin must run after authentication plugins (which sit at approximately 1001-1005), so its priority must be lower.
You can control this using dynamic plugin ordering.
Where you place the VeriKnox plugin relative to Kong AI Gateway plugins determines what gets signed:
|
Priority range
|
What the plugin signs
|
|
785-999
|
Original client payload, before any AI plugin transformation
|
|
Below 765
|
AI-modified payload, what actually reached the LLM and what it returned
|
VeriKnox recommends a priority of approximately 700.
Use 785-999 if you need to sign the raw user intent before any model routing or prompt injection by AI plugins.
The VeriKnox plugin doesn’t authenticate clients to Kong Gateway.
If you want receipts to identify the calling agent, configure an authentication plugin or another gateway mechanism separately, then pass the caller context to the VeriKnox plugin through VeriKnox-specific request headers:
|
Header
|
Purpose
|
x-veriknox-agent-id
|
Caller-provided agent identifier
|
x-veriknox-api-key
|
Caller-provided API key
|
x-veriknox-agent-auth
|
Combined credentials in the form agent_id;api_key
|
Use the Pre-Function plugin to copy these headers into shared request context and remove them before proxying upstream:
plugins:
- name: pre-function
config:
access:
- |-
kong.ctx.shared.veriknox_agent_auth = kong.request.get_header("x-veriknox-agent-auth")
kong.ctx.shared.veriknox_agent_id = kong.request.get_header("x-veriknox-agent-id")
kong.ctx.shared.veriknox_api_key = kong.request.get_header("x-veriknox-api-key")
kong.service.request.clear_header("x-veriknox-agent-auth")
kong.service.request.clear_header("x-veriknox-agent-id")
kong.service.request.clear_header("x-veriknox-api-key")
If no agent ID is supplied through x-veriknox-agent-id or x-veriknox-agent-auth, the plugin generates a traceable ID in the form http-client:<ip-address>.
It uses the forwarded client IP when Kong Gateway trusts the proxy, otherwise it uses the direct client IP.
This fallback supports audit tracing, but it is not an authenticated identity.
In production, each AI agent (HTTP client) must authenticate with Kong Gateway before sending traffic.
Kong Gateway supports this through authentication plugins such as Key Auth or JWT.
The VeriKnox plugin should not handle authentication itself.
Without a paired authentication plugin, Kong Gateway may accept LLM inference, MCP, and A2A traffic without authentication: it allows each HTTP request through, and the VeriKnox plugin may then block it based on policy.
That downstream step is authorization without prior authentication.
Run a separate Kong Gateway authentication plugin or dedicated service for AI agents alongside the VeriKnox plugin to provide x-veriknox-agent-id.
Log verbosity is controlled by Kong Gateway’s KONG_LOG_LEVEL environment variable.
|
Setting
|
Output per request
|
KONG_LOG_LEVEL=info (default)
|
One veriknox log line per request (or policy_block / error on failure)
|
KONG_LOG_LEVEL=debug
|
That summary plus 1-2 plugin lifecycle debug lines
|
KONG_VERIKNOX_LOG_PRINT_ALL=on (with debug)
|
Additional Hub client/server debug lines
|
Set KONG_VERIKNOX_LOG_PRINT_ALL in KONG_NGINX_MAIN_ENV alongside the other VeriKnox environment variables so Nginx workers can read it:
KONG_NGINX_MAIN_ENV="KONG_VERIKNOX_LOG_PRINT_ALL; env KONG_VERIKNOX_IDENTITY_STATE_DIR; env KONG_VERIKNOX_HUB_BASE_URL"