1
0
mirror of https://github.com/openshift/openshift-docs.git synced 2026-02-05 12:46:18 +01:00
Files
openshift-docs/modules/zero-trust-manager-automatic-management.adoc
2025-12-18 19:28:21 +00:00

270 lines
8.1 KiB
Plaintext

// Module included in the following assemblies:
//
// * security/zero_trust_workload_identity_manager/zero-trust-manager-spire-federation.adoc
:_mod-docs-content-type: PROCEDURE
[id="zero-trust-manager-automatic-management_{context}"]
= Using SPIRE federation with Automatic Certificate Management Environment protocol
[role="_abstract"]
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.
.Prerequisites
* You have installed the {zero-trust-full} on all clusters that will participate in the federation.
* You have installed the OpenShift CLI (`oc`).
* You have `cluster-admin` privileges 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.
.Procedure
. Configure the `SpireServer` custom resource on each cluster to enable federation with ACME certificate management.
+
Create or update your `SpireServer` resource with the federation configuration:
+
[source,yaml]
----
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 `trustDomain` field sets a unique trust domain for each cluster (for example, `cluster1.example.com`, `cluster2.example.com`).
* The `profile` field uses the `https_web` profile for ACME-based certificate management.
* The `directoryUrl` field contains the Let's Encrypt production directory URL. For testing, use: `https://acme-staging-v02.api.letsencrypt.org/directory`.
* The `domainName` field is the domain name where your federation endpoint is accessible. This automatically sets to `federation.<cluster-apps-domain>` if `managedRoute` is set to "true".
* The `email` field is your email address for ACME account registration and certificate expiration notifications.
* The `tosAccepted` field accepts the Let's Encrypt Terms of Service.
* The `managedRoute` field enables an automatic route creation by the operator for the federation bundle endpoint.
. Apply the configuration to each cluster by running the following command:
+
[source,terminal]
----
$ oc apply -f spireserver.yaml
----
. Check the status of the SPIRE Server by entering the following command. Wait for the `Ready` status to be returned before proceeding to the next step.
+
[source,terminal]
----
$ oc get spireserver cluster -w
----
+
.Example output
[source,terminal]
----
NAME STATUS AGE
cluster Ready 5m
----
. Verify that the federation route has been created by running the following command:
+
[source,terminal]
----
$ oc get route -n zero-trust-workload-identity-manager | grep federation
----
+
.Example output
[source,terminal]
----
NAME 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:
+
[source,terminal]
----
$ curl https://federation.apps.cluster1.example.com > cluster1-bundle.json
----
+
The response contains the trust bundle in JSON Web Key Set (JWKS) format:
+
.Example trust bundle
[source,json]
----
{
"keys": [
{
"use": "x509-svid",
"kty": "RSA",
"n": "...",
"e": "AQAB",
"x5c": ["..."]
}
],
"spiffe_sequence": 1,
"refresh_hint": 300
}
----
. Create `ClusterFederatedTrustDomain` resources to establish federation relationships.
+
.. On Cluster 1, create resources to federate with Cluster 2 and Cluster 3:
+
[source,yaml]
----
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
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
trustDomainBundle: |
{
"keys": [...],
"spiffe_sequence": 1
}
----
* The `trustDomainBundle` field contains the complete trust bundle JSON that you fetched using `curl` in step 5.
. Apply the `ClusterFederatedTrustDomain` resources by running the following command:
+
[source,terminal]
----
$ oc apply -f cluster-federated-trust-domains.yaml
----
. Repeat steps 6 and 7 on each cluster to establish bidirectional federation. Each cluster needs `ClusterFederatedTrustDomain` resources for every other cluster it federates with.
. Update the `SpireServer` resource on each cluster to add the `federatesWith` configuration:
+
[source,yaml]
----
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 `federatesWith` field lists all remote trust domains this cluster should federate with.
. Apply the updated configuration by running the following command:
+
[source,terminal]
----
$ oc apply -f spireserver.yaml
----
.Verification
. Verify that the `ClusterFederatedTrustDomain` resources have been created by running the following command:
+
[source,terminal]
----
$ oc get clusterfederatedtrustdomains
----
+
.Example output
[source,terminal]
----
NAME 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 `ClusterFederatedTrustDomain` to ensure bundle synchronization is working by running the following command:
+
[source,terminal]
----
$ oc describe clusterfederatedtrustdomain cluster2-federation
----
+
Look for `Successful` status 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:
+
[source,terminal]
----
$ curl https://federation.apps.cluster1.example.com
----
+
You should receive a JSON response containing the trust bundle.
. Check the SPIRE Server logs to confirm federation is active by running the following command:
+
[source,terminal]
----
$ oc logs -n zero-trust-workload-identity-manager deployment/spire-server -c spire-server --tail=50
----
+
Look for log messages indicating successful bundle synchronization with federated trust domains.
. Verify that all SPIRE components are running by running the following command:
+
[source,terminal]
----
$ oc get pods -n zero-trust-workload-identity-manager
----
+
.Example output
[source,terminal]
----
NAME 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.