Contract ②: Gateway Conformance
Any gateway CAIPE supports must satisfy this contract. It is what keeps gateways swappable.
Required capabilities
- OpenAI-compatible endpoint: openai-endpoint.md.
- Upstream translation: OpenAI format ↔ the provider's native format (Bedrock, Anthropic, Azure, …).
- Identity verification:
LLM_GATEWAY_AUTH=jwt: validates the gateway JWT (signature via the issuer's JWKS,iss,aud=LLM_GATEWAY_AUDIENCE,exp).LLM_GATEWAY_AUTH=key: validates per-agent keys bound to an agent and team in the gateway. Keys may be operator-provisioned; automated key issuance is not required.- Rejects missing, expired or forged credentials with 401.
- Limits by identity:
- JWT auth: enforces limits per
sub,agent_idandteam_id, namespaced byorg. - Key auth: enforces agent and team limits using the gateway's key bindings. User attribution comes from the request's
userfield and is unverified, so per-user limits are best-effort (FR-005).
- JWT auth: enforces limits per
- Budget signalling: returns 429 or 402 when a gateway-enforced limit is hit, with a documented header, structured error code or unambiguous pattern distinguishable from forwarded provider throttling and quota errors. Forwarded errors must not carry the gateway-limit signal.
- Fail closed: if the limit store or rate-limit service is unreachable, requests are rejected, not admitted unmetered.
- Error passthrough: upstream errors keep their class. No silent retry that changes it.
- Telemetry: per-request usage (tokens, cost) is exportable (OTel or Prometheus).
- Config as code: gateway config is declared and applied, never hand-patched.
Optional capabilities
- ext_authz to the BFF CAS adapter (#2909) for call-time model checks.
- Admin API for adapter features (gateway-adapter.md). Without it, use adapter
none.
Not required
- HA of the gateway itself (the operator's concern).
- Fallback and retry policy (the gateway's choice).
Conformance check
A gateway passes for its configured authentication mode when:
- Every agent path in scope returns a correct completion, streaming and tool calls included.
- Requests with no credential → 401.
- JWT auth: expired tokens and tokens signed by a foreign key → 401; user, agent and team limits each trigger a budget rejection with the right scope.
- Key auth: invalid or revoked keys → 401; agent and team limits each trigger a budget rejection with the right scope. Document whether best-effort per-user limits are supported.
- Key auth with adapter
none: an operator-provisioned key stored in CAIPE works without key-issuance capability. - An induced upstream 429 or 5xx reaches the agent with its class unchanged, including provider quota errors containing "budget" or "quota".
- Ambiguous 402/429 responses retain their original classification without inferred scope or budget-increase advice.
- With adapter
none, an operator-configured rule identifies a gateway limit and excludes provider errors; a missing rule does not satisfy budget-error conformance. - With the limit store down, requests are rejected (AgentRouter:
quotaRateLimitFailureModeDeny=true). - JWT auth: usage is attributable to verified
sub,agent_idandteam_id. - Key auth: usage is attributable to the key's agent and team; any user attribution is explicitly treated as unverified.