Using SPIRE federation with Automatic Certificate Management Environment protocol
Using SPIRE federation with Automatic Certificate Management Environment (ACME) protocol provides automatic certificate provisioning from Let’s Encrypt. ACME also enables automatic certificate renewal before expiration, eliminating manual certificate management overhead.
-
You have installed the Zero Trust Workload Identity Manager on all clusters that will participate in the federation.
-
You have installed the OpenShift CLI (
oc). -
You have
cluster-adminprivileges on all participating clusters. -
Your federation endpoints must be publicly accessible for Let’s Encrypt HTTP-01 challenge validation.
-
You have network connectivity between all federated clusters.
-
Configure the
SpireServercustom resource on each cluster to enable federation with ACME certificate management.Create or update your
SpireServerresource with the federation configuration:apiVersion: operator.openshift.io/v1alpha1 kind: SpireServer metadata: name: cluster spec: trustDomain: cluster1.example.com federation: bundleEndpoint: profile: https_web refreshHint: 300 httpsWeb: acme: directoryUrl: https://acme-v02.api.letsencrypt.org/directory domainName: federation.apps.cluster1.example.com email: admin@example.com tosAccepted: "true" managedRoute: "true"-
The
spec.trustDomainfield sets a unique trust domain for each cluster (for example,cluster1.example.com,cluster2.example.com). -
The
spec.federation.bundleEndpoint.profilefield uses thehttps_webprofile for ACME-based certificate management. -
The
spec.federation.bundleEndpoint.httpsWeb.acme.directoryUrlfield contains the Let’s Encrypt production directory URL. For testing, use:https://acme-staging-v02.api.letsencrypt.org/directory. -
The
spec.federation.bundleEndpoint.httpsWeb.acme.domainNamefield is the domain name where your federation endpoint is accessible. This automatically sets tofederation.<cluster-apps-domain>ifmanagedRouteis set to "true". -
The
spec.federation.bundleEndpoint.httpsWeb.acme.emailfield is your email address for ACME account registration and certificate expiration notifications. -
The
spec.federation.bundleEndpoint.httpsWeb.acme.tosAcceptedfield accepts the Let’s Encrypt Terms of Service. -
The
spec.federation.managedRoutefield enables an automatic route creation by the operator for the federation bundle endpoint.
-
-
Apply the configuration to each cluster by running the following command:
$ oc apply -f spireserver.yaml -
Check the status of the SPIRE Server by entering the following command. Wait for the
Readystatus to be returned before proceeding to the next step.$ oc get spireserver cluster -wExample outputNAME STATUS AGE cluster Ready 5m -
Verify that the federation route has been created by running the following command:
$ oc get route -n zero-trust-workload-identity-manager | grep federationExample outputNAME HOST/PORT PATH SERVICES PORT TERMINATION spire-server-federation federation.apps.cluster1.example.com spire-server 8443 passthrough -
On each cluster, fetch the trust bundle from the federation endpoint by running the following command:
$ curl https://federation.apps.cluster1.example.com > cluster1-bundle.jsonThe response contains the trust bundle in JSON Web Key Set (JWKS) format:
Example trust bundle{ "keys": [ { "use": "x509-svid", "kty": "RSA", "n": "...", "e": "AQAB", "x5c": ["..."] } ], "spiffe_sequence": 1, "refresh_hint": 300 } -
Create
ClusterFederatedTrustDomainresources to establish federation relationships.-
On Cluster 1, create resources to federate with Cluster 2 and Cluster 3:
apiVersion: spire.spiffe.io/v1alpha1 kind: ClusterFederatedTrustDomain metadata: name: cluster2-federation spec: trustDomain: cluster2.example.com bundleEndpointURL: https://federation.apps.cluster2.example.com bundleEndpointProfile: type: https_web className: zero-trust-workload-identity-manager-spire trustDomainBundle: | { "keys": [...], "spiffe_sequence": 1 } --- apiVersion: spire.spiffe.io/v1alpha1 kind: ClusterFederatedTrustDomain metadata: name: cluster3-federation spec: trustDomain: cluster3.example.com bundleEndpointURL: https://federation.apps.cluster3.example.com bundleEndpointProfile: type: https_web className: zero-trust-workload-identity-manager-spire trustDomainBundle: | { "keys": [...], "spiffe_sequence": 1 }-
The
spec.trustDomainBundlefield contains the complete trust bundle JSON that you fetched usingcurlin step 5. -
The
spec.classNamefield contains the name of a class to watch CRs for. Spire-controller-manager watches the resource only ifspec.classNameis set tozero-trust-workload-identity-manager-spire.
-
-
-
Apply the
ClusterFederatedTrustDomainresources by running the following command:$ oc apply -f cluster-federated-trust-domains.yaml -
Repeat steps 6 and 7 on each cluster to establish bidirectional federation. Each cluster needs
ClusterFederatedTrustDomainresources for every other cluster it federates with. -
Update the
SpireServerresource on each cluster to add thefederatesWithconfiguration:apiVersion: operator.openshift.io/v1alpha1 kind: SpireServer metadata: name: cluster spec: # ... existing configuration ... federation: bundleEndpoint: # ... existing bundleEndpoint configuration ... federatesWith: - trustDomain: cluster2.example.com bundleEndpointUrl: https://federation.apps.cluster2.example.com bundleEndpointProfile: https_web - trustDomain: cluster3.example.com bundleEndpointUrl: https://federation.apps.cluster3.example.com bundleEndpointProfile: https_web managedRoute: "true"-
The
spec.federation.federatesWithfield lists all remote trust domains this cluster should federate with.
-
-
Apply the updated configuration by running the following command:
$ oc apply -f spireserver.yaml
-
Verify that the
ClusterFederatedTrustDomainresources have been created by running the following command:$ oc get clusterfederatedtrustdomainsExample outputNAME TRUST DOMAIN ENDPOINT URL AGE cluster2-federation cluster2.example.com https://federation.apps.cluster2.example.com 5m cluster3-federation cluster3.example.com https://federation.apps.cluster3.example.com 5m -
Check the status of a
ClusterFederatedTrustDomainto ensure bundle synchronization is working by running the following command:$ oc describe clusterfederatedtrustdomain cluster2-federationLook for
Successfulstatus conditions indicating that the trust bundle has been synchronized. -
Verify that the federation endpoint is accessible and serving the trust bundle by running the following command:
$ curl https://federation.apps.cluster1.example.comYou should receive a JSON response containing the trust bundle.
-
Check the SPIRE Server logs to confirm federation is active by running the following command:
$ oc logs -n zero-trust-workload-identity-manager deployment/spire-server -c spire-server --tail=50Look for log messages indicating successful bundle synchronization with federated trust domains.
-
Verify that all SPIRE components are running by running the following command:
$ oc get pods -n zero-trust-workload-identity-managerExample outputNAME READY STATUS RESTARTS AGE spire-agent-abcde 1/1 Running 0 10m spire-server-0 2/2 Running 0 10m -
Optional: Test cross-cluster workload authentication by deploying workloads with SPIFFE identities on different clusters and verifying they can authenticate to each other using the federated trust.