Skip to content

Commit 108bc9c

Browse files
committed
Define SPIFFE trust configuration
Both SPIFFE credential methods (X.509-SVID and JWT-SVID) need one fail-closed identity and association model before authentication can produce equivalent authorization outcomes for either method. Without a shared model, adding live SVID verification later would force a choice between duplicating trust-domain/scope/audience checks per credential type or bolting authorization onto whichever method lands first. This commit defines that model as pure config validation, deliberately without loading trust bundles or authenticating credentials — those are separate, later steps on this stacked branch (refs #6200). It is, however, independently fail-closed: `RunConfig.Validate()` now validates `spiffe_trust_domains`/`inbound_grants.spiffe_client_auth` directly, and `Config.SPIFFETrust` is built in the embedded auth server constructor, so a malformed or half-configured declaration cannot start successfully and silently have no effect. `SPIFFETrustDomainRunConfig` declares a named trust domain, the credential methods it enables, and exactly one future bundle source (a SPIFFE Bundle Endpoint or the local Workload API) — validated for shape now so the field exists in the authoritative model before consumption is built, even though fetching a bundle is out of scope here. `SPIFFEClientAuthRunConfig` associates a SPIFFE principal pattern (a concrete ID or a terminal `/*` wildcard) within a declared trust domain with an explicit OAuth client_id, methods, and permissions — client_id is never derived from the SPIFFE ID, so an operator always states which OAuth identity a workload maps to. Permissions are three independent dimensions instead of one combined list: `resources` (RFC 8707, optional, must be an absolute HTTP(S) URI), `audiences` (RFC 8693, required, bounded by the server's global allowlist), and `grant_types` (required, must be exactly token-exchange for now) — so permitting a resource never implies permitting the same value as an audience, and client authentication never by itself confers a grant. `NewSPIFFETrustConfig` validates and normalizes these declarations into an immutable `SPIFFETrustConfig`. It retains the validated, canonicalized trust-domain records (not just the association policy), exposed via a lookup-by-name method, so a future X.509/JWT-SVID validator has one authoritative source for a trust domain's canonical form, enabled methods, and bundle source instead of re-parsing the raw RunConfig separately. Its zero value is also valid (equivalent to what the constructor returns for empty input), so external packages may construct it directly without going through the constructor. Validation fails closed on anything that could make authorization ambiguous or order-dependent: duplicate trust-domain names or canonical trust domains, a principal whose trust domain doesn't match its declared trust-domain reference, overlapping principal patterns across associations (segment-aware, so `/agent/*` doesn't collide with `/agent-x/*`), client IDs colliding with the reserved synthetic-client namespace or matching a client metadata document URL (reserved for CIMD-resolved clients, checked with the same predicate the runtime CIMD router uses), and a bundle source whose declared type doesn't match its payload. Refs #6200 Signed-off-by: Jakub Hrozek <jakub@stacklok.com>
1 parent 65eaa1b commit 108bc9c

9 files changed

Lines changed: 1447 additions & 4 deletions

File tree

docs/server/docs.go

Lines changed: 131 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/server/swagger.json

Lines changed: 131 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)