Skip to content

feat(filter): add API key validation filter for external key services #707

Description

@yossiovadia

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:

  1. Validate the key against the key service (is it active, not expired, not revoked?)
  2. Extract identity (username, groups, subscription) from the validation response
  3. Strip the client-provided key so it doesn't leak to the upstream provider
  4. 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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Projects

Relationships

None yet

Development

No branches or pull requests

Issue actions