# Gateway Tenant Auth & ABAC Contract (Web V) ## Status - Draft v0.1 (2025-12-01); to be confirmed at 2025-12-02 checkpoint with Policy Guild. ## Scope - Gateway header/claim contract for tenant activation and scope validation across Web V endpoints. - ABAC overlay hooks with Policy Engine (attributes, evaluation order, failure modes). - Audit emission requirements for auth decisions (RBAC + ABAC). ## Header & Claim Inputs - `Authorization: Bearer ` — RS256/ES256, optionally DPoP-bound; claims: `iss`, `sub`, `aud`, `exp`, `iat`, `nbf`, `jti`, optional `scp` (scopes) and `ten` (tenant). - `X-Stella-Tenant` — required, tenant slug or UUID; must match `ten` claim when present. - `X-Stella-Project` — optional project/workspace slug; required for project-scoped routes. - `X-Stella-Scopes` — optional override for service tokens; space-delimited (`policy:run notifier:emit`). - `X-Stella-Trace-Id` — propagated trace ID for audit linking; if absent, gateway generates ULID-based trace ID. - `X-Request-Id` — optional client request ID; echoed for idempotency diagnostics. ## Processing Rules - Validate JWT signature against offline bundle trust roots; enforce `aud` ∈ {`stellaops-web`, `stellaops-gateway`} and `exp/nbf`. - Resolve tenant: prefer `X-Stella-Tenant`; fallback to `ten` claim when header missing; mismatch → `ERR_TENANT_MISMATCH`. - Scope evaluation: - Base scopes from JWT `scp` or `X-Stella-Scopes`. - Enforce required scopes per route; deny with `ERR_SCOPE_MISMATCH` on missing scope. - ABAC overlay: - Attribute sources: JWT claims (`sub`, `roles`, `org`), headers (`X-Stella-Tenant`, `X-Stella-Project`), request path/query/body attributes per route contract. - Evaluation order: RBAC allow → ABAC evaluate → deny overrides → allow. - Failure → `ERR_ABAC_DENY` with `reason` and `trace_id`. - Determinism: reject requests lacking tenant header; no fallback to anonymous; enforce stable error codes. ## Outputs - On success: downstream context includes `tenant_id`, `project_id`, `subject`, `scopes`, `abac_result`, `trace_id`, `request_id`. - On failure: structured envelope with `error.code`, `error.message`, `trace_id`, `request_id`; HTTP 401 for token errors, 403 for scope/ABAC denials, 400 for tenant mismatch/missing. ## Audit & Telemetry - Emit DSSE-wrapped audit record: `{ tenant_id, project_id, subject, scopes, decision, reason_code, trace_id, request_id, route, ts_utc }`. - Counters: `gateway.auth.success`, `gateway.auth.denied`, `gateway.auth.abac_denied`, `gateway.auth.tenant_missing`, labeled by route and tenant. ## Open Questions - Confirm whether DPoP binding is mandatory for Web gateway tokens. - Confirm canonical scope names for service tokens and whether `X-Stella-Scopes` should be allowed in prod.