Federating trust domains is one ofSPIFFEandSPIRE’s most requested, actively developed features. In this blog post, I will provide an overview of our current plan and the challenges in implementing it.
What is federation?
Certificates in a SPIFFE trust domain share a single root of trust. This is currently a root trust bundle consisting of several certificates that are shared between and within control planes using non-standardized formats and protocols.
This isn’t good enough, however. Many organizations have multiple roots of trust: perhaps because they have different organizational divisions with different administrators, or because they have separate staging and production environments that occasionally need to communicate. A similar use-case is SPIFFE interoperability between organizations, such as between a cloud provider and its customers. Both use-cases require a well-defined, interoperable method for a workload in one trust domain to authenticate a workload in a different trust domain. This is federation.
To implement federation, we must share public keys between different SPIFFE servers. This isn’t a one-time operation; because of key rotation, each trust domain’s public key changes periodically. Each federating domain must download the other domain’s public keys periodically, at a frequency at least as fast as key rotation.
The data format for periodically downloading certificates isn’t finalized yet. Our current thinking is to have SPIFFE implementations use the JWKS format to publish certificates publicly at a well-known URL. Then, to start a federation relationship, implementations can download the JWKS data and import the certificates from it.
We like JWKS because it is a generic, extensible format for sharing key information that can accommodate JWT and X.509 certificates. (For security reasons, SPIFFE requires different key material for JWT and X.509 identities — they can’t just be the same public keys encoded in different formats.) JWKS’ flexibility allows a single federation API to support both JWT and X.509.
The SPIFFE workload API provides endpoints for reading federated public keys. This API is distinct from the API for reading the certificates for the current trust domain, so applications can distinguish between clients from the local and federated domains.
Experimental support in SPIRE
Even though it is not officially standardized as part of SPIFFE yet, an experimental implementation of JWKS is already available in SPIRE.
Initial authentication of the foreign SPIFFE server
There’s a bootstrapping problem with the federation API: if neither side shares a trust root, there’s no way to establish an initial secure connection. One solution is to use web PKI with a certificate authority that both SPIFFE servers trust. Another solution is to use manual authentication mechanisms to obviate the need for a public certificate authority (CA).
SPIRE implements federation similarly to node and workload registration. As we extend the registration API, it will be possible to manipulate federation through that API much like node and workload registration.
Network outage tolerance
Each time a SPIFFE implementation imports new certificates from a peer SPIFFE implementation, it authenticates the connection using the last known bundle. If there’s a long network outage and two SPIFFE implementations can’t communicate for more than a full key rotation cycle, then they won’t be able to communicate going forward, thus breaking the federation relationship.
One solution is to set the key rotation interval longer than the longest possible network outage length (or re-initialize federation if a long outage occurs). This is a design tradeoff: if the key rotation interval is longer, a compromised key will remain valid for a longer period as well.
Alternatively, if web PKI is available for the SPIFFE servers, that can be used to secure the federated connection. We believe web PKI between federated SPIFFE servers will be a common design pattern because it avoids the issue with long network outages breaking key rotation.
Transitive & two-way federation
Kerberos and Active Directory have the equivalent of federation, called “cross-realm trust.” In most cases, cross-realm trust is two-way (both sides trust each other) and transitive (if A trusts B, and B trusts C, then A trusts C).
Two-way federation in SPIFFE is usually, but not always, desirable. For public APIs, the API provider may want to use web PKI to secure the server side of the connection, and SPIFFE to secure the client side. Because of this, we do not automatically configure two-way federation.
For large organizations with many trust domains, transitive federation may simplify implementation complexity. However, transitive federation can make it difficult to reason about the security properties of a SPIFFE implementation. For this reason, we are not implementing transitive federation in SPIFFE right now.
For now, users must manually configure transitive and two-way federation by adding more federation relationships.
Scoping of federated trust domain SVIDs
In web PKI, everyone trusts the same root certificate authorities. In SPIFFE, organizations that don’t entirely trust each other may still want to federate their trust domains. Applications must verify that each SVID is issued by a SPIFFE server that owns that trust domain.
Imagine a strange world where Coke and Pepsi must exchange data. To do this, they federate their respective trust domains. Coke’s SPIFFE certificate root is added to Pepsi’s trust store, and vice versa. In a simple implementation of certificate validation, a Coke server could fraudulently impersonate a Pepsi server on Pepsi’s network, since Pepsi trusts Coke’s root certificates!
Here’s the problem: root certificates aren’t “scoped.” Any CA can sign a certificate for any name. This is fine if all CAs are trusted, for example within a single company. In an environment with multiple CAs, each of which should only be allowed to sign certificates with specific names, it leads to security holes.
One approach to prevent this would be to use the X.509 Name Constraints extension. The Name Constraints extension allows a CA certificate to be limited to issuing certificates for a particular domain name. However, support for the Name Constraints extension is limited in TLS libraries, and it does not solve the problem for future SPIFFE identity formats such as JWT. For these reasons, SPIFFE is not including the Name Constraints extension.
This means all applications that use SVIDs must check that the SPIFFE ID in the SVID matches the trust domain of the actual CA that signed the certificate. That means checking that a Pepsi SVID isn’t signed by Coke’s CA. Current widely-used applications, such as web servers and proxies, don’t perform this check.
Federation is critical to implement for SPIFFE to be successful. However, there are challenges ahead to implement it in a secure and usable way. We’re working hard with the community to work our way through these challenges, and would love to hear from you if you have perspective!
To learn more about SPIFFE federation:
- Check out the new Java SPIFFE Federation Demo, which demonstrates working federation between two domains using SPIRE in a Tomcat server environment.
- Join the SPIFFE Slack to discuss SPIFFE with experts.
- Join the SPIFFE SIG-SPEC bimonthly meetings to design the future of federation in SPIFFE. (There will soon be a separate Federation Working Group.)