Security and Network Configuration
The ip_allowlist:, cors:, and size_limits: sections control network-level access, cross-origin requests, and request size boundaries.
Use this page when
- You are restricting gateway access to specific IP ranges using an allowlist.
- You need to configure CORS headers for browser-based LLM API calls.
- You are setting request and response size limits to protect against oversized payloads.
Primary audience
- Primary: AI Agents, Technical Engineers
- Secondary: Technical Leaders
IP allowlist
Restrict gateway access to specific CIDR ranges.
ip_allowlist:
enabled: true
cidrs:
- "10.0.0.0/8"
- "172.16.0.0/12"
- "192.168.1.0/24"
- "203.0.113.42/32" # single IP
trust_proxy_depth: 1
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
enabled | boolean | no | true | Enable/disable the allowlist |
cidrs | string[] | yes | — | IPv4/IPv6 CIDR ranges to permit |
trust_proxy_depth | integer | no | 0 | Number of trusted reverse-proxy X-Forwarded-For hops to skip |
Trust proxy depth
When the gateway sits behind a reverse proxy (nginx, ALB, Cloudflare), the client IP appears in the X-Forwarded-For header. Set trust_proxy_depth to the number of proxies between the client and the gateway.
# Client → CloudFlare → ALB → Gateway
ip_allowlist:
cidrs: ["10.0.0.0/8"]
trust_proxy_depth: 2 # skip CloudFlare + ALB IPs
trust_proxy_depth too high allows clients to spoof their IP by injecting fake X-Forwarded-For headers. Only trust proxies you control.IPv6 support
ip_allowlist:
cidrs:
- "10.0.0.0/8"
- "fd00::/8"
- "2001:db8::/32"
CORS
Configure Cross-Origin Resource Sharing for browser-based LLM calls.
cors:
enabled: true
allow_origins:
- "https://app.example.com"
- "https://staging.example.com"
allow_methods:
- "GET"
- "POST"
- "OPTIONS"
allow_headers:
- "Content-Type"
- "Authorization"
- "X-Custom-Header"
expose_headers:
- "X-Request-Id"
- "X-RateLimit-Remaining"
credentials: true
max_age: 3600
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
enabled | boolean | no | true | Enable/disable CORS headers |
allow_origins | string[] | no | ["*"] | Allowed origins (* for any) |
allow_methods | string[] | no | ["GET","POST","OPTIONS"] | Allowed HTTP methods |
allow_headers | string[] | no | ["Content-Type","Authorization"] | Allowed request headers |
expose_headers | string[] | no | [] | Response headers exposed to JavaScript |
credentials | boolean | no | false | Allow Access-Control-Allow-Credentials |
max_age | integer | no | 3600 | Preflight cache duration (seconds) |
allow_origins: ["*"] with credentials: true is invalid per the CORS spec. When credentials is enabled, list origins explicitly.Wildcard subdomain matching
cors:
allow_origins:
- "https://*.example.com" # all subdomains
Disabling CORS
cors:
enabled: false
Size limits
Control maximum request and response sizes. These are enforced before policy evaluation.
size_limits:
max_request_body_bytes: 1048576 # 1 MB
max_response_body_bytes: 10485760 # 10 MB
max_prompt_chars: 100000
max_completion_chars: 50000
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
max_request_body_bytes | integer | no | — | Maximum raw request body size |
max_response_body_bytes | integer | no | — | Maximum raw response body size |
max_prompt_chars | integer | no | — | Maximum character count in the prompt (after message assembly) |
max_completion_chars | integer | no | — | Maximum character count in the completion |
Requests exceeding any limit receive a 413 Payload Too Large response before reaching the policy chain.
Bot detector
The bot-detector policy identifies and optionally blocks automated clients based on request patterns, user agents, and behavioral signals.
policy:
bot-detector:
enabled: true
block_mode: block
patterns:
user_agent:
block:
- curl/*
- python-requests/*
- Go-http-client/*
allow:
- MyApp/*
rate_signal:
enabled: true
window_seconds: 60
max_requests: 100
pack:
name: config-security-network-example-8
version: 1.0.0
enabled: true
policies:
chain:
- bot-detector
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
enabled | boolean | no | true | Enable/disable bot detection |
block_mode | string | no | "block" | block (409), flag (header), or audit (log only) |
patterns.user_agent.block | string[] | no | — | Glob patterns to block |
patterns.user_agent.allow | string[] | no | — | Glob patterns to explicitly allow |
rate_signal.enabled | boolean | no | false | Enable rate-based bot detection |
rate_signal.window_seconds | integer | no | 60 | Detection window |
rate_signal.max_requests | integer | no | 100 | Max requests before flagging |
Complete security configuration example
pack:
name: "secured-gateway"
version: "1.0.0"
enabled: true
providers:
targets:
- id: "openai-prod"
provider: "openai"
model: "gpt-4o"
secret_key_ref:
env: "OPENAI_API_KEY"
ip_allowlist:
enabled: true
cidrs:
- "10.0.0.0/8"
- "172.16.0.0/12"
trust_proxy_depth: 1
cors:
enabled: true
allow_origins:
- "https://app.example.com"
allow_methods: ["POST", "OPTIONS"]
allow_headers: ["Content-Type", "Authorization"]
credentials: true
max_age: 7200
size_limits:
max_request_body_bytes: 2097152 # 2 MB
max_response_body_bytes: 20971520 # 20 MB
max_prompt_chars: 200000
max_completion_chars: 100000
policies:
chain:
- "bot-detector"
- "prompt-injection"
- "pii-detector"
policy:
bot-detector:
block_mode: "block"
patterns:
user_agent:
block: ["curl/*", "python-requests/*"]
allow: ["MyApp/*"]
prompt-injection:
enabled: true
pii-detector:
enabled: true
For AI systems
- Canonical terms: Keeptrusts, ip_allowlist, cors, size_limits, cidrs, trust_proxy_depth, allow_origins, max_body_bytes
- Config/command names:
ip_allowlist:section,cors:section,size_limits:section,trust_proxy_depth,cidrs,allow_origins,credentials,max_age - Best next pages: Config Rate Limits, Routes and Consumer Groups, Declarative Config Reference
For engineers
- Prerequisites: Knowledge of your network topology — specifically how many reverse proxies sit between clients and the gateway (for
trust_proxy_depth). For CORS, the list of frontend origins that will call the gateway. - Validation: Lint with
kt policy lint. Test IP allowlist by sending a request from a non-allowed IP and confirming HTTP 403. Test CORS by sending a preflight OPTIONS request and verifying theAccess-Control-Allow-Originheader. - Key commands:
kt policy lint,curl -X OPTIONS -H 'Origin: https://app.example.com',kt gateway run
For leaders
- Governance: IP allowlisting restricts gateway access to known networks. Combined with consumer groups and RBAC, this forms the first layer of defense against unauthorized API access.
- Cost: No direct cost impact — these are gateway-local controls. However, overly permissive CORS or missing IP restrictions increase attack surface and potential abuse costs.
- Rollout: Deploy IP allowlisting in audit mode first (log but don't block) to verify expected client IPs. Tighten to enforcement after confirming all legitimate traffic sources are covered.
Next steps
- Config Rate Limits — Layer rate limits on top of network controls
- Routes and Consumer Groups — Consumer-level access control
- RBAC — Identity-based access control
- Declarative Config Reference — Full schema reference