Skip to main content

Kong Plugin

FieldValue
Document IDASCEND-SDK-006
Version1.0.0
Last UpdatedDecember 19, 2025
AuthorAscend Engineering Team
PublisherOW-KAI Technologies Inc.
ClassificationEnterprise Client Documentation
ComplianceSOC 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.

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 install kong-plugin-ascend

Package Info: kong-plugin-ascend on LuaRocks | Version: 1.0.0 | License: Proprietary

Manual Installation

  1. Copy plugin files to Kong plugins directory:
cp -r kong/plugins/ascend /usr/local/share/lua/5.1/kong/plugins/
  1. Add to kong.conf:
plugins = bundled,ascend
  1. 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

OptionTypeDefaultDescription
api_keystringRequiredASCEND API key
api_urlstringhttps://pilot.owkai.appAPI endpoint
environmentstringproductionEnvironment name
fail_openbooleanfalseAllow on API error
cache_ttlnumber60Cache TTL in seconds
require_agent_idbooleantrueRequire agent header
default_agent_idstring-Default agent ID
block_on_pendingbooleantrueBlock pending approvals
log_decisionsbooleantrueLog all decisions
excluded_pathsarray[]Paths to skip
custom_action_typesobject{}Path to action mapping
denied_status_codenumber403Status for denials
pending_status_codenumber202Status for pending
error_status_codenumber503Status 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_iddefault_agent_idBehavior
true-Deny (401)
truedefault-agentUse default
false-Skip governance
falsedefault-agentUse 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:

HeaderValueDescription
X-Ascend-Decisionapproved/denied/pendingDecision result
X-Ascend-Action-ID12345Action identifier
X-Ascend-Risk-Score3.5Risk score (0-100)
X-Ascend-Risk-Levellow/medium/highRisk 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

ScenarioLatency (p50)Latency (p99)
Cache hit0.5ms2ms
Cache miss (local)15ms50ms
Cache miss (cloud)30ms100ms

Optimization Tips

  1. Increase cache TTL for high-volume endpoints
  2. Use path exclusions for health checks
  3. 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

IssueCauseSolution
no plugin 'ascend'Not installedCheck LuaRocks path
All requests deniedInvalid API keyVerify api_key config
503 errorsASCEND unreachableCheck network/firewall
Slow responsesNo cachingSet cache_ttl > 0

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


Document Version: 1.0.0 | Last Updated: December 2025