callout_credentials
On this page
Establishing filter that captures typed per-user callout secrets from ingress headers.
Configuration Notes
SECURITY: every configured source_header is trusted-boundary-owned input. The authentication boundary that terminates ingress MUST unconditionally delete and then set each credential source header on every request, so a client can never spoof another user’s credential by supplying the source header itself. This filter strips the source headers before they reach any upstream, but it cannot distinguish a boundary-set value from a client-supplied one; a deployment that exposes a source_header a client can reach without that delete-then-set step lets any caller inject an arbitrary per-user secret. Only route requests through this filter behind a boundary that owns every configured source header.
Place this filter once in the outer request chain, before body pre-read callouts and any iterative_request_router. It establishes one [CalloutCredentials] map that the router carries across iterations; callout consumers inside or outside the router select their own slot. Do not repeat the establishing filter inside router steps.
Configuration
| Field | Type | Required | Description |
|---|---|---|---|
credentials | RawSlot[] | no | Per-user credential slots to capture from ingress headers. |
credentials[].slot | string | yes | Config-static slot identifier. |
credentials[].source_header | string | yes | Ingress header name to read the per-user secret from. |
assertions | RawSlot[] | no | Opaque authorization-assertion slots to capture from trusted ingress headers. |
assertions[].slot | string | yes | Config-static slot identifier. |
assertions[].source_header | string | yes | Ingress header name to read the per-user secret from. |
Example
- filter: callout_credentials
credentials:
- slot: brave_search
source_header: x-user-brave-key
assertions:
- slot: mcp_gateway
source_header: x-mcp-authorized