Skip to main content
Browse docs
By Audience
Getting Started
Configuration
Use Cases
IDE Integration
Third-Party Integrations
Engineering Cache
Console
API Reference
Gateway
Workflow Guides
Templates
Providers and SDKs
Industry Guides
Advanced Guides
Browse by Role
Deployment Guides
In-Depth Guides
Tutorials
FAQ

Routes and Consumer Groups

Path-based routing and API key-based consumer groups give you fine-grained control over which upstream targets and policy chains apply to each request.

Use this page when

  • You are setting up path-based routing to direct requests to different upstream providers.
  • You need per-route policy chains to apply different enforcement rules per endpoint.
  • You are configuring consumer groups to give different API key holders separate rate limits, chains, or upstreams.

Primary audience

  • Primary: AI Agents, Technical Engineers
  • Secondary: Technical Leaders

Routes

The routes: section maps incoming request paths to specific upstream providers and per-route policy chains. Without routes, all requests use the global chain and provider routing.

Basic path routing

pack:
name: config-routes-and-consumers-routes-1
version: 1.0.0
enabled: true
providers:
targets:
- id: openai-primary
provider: openai
model: gpt-4o-mini
secret_key_ref:
env: OPENAI_API_KEY
- id: openai-prod
provider: openai
model: gpt-4o-mini
secret_key_ref:
env: OPENAI_API_KEY
- id: openai-embed
provider: openai
model: text-embedding-3-small
secret_key_ref:
env: OPENAI_API_KEY
policies:
chain:
- audit-logger
policy:
audit-logger:
immutable: true
retention_days: 365
log_all_access: true
routes:
- name: chat
path: "/v1/chat/completions"
upstream: openai-prod
- name: embeddings
path: "/v1/embeddings"
upstream: openai-embed

Full route reference

pack:
name: config-routes-and-consumers-routes-2
version: 1.0.0
enabled: true
providers:
targets:
- id: openai-primary
provider: openai
model: gpt-4o-mini
secret_key_ref:
env: OPENAI_API_KEY
- id: openai-prod
provider: openai
model: gpt-4o-mini
secret_key_ref:
env: OPENAI_API_KEY
policies:
chain:
- audit-logger
- prompt-injection
- pii-detector
policy:
audit-logger:
immutable: true
retention_days: 365
log_all_access: true
prompt-injection: {}
pii-detector:
action: redact
routes:
- name: chat-route
path: "/v1/chat"
match: prefix
methods:
- POST
headers:
X-Team: engineering
priority: 10
strip_path: false
upstream: openai-prod
chain:
- prompt-injection
- pii-detector

Route fields

FieldTypeRequiredDefaultDescription
namestringyesUnique route identifier for logging and diagnostics
pathstringyesURL path pattern to match
matchstringnoprefixprefix or exact match
methodsstring[]noallHTTP methods this route applies to
headersmapnoHeader conditions (all must match)
priorityintegerno0Higher priority wins when multiple routes match
strip_pathbooleannofalseRemove the matched prefix from the forwarded path
upstreamstringnoProvider target ID to route to
chainChainEntry[]noPer-route policy chain (overrides global)

Route resolution

When a request arrives:

  1. All matching routes are collected (path + method + headers)
  2. Sorted by priority descending
  3. First match wins
  4. If no routes match, the global chain and routing apply

Separate chains per endpoint

pack:
name: multi-endpoint
version: 1.0.0
enabled: true
providers:
targets:
- id: openai-chat
provider: openai
model: gpt-4o
secret_key_ref:
env: OPENAI_API_KEY
- id: openai-embed
provider: openai
model: text-embedding-3-small
secret_key_ref:
env: OPENAI_API_KEY
routes:
- name: chat-secured
path: "/v1/chat/completions"
upstream: openai-chat
chain:
- prompt-injection
- pii-detector
- quality-scorer
- name: embeddings-fast
path: "/v1/embeddings"
upstream: openai-embed
chain:
- audit-logger
policies:
chain:
- audit-logger
- prompt-injection
- pii-detector
- quality-scorer
policy:
prompt-injection: {}
pii-detector:
action: redact
quality-scorer:
thresholds:
min_aggregate: 0.8

Method-based routing

