Summary
Add a filter that validates API keys (e.g. sk-oai-* format) against an external key management service via HTTP callout, extracts authenticated identity into filter_metadata, and strips the client key before upstream forwarding.
Motivation
MaaS (Models as a Service) issues API keys to tenants for accessing LLM providers through the gateway. The gateway needs to:
- Validate the key against the key service (is it active, not expired, not revoked?)
- Extract identity (username, groups, subscription) from the validation response
- Strip the client-provided key so it doesn't leak to the upstream provider
- Hand off to
credential_injection which replaces it with the real provider key
This is the API-key counterpart to JWT/OIDC authentication — simpler UX (no token expiry, no refresh flows), suitable for CLI tools and SDK integrations where OAuth flows are impractical.
Key design points
- HTTP callout to a configurable validation endpoint (e.g.
POST /internal/v1/api-keys/validate)
- In-memory cache with configurable TTL — avoids per-request HTTP roundtrips for hot keys
- Writes to
filter_metadata — same contract as other auth filters (username, groups, subscription), so downstream filters (external_metering, identity_header_guard) work unchanged
- Strips client key header before upstream send — the real provider key is injected by
credential_injection
- Fail-closed — invalid, expired, or unverifiable keys are rejected (unlike metering which can fail-open)
Relationship to other filters
Scope
- Configurable validation URL, token header name, cache TTL, timeout
- ~250 lines of filter code
- Unit tests with wiremock (valid/invalid/missing key, cache hit, endpoint down, header strip)
- Integration test, example config
- Working implementation with tests available on my fork (
yossiovadia/ai, branch feat/dogfood-gateway)
Non-goals
- No key creation/management — that's the external service's responsibility
- No authorization decisions beyond "is this key valid" — RBAC is out of scope
- No opinion on key format — works with any opaque string token
Summary
Add a filter that validates API keys (e.g.
sk-oai-*format) against an external key management service via HTTP callout, extracts authenticated identity intofilter_metadata, and strips the client key before upstream forwarding.Motivation
MaaS (Models as a Service) issues API keys to tenants for accessing LLM providers through the gateway. The gateway needs to:
credential_injectionwhich replaces it with the real provider keyThis is the API-key counterpart to JWT/OIDC authentication — simpler UX (no token expiry, no refresh flows), suitable for CLI tools and SDK integrations where OAuth flows are impractical.
Key design points
POST /internal/v1/api-keys/validate)filter_metadata— same contract as other auth filters (username,groups,subscription), so downstream filters (external_metering,identity_header_guard) work unchangedcredential_injectionRelationship to other filters
filter_metadataoutput contractcredential_injection(core builtin) for the key swapidentity_header_guard(feat(filter): add identity header guard filter #698) for identity header captureexternal_metering(feat(filter): add external metering filter for usage reporting and balance checks #577) which reads identity from metadataScope
yossiovadia/ai, branchfeat/dogfood-gateway)Non-goals