Implement SPIFFE trust-domain bundle management and rotation
@jhrozek is already working on this.
Since Aug 14, 2026.
- Dominant language
- Go
- Stars
- 2.2k
- Forks
- 300
- Avg merge
- 1d 15h
- Merged PRs (30d)
- 184
Description
Description
Provide the validation material both SPIFFE credential types are checked
against: X.509 roots and intermediates for X.509-SVID chains, and JWT
verification keys for JWT-SVID signatures, keyed by an explicitly configured
trust domain.
This is the largest greenfield piece of the epic and the largest risk. The
spiffee-authserver branch has no bundle or rotation code at all —
spiffe.NewMiddleware takes only an expected trust domain and relies on chain
validation configured on the TLS listener. There is nothing to harvest here, so
the work should be split along the line where existing machinery stops.
Scope
One bundle document carries both key types, so both halves share a single
fetch. Do not split this work by credential type.
- Add a trust-domain-keyed bundle registry supplying both
x509bundle.Source
andjwtbundle.Source. Those are the interfacesx509svid.Verify(#6202)
andjwtsvid.ParseAndValidate(#6203) consume, and they are the deliverable. - Supply X.509 roots and intermediates for chain validation, and JWT
verification keys restricted to the bundle'sjwt-svidkeys. - Support explicitly configured SPIFFE Bundle Endpoints.
- Support a SPIRE Workload API bundle source for locally attested deployments.
- Implement bundle refresh hints, sequence-number monotonicity, and an explicit
last-known-good policy. - Keep Workload API and remote Bundle Endpoint configuration independent —
neither should imply or override the other.
go-spiffe/v2 is already a direct dependency and covers most of the above:
workloadapi.NewBundleSource, spiffebundle.Set (trust-domain-keyed, already
fails closed on unknown domains), spiffebundle.Read, Bundle.RefreshHint(),
Bundle.SequenceNumber(), and federation.NewHandler for serving spec-correct
bundle documents in tests. Do not reimplement any of it. Note that go-spiffe
parses spiffe_sequence but never enforces it, so rollback protection is ours.
Two corrections to the original scope
Do not extend pkg/oauthproto/jwks.go. A SPIFFE bundle is keyed by trust
domain rather than issuer, carries spiffe_sequence and spiffe_refresh_hint,
and partitions keys by use. JWKSFetcher is issuer-keyed and discovery-driven,
so adopting it means reimplementing spiffebundle.Read worse. That file is also
an unpushed spike artifact that should not be adopted at all — see #6319 for the
separate and unrelated JWKS consolidation work.
Rotation overlap is not configurable. A bundle is an authority set, and the
trust domain publishes old and new authorities together during rotation. A local
overlap window would retain authorities the domain has already withdrawn, which
contradicts the "removed keys stop validating" criterion below. Overlap is the
bundle's content, not a knob.
Acceptance criteria
- Bundle material is selected by a configured trust domain, never by an
arbitrary issuer or claim taken from the credential being validated. - Bundle Endpoint URLs are explicitly configured and authenticated using
WebPKI, kept separate from SPIFFE workload trust. - X.509 and JWT validation cannot mix keys across trust domains.
- A rotated bundle validates its new authorities and stops validating removed
ones on the next successful fetch, with no restart. - A bundle whose sequence number is lower than the current one is rejected and
the current material is retained. - Removed keys stop validating once the updated bundle becomes authoritative.
- Unknown trust domains fail closed.
- Bundle refresh and failure behaviour is observable without logging
credentials or key material.
Dependencies
- Sub-issue 1 (identity, association and configuration model) — the trust
domain this registry is keyed by is declared there.
Related
- Part of the SPIFFE client-authentication epic
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.