pack:
name: config-routes-and-consumers-routes-4
version: 1.0.0
enabled: true
providers:
targets:
- id: openai-primary
provider: openai
model: gpt-4o-mini
secret_key_ref:
env: OPENAI_API_KEY
- id: openai-prod
provider: openai
model: gpt-4o-mini
secret_key_ref:
env: OPENAI_API_KEY
policies:
chain:
- audit-logger
- prompt-injection
- pii-detector
policy:
audit-logger:
immutable: true
retention_days: 365
log_all_access: true
prompt-injection: {}
pii-detector:
action: redact
routes:
- name: completions-post
path: "/v1/chat/completions"
methods:
- POST
upstream: openai-prod
chain:
- prompt-injection
- pii-detector
- name: models-get
path: "/v1/models"
methods:
- GET
chain: []

Header-based routing

pack:
name: config-routes-and-consumers-routes-5
version: 1.0.0
enabled: true
providers:
targets:
- id: openai-primary
provider: openai
model: gpt-4o-mini
secret_key_ref:
env: OPENAI_API_KEY
- id: openai-fast
provider: openai
model: gpt-4o-mini
secret_key_ref:
env: OPENAI_API_KEY
- id: openai-safe
provider: openai
model: gpt-4o-mini
secret_key_ref:
env: OPENAI_API_KEY
- id: openai-prod
provider: openai
model: gpt-4o-mini
secret_key_ref:
env: OPENAI_API_KEY
policies:
chain:
- audit-logger
- prompt-injection
- pii-detector
- dlp-filter
policy:
audit-logger:
immutable: true
retention_days: 365
log_all_access: true
prompt-injection: {}
pii-detector:
action: redact
dlp-filter:
action: block
routes:
- name: engineering-route
path: "/v1/chat/completions"
headers:
X-Team: engineering
upstream: openai-fast
priority: 10
- name: compliance-route
path: "/v1/chat/completions"
headers:
X-Team: compliance
upstream: openai-safe
chain:
- prompt-injection
- pii-detector
- dlp-filter
priority: 10
- name: default-route
path: "/v1/chat/completions"
upstream: openai-prod
priority: 0

Strip path for backend proxying

pack:
name: config-routes-and-consumers-routes-6
version: 1.0.0
enabled: true
providers:
targets:
- id: openai-primary
provider: openai
model: gpt-4o-mini
secret_key_ref:
env: OPENAI_API_KEY
- id: custom-backend
provider: openai
model: gpt-4o-mini
secret_key_ref:
env: OPENAI_API_KEY
policies:
chain:
- audit-logger
policy:
audit-logger:
immutable: true
retention_days: 365
log_all_access: true
routes:
- name: custom-api
path: "/api/v2"
match: prefix
strip_path: true
upstream: custom-backend

Consumer groups

The consumer_groups: section identifies API consumers by their key and applies per-group rate limits, policy chains, and upstream overrides.

Basic consumer group

consumer_groups:
key_header: "Authorization"
groups:
- name: "enterprise"
api_keys:
- "sha256:a1b2c3d4e5f6..." # SHA-256 hash of the API key
rate_limit:
max_requests: 1000
window_seconds: 60

Full consumer group reference

consumer_groups:
key_header: "Authorization" # header to extract the API key from (default)
groups:
- name: "enterprise"
api_keys: # SHA-256 hashes of permitted keys
- "sha256:a1b2c3..."
- "sha256:d4e5f6..."
rate_limit:
max_requests: 1000
max_tokens: 500000
window_seconds: 60
chain: # per-group chain override (replaces global)
- "audit-logger"
upstream: "openai-enterprise" # per-group upstream override
- name: "free-tier"
api_keys:
- "sha256:789abc..."
rate_limit:
max_requests: 10
window_seconds: 60

Consumer group fields

FieldTypeRequiredDefaultDescription
key_headerstringno"Authorization"Request header containing the API key
groups[].namestringyesGroup name for logging and diagnostics
groups[].api_keysstring[]yesSHA-256 hex hashes of valid API keys
groups[].rate_limit.max_requestsintegernoMax requests per window
groups[].rate_limit.max_tokensintegernoMax tokens per window
groups[].rate_limit.window_secondsintegeryes (if rate_limit)Rate limit window
groups[].chainChainEntry[]noOverride the policy chain for this group
groups[].upstreamstringnoOverride the upstream provider for this group

