Skip to content

Add SPIRE and operator deployment integration for SPIFFE client auth #6205

Description

@jhrozek

Description

Provide the supported Kubernetes deployment and credential-delivery path: SPIRE
issues rotating SVIDs over the Workload API, and the operator declares trust
domains, enabled methods and client associations through the CRD.

Without this the epic is a library change nobody can deploy. It is also where
the "no static secret" claim is actually cashed out — the workload must obtain
both credential types with no private-key file and no OAuth client secret
anywhere in the manifest.

Scope

  • Add v1beta1 CRD and controller wiring.
  • Configure trust domains, enabled authentication methods, client associations,
    TLS, bundle sources, scopes, resources and audiences.
  • Support referenced Secrets, ConfigMaps, SPIFFE Bundle Endpoints and Workload
    API sockets as appropriate to each field.
  • Provide a supported SPIRE Server and Agent deployment.
  • Define node and workload attestation, and workload registration entries.
  • Obtain rotating X.509-SVIDs and trust bundles through the Workload API.
  • Obtain audience-specific JWT-SVIDs whose audience exactly matches the ToolHive
    authorization-server issuer.
  • Support bundle and credential rotation without application restart.

API version and enforcement

Two things to get right rather than inherit:

API version. The spiffee-authserver branch's CRD work is on v1alpha1
MCPExternalAuthConfig, but the trustedIssuers / inboundGrants surface this
epic extends is v1beta1. Reusing that surface resolves the drift; porting the
v1alpha1 work forward re-creates it.

Three-layer enforcement. Mirror the pattern already used for inbound trust:
CEL admission rules on the CRD, a Go mirror in the controller for the rules CEL
cannot express (cross-entry uniqueness in particular), and a runtime registry
build at authserver startup. Each layer is deliberately redundant — CEL is the
cheapest failure point, the Go mirror catches stored objects that bypassed
admission, and the runtime build is the backstop.

One existing gap in that pattern is worth not repeating: the runtime
registry build is gated on ID-JAG grants being present, so a
token-exchange-only deployment has no runtime backstop at all and relies
entirely on the first two layers. The SPIFFE equivalent should be gated on its
own configuration being present, not on an unrelated grant.

Acceptance criteria

  • The operator rejects incomplete or contradictory SPIFFE configurations at
    admission time where CEL can express the rule, and during reconciliation
    otherwise.
  • The operator reconciles relevant Secret, ConfigMap and bundle-source changes.
  • A SPIRE-attested workload obtains both supported SVID types with no static
    OAuth client secret.
  • No private-key file is required on the SPIRE Workload API path.
  • X.509-SVID and JWT-SVID rotation work without restarting the workload or the
    authorization server.
  • The cert-manager CSI implementation is documented only as an optional
    compatibility or development path, with its different attestation and RBAC
    properties made explicit.

Dependencies

  • Sub-issue 5 (OAuth grants and discovery integration)
  • The v1beta1 trustedIssuers / inboundGrants CRD surface (unpushed,
    xaa-spike-1)

Related

  • Part of the SPIFFE client-authentication epic

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions