You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When a registration entry's federatesWith references a trust domain with no corresponding bundles row, SPIRE Server rejects the entry create/update entirely:
unable to find federated bundle "spiffe://some-trust-domain"
This is enforced in makeFederatesWith
(pkg/server/datastore/sqlstore/sqlstore.go), which requires every trust domain listed in federatesWith to resolve to an existing bundles row before the entry write succeeds.
Real-world impact
We run federation from several per-cluster trust domains into a central cluster, managed by an operator reconciling ClusterFederatedTrustDomainresources.
During an incident, one federated cluster's bundle failed to publish to its storage backend (S3 404 / NoSuchKey).
SPIRE Server had a FederatedTrustDomain relationship for that trust domain registered, but no bundles row.
Our default ClusterSPIFFEID's federatesWith included that trust domain among several others, so every entry generated from that CSID failed to create — surfacing to workloads as PermissionDenied: no identity issued even though only one of several federated trust domains was actually unhealthy.
History
This is actually a known issue initially raised in #1256 but due to small complications in an initial fix PR was later abandoned due to lack of perceived demand for this edge case.
Creating entries with a FederatesWith for an unknown trust domain should succeed #1256 (2019): proposed a fix. Discussion converged on a "sentinel bundle" design (@azdagron's comment): auto-create an empty bundle row (trust domain set, data column NULL) as a placeholder so the federated_registration_entries many-to-many join always resolves, with fetch/list operations filtering out NULL-data rows so placeholders are never mistaken for real bundles.
This was chosen specifically to avoid the schema/data migration a "proper" fix would otherwise need (a decoupled table mapping entry ID -> trust domain strings, discussed here).
@dfeldman implemented an auto-create-on-missing-bundle approach in If a bundle doesn't exist yet when creating a federation reg. entry, create it #1448
(dfeldman:empty-bundle-federation).
Note that this always created a real bundles row (never left a literal dangling foreign key — every entry's federatesWith still pointed at something that existed), but left two things unresolved: placeholder bundles showed up in bundle list operations indistinguishable from real ones, and nothing cleaned them up when the owning relationship was removed.
The issue and PR were ultimately closed won't-fix @evan2645's closing rationale points back to the original 2019 intent behind the strict check: "we did this consciously with the intention of signaling to the registrant that something is up."
Auto-creating a bundle on any federatesWith value removes that typo/misconfiguration signal, so a mistyped or stale trust domain string would succeed silently and leave a permanent, unintentional bundle row behind, with nothing to prompt an operator to notice.
Make this opt-in and server-wide (no per-relationship granularity, no CRD
or spire-api-sdk changes, no schema migration), addressing the concerns
that sank #1256/#1448:
Revive @dfeldman 's original approach of setting empty bundles as this is valid today
Filter placeholders from FetchBundle/ListBundles, per @azdagron's original proposal, so they don't show up in spire-server bundle list/bundle show (or via GetFederatedBundle/ListFederatedBundles) as if they were real (if empty) published
bundles.
No new cleanup mechanism on relationship deletion. Placeholder bundles are ordinary bundles rows. Deleting a FederationRelationship doesn't touch bundles today either, and shouldn't start now —spire-server bundle delete already defaults to RESTRICT, so any real entry dependency blocks accidental removal.
Building bespoke cleanup here would risk recreating the exact dangling-reference bug this proposal avoids.
Operator UX parity. Losing the hard failure removes the original typo/misconfiguration signal (see "History"). Getting equivalent visibility back isn't a single change: today the error reaches CLI/API callers as an immediate, hard failure, and reaches spire-controller-manager as both a specific log line and a bump to the existing ClusterSPIFFEID status stats.
Matching that means work in a few places: SPIRE Server surfacing a non-error warning on the affected create/update result, the spire-server CLI actually displaying it (today it only reads the result message on failure, not success), and spire-controller-manager surfacing the same signal somewhere operators already look (e.g. ClusterSPIFFEID/ClusterFederatedTrustDomain status). None of this comes for free just by adding the server-side flag and empty sentinel bundle.
Happy to put together a WIP PR if this direction seems reasonable to
maintainers.
Summary
When a registration entry's
federatesWithreferences a trust domain with no correspondingbundlesrow, SPIRE Server rejects the entry create/update entirely:This is enforced in
makeFederatesWith(
pkg/server/datastore/sqlstore/sqlstore.go), which requires every trust domain listed infederatesWithto resolve to an existingbundlesrow before the entry write succeeds.Real-world impact
We run federation from several per-cluster trust domains into a central cluster, managed by an operator reconciling
ClusterFederatedTrustDomainresources.During an incident, one federated cluster's bundle failed to publish to its storage backend (S3 404 /
NoSuchKey).SPIRE Server had a
FederatedTrustDomainrelationship for that trust domain registered, but nobundlesrow.Our default
ClusterSPIFFEID'sfederatesWithincluded that trust domain among several others, so every entry generated from that CSID failed to create — surfacing to workloads asPermissionDenied: no identity issuedeven though only one of several federated trust domains was actually unhealthy.History
This is actually a known issue initially raised in #1256 but due to small complications in an initial fix PR was later abandoned due to lack of perceived demand for this edge case.
datacolumnNULL) as a placeholder so thefederated_registration_entriesmany-to-many join always resolves, with fetch/list operations filtering outNULL-data rows so placeholders are never mistaken for real bundles.(
dfeldman:empty-bundle-federation).Note that this always created a real
bundlesrow (never left a literal dangling foreign key — every entry'sfederatesWithstill pointed at something that existed), but left two things unresolved: placeholder bundles showed up inbundle listoperations indistinguishable from real ones, and nothing cleaned them up when the owning relationship was removed.The issue and PR were ultimately closed won't-fix @evan2645's closing rationale points back to the
original 2019 intent behind the strict check: "we did this consciously with the intention of signaling to the registrant that something is up."
Auto-creating a bundle on any
federatesWithvalue removes that typo/misconfiguration signal, so a mistyped or stale trust domain string would succeed silently and leave a permanent, unintentional bundle row behind, with nothing to prompt an operator to notice.ClusterSPIFFEID. @evan2645 called it "pretty tough to fix" and asked fora volunteer; none appeared, closed without a fix.
Proposal
Make this opt-in and server-wide (no per-relationship granularity, no CRD
or
spire-api-sdkchanges, no schema migration), addressing the concernsthat sank #1256/#1448:
FetchBundle/ListBundles, per @azdagron's original proposal, so they don't show up inspire-server bundle list/bundle show(or viaGetFederatedBundle/ListFederatedBundles) as if they were real (if empty) publishedbundles.
bundlesrows. Deleting aFederationRelationshipdoesn't touchbundlestoday either, and shouldn't start now —spire-server bundle deletealready defaults toRESTRICT, so any real entry dependency blocks accidental removal.Building bespoke cleanup here would risk recreating the exact dangling-reference bug this proposal avoids.
ClusterSPIFFEIDstatus stats.Matching that means work in a few places: SPIRE Server surfacing a non-error warning on the affected create/update result, the
spire-serverCLI actually displaying it (today it only reads the result message on failure, not success), and spire-controller-manager surfacing the same signal somewhere operators already look (e.g.ClusterSPIFFEID/ClusterFederatedTrustDomainstatus). None of this comes for free just by adding the server-side flag and empty sentinel bundle.Happy to put together a WIP PR if this direction seems reasonable to
maintainers.