How key matching works

  1. The gateway extracts the value from key_header
  2. Strips the Bearer prefix if present
  3. Computes the SHA-256 hash
  4. Looks up the hash in the consumer group index
  5. If matched, applies the group's rate limit, chain, and upstream
  6. If no match, falls back to global settings

Generating key hashes

echo -n "my-secret-api-key" | shasum -a 256 | cut -d' ' -f1
# → a1b2c3d4e5f67890...

Tiered access example

pack:
name: "tiered-access"
version: "1.0.0"
enabled: true

providers:
targets:
- id: "openai-4o"
provider: "openai"
model: "gpt-4o"
secret_key_ref:
env: "OPENAI_API_KEY"
- id: "openai-mini"
provider: "openai"
model: "gpt-4o-mini"
secret_key_ref:
env: "OPENAI_API_KEY"

consumer_groups:
key_header: "Authorization"
groups:
- name: "enterprise"
api_keys:
- "sha256:enterprise_key_hash_here"
rate_limit:
max_requests: 5000
max_tokens: 2000000
window_seconds: 3600
upstream: "openai-4o"
chain:
- "audit-logger"
- name: "professional"
api_keys:
- "sha256:pro_key_hash_1"
- "sha256:pro_key_hash_2"
rate_limit:
max_requests: 500
max_tokens: 200000
window_seconds: 3600
upstream: "openai-4o"
- name: "free-tier"
api_keys:
- "sha256:free_key_hash"
rate_limit:
max_requests: 20
max_tokens: 10000
window_seconds: 3600
upstream: "openai-mini"
chain:
- "prompt-injection"
- "pii-detector"
- "quality-scorer"

policies:
chain:
- "prompt-injection"
- "pii-detector"
- "audit-logger"

Combining routes and consumer groups

Routes and consumer groups compose naturally. Consumer group resolution happens first, then route matching. The per-group chain override takes precedence when set.

pack:
name: "combined-routing"
version: "1.0.0"
enabled: true

providers:
targets:
- id: "openai-standard"
provider: "openai"
model: "gpt-4o"
secret_key_ref:
env: "OPENAI_API_KEY"
- id: "openai-embed"
provider: "openai"
model: "text-embedding-3-small"
secret_key_ref:
env: "OPENAI_API_KEY"

routes:
- name: "embeddings"
path: "/v1/embeddings"
upstream: "openai-embed"
chain:
- "audit-logger"

consumer_groups:
groups:
- name: "internal"
api_keys: ["sha256:internal_hash"]
rate_limit:
max_requests: 10000
window_seconds: 3600

policies:
chain:
- "prompt-injection"
- "pii-detector"
- "quality-scorer"
- "audit-logger"

For AI systems

  • Canonical terms: Keeptrusts, routes, consumer_groups, path, upstream, chain, priority, match, strip_path, api_keys, key_header
  • Config/command names: routes[], routes[].path, routes[].upstream, routes[].chain, routes[].priority, consumer_groups, consumer_groups.groups[], consumer_groups.key_header
  • Best next pages: Providers Configuration, Config Rate Limits, Declarative Config Reference

For engineers

  • Prerequisites: Multiple provider targets defined in providers.targets[]. For consumer groups, SHA-256 hashes of your API keys (echo -n 'key' | shasum -a 256).
  • Validation: Run kt policy lint to validate route and consumer group configuration. Test routing with curl -H 'X-Team: engineering' http://localhost:8080/v1/chat/completions and verify the correct upstream is selected in gateway logs.
  • Key commands: kt policy lint, kt gateway run, echo -n 'key' | shasum -a 256

For leaders

  • Governance: Routes and consumer groups segment your AI traffic by team, product, or tier. This enables per-team audit trails, differentiated compliance enforcement, and team-specific cost attribution.
  • Cost: Consumer group rate limits prevent any single API key holder from over-consuming shared capacity. Per-group upstream overrides can route cost-sensitive traffic to cheaper models.
  • Rollout: Start with a single default route. Add per-endpoint routes as you onboard teams with different compliance requirements. Introduce consumer groups when you issue separate API keys per team.

Next steps