Kong Plugin
| Field | Value |
|---|---|
| Document ID | ASCEND-SDK-006 |
| Version | 2026.04 |
| Last Updated | April 2026 |
| Author | Ascend Engineering Team |
| Publisher | OW-KAI Technologies Inc. |
| Classification | Enterprise Client Documentation |
| Compliance | SOC 2 CC6.1/CC6.2, PCI-DSS 7.1/8.3, HIPAA 164.312, NIST 800-53 AC-2/SI-4 |
Reading Time: 15 minutes | Skill Level: Intermediate
Overview
The ASCEND Kong Plugin provides native AI governance integration for Kong Gateway. All AI agent traffic is evaluated against governance policies without code changes.
When ASCEND is unreachable, this gateway denies all requests by default. Ensure ASCEND availability before enabling governance in production.
Features
- FAIL SECURE — Deny by default on errors
- Decision Caching — Sub-millisecond response times
- Custom Action Types — Map paths to action categories
- Path Exclusions — Skip governance for health checks
- Structured Logging — JSON audit logs
Installation
LuaRocks (Recommended)
luarocks install kong-plugin-ascend
Package Info: kong-plugin-ascend on LuaRocks | Version: 1.0.0 | License: Proprietary
Manual Installation
- Copy plugin files to Kong plugins directory:
cp -r kong/plugins/ascend /usr/local/share/lua/5.1/kong/plugins/
- Add to
kong.conf:
plugins = bundled,ascend
- Restart Kong:
kong restart
Configuration
Declarative (DB-less)
# kong.yml
_format_version: "3.0"
plugins:
- name: ascend
config:
api_key: owkai_your_key_here
api_url: https://pilot.owkai.app
environment: production
fail_open: false
cache_ttl: 60
require_agent_id: true
block_on_pending: true
log_decisions: true
Admin API
curl -X POST http://localhost:8001/plugins \
-d "name=ascend" \
-d "config.api_key=owkai_your_key_here" \
-d "config.environment=production" \
-d "config.fail_open=false" \
-d "config.cache_ttl=60"
Per-Route Configuration
# Apply to specific route
curl -X POST http://localhost:8001/routes/{route_id}/plugins \
-d "name=ascend" \
-d "config.api_key=owkai_your_key_here"
Per-Service Configuration
# Apply to all routes on a service
curl -X POST http://localhost:8001/services/{service_id}/plugins \
-d "name=ascend" \
-d "config.api_key=owkai_your_key_here"
Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
api_key | string | Required | ASCEND API key |
api_url | string | https://pilot.owkai.app | API endpoint |
environment | string | production | Environment name |
fail_open | boolean | false | Allow on API error |
cache_ttl | number | 60 | Cache TTL in seconds |
require_agent_id | boolean | true | Require agent header |
default_agent_id | string | - | Default agent ID |
block_on_pending | boolean | true | Block pending approvals |
log_decisions | boolean | true | Log all decisions |
excluded_paths | array | [] | Paths to skip |
custom_action_types | object | {} | Path to action mapping |
denied_status_code | number | 403 | Status for denials |
pending_status_code | number | 202 | Status for pending |
error_status_code | number | 503 | Status for errors |
Agent ID Header
The plugin extracts agent ID from the X-Ascend-Agent-ID header:
curl -H "X-Ascend-Agent-ID: my-agent-001" \
https://api.yourcompany.com/data
Missing Agent ID Behavior
require_agent_id | default_agent_id | Behavior |
|---|---|---|
true | - | Deny (401) |
true | default-agent | Use default |
false | - | Skip governance |
false | default-agent | Use default |
Path Exclusions
Skip governance for certain paths:
config:
excluded_paths:
- "^/health$"
- "^/metrics$"
- "^/public/.*"
- "^/__kong/.*"
Custom Action Types
Map URL patterns to action types:
config:
custom_action_types:
"^/api/v1/customers$": "customer.list"
"^/api/v1/customers/[^/]+$": "customer.read"
"^/api/v1/orders$": "order.create"
"^/api/v1/payments$": "payment.process"
Default Action Type Mapping
If no custom mapping matches:
-- Source: kong-plugin-ascend/kong/plugins/ascend/handler.lua:57
-- HTTP Method to action type mapping
METHOD_ACTION_MAP = {
GET = "read",
POST = "create",
PUT = "update",
PATCH = "update",
DELETE = "delete"
}
-- Action type: {method}_{first_path_segment}
-- Example: GET /customers/123 → read_customers
Response Headers
The plugin adds governance headers to responses:
| Header | Value | Description |
|---|---|---|
X-Ascend-Decision | approved/denied/pending | Decision result |
X-Ascend-Action-ID | 12345 | Action identifier |
X-Ascend-Risk-Score | 3.5 | Risk score (0-100) |
X-Ascend-Risk-Level | low/medium/high | Risk level |
Decision Flow
-- Source: kong-plugin-ascend/kong/plugins/ascend/handler.lua:246
function AscendHandler:access(conf)
-- 1. Check path exclusions
if is_path_excluded(path, conf.excluded_paths) then
return -- Allow without governance
end
-- 2. Extract agent ID
local agent_id = extract_agent_id(conf)
if not agent_id and conf.require_agent_id then
return deny_request(401, "Missing agent ID")
end
-- 3. Check cache
if conf.cache_ttl > 0 then
local cached = kong.cache:get(cache_key)
if cached then
return allow_request(cached)
end
end
-- 4. Call ASCEND API
local decision, err = http_client.submit_action(conf, payload)
if err then
if conf.fail_open then
return -- Allow with warning
end
return deny_request(503, "Governance unavailable")
end
-- 5. Process decision
if decision.status == "approved" then
kong.cache:set(cache_key, decision, conf.cache_ttl)
return allow_request(decision)
elseif decision.status == "pending" then
if conf.block_on_pending then
return deny_request(202, "Requires approval")
end
return -- Allow but flag as pending
else
return deny_request(403, decision.denial_reason)
end
end
Fail Secure Design
-- Source: kong-plugin-ascend/kong/plugins/ascend/handler.lua:302
-- FAIL SECURE: Deny on error unless fail_open configured
if api_err then
kong.ctx.plugin.api_error = api_err
if conf.fail_open then
kong.log.warn("ASCEND API error, fail_open=true")
return -- Allow with warning
end
return deny_request(503, "Governance service unavailable")
end
Logging
Access Log
Enable structured decision logging:
config:
log_decisions: true
Output format:
{
"plugin": "ascend",
"version": "1.0.0",
"timestamp": 1702725600000,
"latency_ms": 45,
"method": "GET",
"path": "/customers/123",
"agent_id": "my-agent-001",
"action_type": "read_customers",
"decision_status": "approved",
"action_id": 12345,
"risk_score": 3.5,
"risk_level": "low",
"cache_hit": false
}
Kong Log Plugin Integration
Combine with Kong's built-in logging:
plugins:
- name: file-log
config:
path: /var/log/kong/access.log
Caching
Kong Cache Integration
The plugin uses Kong's built-in cache:
-- Cache approved decisions
kong.cache:set(cache_key, decision, conf.cache_ttl)
-- Retrieve from cache
local cached = kong.cache:get(cache_key)
Cache Key Format
ascend:cache:{agent_id}:{method}:{normalized_path}
Path normalization replaces:
- Numeric IDs:
/users/123→/users/{id} - UUIDs:
/items/abc-123-def→/items/{id}
Performance
Benchmarks
| Scenario | Latency (p50) | Latency (p99) |
|---|---|---|
| Cache hit | 0.5ms | 2ms |
| Cache miss (local) | 15ms | 50ms |
| Cache miss (cloud) | 30ms | 100ms |
Optimization Tips
- Increase cache TTL for high-volume endpoints
- Use path exclusions for health checks
- Deploy ASCEND in same region as Kong
Testing
Unit Tests
cd kong-plugin-ascend
busted spec/
Integration Test
# Start Kong with plugin
kong start
# Test approved request
curl -v -H "X-Ascend-Agent-ID: test-agent" \
http://localhost:8000/api/data
# Check response headers
# X-Ascend-Decision: approved
Troubleshooting
Plugin returns 403 on all requests
Cause: The ASCEND API key is missing or invalid in the plugin configuration. The plugin defaults to deny when it cannot authenticate with the ASCEND API.
Solution: Verify config.api_key is set in your Kong declarative config. Test the key independently: curl -H "X-API-Key: $KEY" https://pilot.owkai.app/health
Requests bypass governance (no evaluation)
Cause: The plugin is not enabled on the route or service, or the request path matches an excluded pattern in config.excluded_paths.
Solution: Verify the plugin is enabled: kong plugins list. Check excluded_paths configuration does not inadvertently match your governed routes.
High latency on first request after deploy
Cause: The plugin initializes shared state and warms the decision cache on the first request after Kong restart. Solution: This is expected behavior. Subsequent requests use the cached decision path. If latency persists, check network connectivity between Kong and the ASCEND API endpoint.
ASCEND API unreachable — all requests blocked
Cause: Network connectivity issue between Kong and pilot.owkai.app. The plugin defaults to fail-closed (deny all) when it cannot reach the ASCEND API.
Solution: Check DNS resolution and firewall rules for outbound HTTPS to pilot.owkai.app:443. If you need fail-open behavior during outages, set config.fail_open = true in the plugin configuration (not recommended for production).
Kubernetes Deployment
Kong Ingress Controller
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
name: ascend-governance
config:
api_key: owkai_your_key_here
environment: production
fail_open: false
plugin: ascend
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-api
annotations:
konghq.com/plugins: ascend-governance
spec:
rules:
- host: api.yourcompany.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-service
port:
number: 80
Next Steps
- AWS Lambda — For API Gateway
- Envoy/Istio — For service mesh
- Smart Rules — Create custom rules
Document Version: 2026.04 | Last Updated: April 2026