Routes and consumer groups
Routes for paths and headers select policy chains for supported gateway requests. Consumer groups for API keys select policy chains and request limits.
Routes
The live gateway uses routes: to select a policy chain for each Chat Completions and Responses route.
The applicable paths are POST /v1/chat/completions and POST /v1/responses. Other request types, including Embeddings, do not resolve routes at this time.
If no route chain matches, the request uses the global chain.
Use routes only for matching and route policy chains. Configure provider
selection in providers:.
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: your-openai-model
secret_key_ref:
env: VERDICTAN_OPENAI_API_KEY
policies:
chain:
- audit-logger
- prompt-injection
- pii-detector
policy:
audit-logger: {}
prompt-injection: {}
pii-detector:
action: redact
routes:
- name: chat
path: "/v1/chat/completions"
match: exact
chain:
- prompt-injection
- pii-detector
- name: responses
path: "/v1/responses"
match: exact
chain:
- audit-logger
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: your-openai-model
secret_key_ref:
env: VERDICTAN_OPENAI_API_KEY
policies:
chain:
- audit-logger
- prompt-injection
- pii-detector
policy:
audit-logger: {}
prompt-injection: {}
pii-detector:
action: redact
routes:
- name: engineering-chat
path: "/v1/chat/completions"
match: exact
methods:
- POST
headers:
X-Team: engineering
priority: 10
chain:
- prompt-injection
- pii-detector
Route fields
| Field | Type | Necessary | Default | Description |
|---|---|---|---|---|
name | string | yes | — | This is the unique route ID for schema validation and diagnostic data. |
path | string | yes | — | This is the URL path pattern to match. |
match | string | no | prefix | This field selects a prefix or exact match. |
methods | string[] | no | all | This field contains the HTTP methods for the route. |
headers | map | no | — | This field contains header conditions. All conditions must match. |
priority | integer | no | 0 | The route with the higher priority wins when multiple routes match. |
chain | ChainEntry[] | no | — | This route policy chain replaces the global chain. |
Route resolution
For Chat Completions and Responses requests, the gateway does these operations:
- It collects routes that match the normalized path, method, and headers.
- It sorts routes from high to low
priority. For equalpriorityvalues, the first declared route wins. - It uses the matched route
chainwhen the chain contains a value. - It uses the global chain when no route matches or the matched route has no
chain.
The two live handlers resolve routes with POST. Thus, a route for a different method does not match.
Route matching does not change provider routes or the forwarded path.
Different chains for each endpoint
pack:
name: multi-endpoint
version: 1.0.0
enabled: true
providers:
targets:
- id: openai-primary
provider: openai
model: your-openai-model
secret_key_ref:
env: VERDICTAN_OPENAI_API_KEY
routes:
- name: chat-secured
path: "/v1/chat/completions"
match: exact
chain:
- prompt-injection
- pii-detector
- quality-scorer
- name: responses-audited
path: "/v1/responses"
match: exact
chain:
- audit-logger
policies:
chain:
- audit-logger
- prompt-injection
- pii-detector
- quality-scorer
policy:
audit-logger: {}
prompt-injection: {}
pii-detector:
action: redact
quality-scorer:
thresholds:
min_aggregate: 0.8
Method conditions
The schema accepts a methods list, but the two route handlers are POST endpoints. Use POST or do not specify methods.
Do not define routes for other methods or paths. Those requests do not use this route resolver.
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: your-openai-model
secret_key_ref:
env: VERDICTAN_OPENAI_API_KEY
policies:
chain:
- audit-logger
- prompt-injection
- pii-detector
- dlp-filter
policy:
audit-logger: {}
prompt-injection: {}
pii-detector:
action: redact
dlp-filter:
action: block
routes:
- name: engineering-route
path: "/v1/chat/completions"
match: exact
headers:
X-Team: engineering
chain:
- audit-logger
priority: 10
- name: compliance-route
path: "/v1/chat/completions"
match: exact
headers:
X-Team: compliance
chain:
- prompt-injection
- pii-detector
- dlp-filter
priority: 10
- name: default-route
path: "/v1/chat/completions"
match: exact
chain:
- audit-logger
priority: 0
Consumer groups
The consumer_groups: section identifies API consumers from a supplied key. For Chat Completions and Responses, a matched group can replace the policy chain.
The group can also enforce an in-memory max_requests window on that gateway instance.
Configure provider selection in providers:.
Basic consumer group
consumer_groups:
key_header: "Authorization"
groups:
- name: "enterprise"
api_keys:
- "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
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
- "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
- "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
rate_limit:
max_requests: 1000
window_seconds: 60
chain: # per-group chain override (replaces global)
- "audit-logger"
- name: "free-tier"
api_keys:
- "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
rate_limit:
max_requests: 10
window_seconds: 60
Consumer group fields
| Field | Type | Necessary | Default | Description |
|---|---|---|---|---|
key_header | string | no | "Authorization" | This request header contains the API key. |
groups[].name | string | yes | — | This group name occurs in logs and diagnostic data. |
groups[].api_keys | string[] | yes | — | This field contains SHA-256 hex hashes of correct API keys. |
groups[].rate_limit.max_requests | integer | no | — | This is the in-memory request limit for each group and gateway instance. It applies to Chat Completions and Responses. |
groups[].rate_limit.window_seconds | integer | yes (if rate_limit) | — | This field sets the rate limit window. |
groups[].chain | ChainEntry[] | no | — | This field replaces the policy chain for the group. |
How key matching works
- The gateway gets the value from
key_header. - When
key_headerisAuthorization, the gateway removes theBearerprefix when it is available. - The gateway calculates the SHA-256 hash.
- The gateway looks for the hash in the consumer group index.
- For Chat Completions and Responses, the gateway applies the group
max_requestslimit. It uses a configured groupchain. - If no group matches, the gateway uses a configured route chain. If that chain is missing, it uses the global chain.
For all other request types, the active handlers do not resolve consumer groups.
Calculate key hashes
echo -n "my-secret-api-key" | shasum -a 256 | cut -d' ' -f1
# → 325ededd6c3b9988f623c7f964abb9b016b76b0f8b3474df0f7d7c23b941381f
Tiered access example
pack:
name: "tiered-access"
version: "1.0.0"
enabled: true
providers:
targets:
- id: "openai-primary"
provider: "openai"
model: "your-openai-model"
secret_key_ref:
env: "VERDICTAN_OPENAI_API_KEY"
consumer_groups:
key_header: "Authorization"
groups:
- name: "enterprise"
api_keys:
- "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
rate_limit:
max_requests: 5000
window_seconds: 3600
chain:
- "audit-logger"
- name: "professional"
api_keys:
- "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
- "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
rate_limit:
max_requests: 500
window_seconds: 3600
- name: "free-tier"
api_keys:
- "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
rate_limit:
max_requests: 20
window_seconds: 3600
chain:
- "prompt-injection"
- "pii-detector"
- "quality-scorer"
policies:
chain:
- "prompt-injection"
- "pii-detector"
- "quality-scorer"
- "audit-logger"
Use routes with groups
For Chat Completions and Responses, the gateway resolves a matching route and consumer group.
A configured consumer group chain overrides a route chain. A route chain overrides the global chain.
pack:
name: "combined-routing"
version: "1.0.0"
enabled: true
providers:
targets:
- id: "openai-primary"
provider: "openai"
model: "your-openai-model"
secret_key_ref:
env: "VERDICTAN_OPENAI_API_KEY"
routes:
- name: "responses-audited"
path: "/v1/responses"
match: exact
chain:
- "audit-logger"
consumer_groups:
groups:
- name: "internal"
api_keys: ["dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"]
rate_limit:
max_requests: 10000
window_seconds: 3600
chain:
- "prompt-injection"
- "pii-detector"
policies:
chain:
- "prompt-injection"
- "pii-detector"
- "quality-scorer"
- "audit-logger"