Este contenido no está disponible en el idioma seleccionado.
Chapter 10. Zero Trust Workload Identity Manager
10.1. Zero Trust Workload Identity Manager overview Copiar enlaceEnlace copiado en el portapapeles!
The Zero Trust Workload Identity Manager is an OpenShift Container Platform Operator that manages the lifecycle of SPIFFE Runtime Environment (SPIRE) components. It enables workload identity management based on the Secure Production Identity Framework for Everyone (SPIFFE) standard, providing cryptographically verifiable identities (SVIDs) to workloads running in OpenShift Container Platform clusters.
The following are components of the Zero Trust Workload Identity Manager architecture:
10.1.1. SPIFFE Copiar enlaceEnlace copiado en el portapapeles!
Secure Production Identity Framework for Everyone (SPIFFE) provides a standardized way to establish trust between software workloads in distributed systems. SPIFFE assigns unique IDs called SPIFFE IDs. These IDs are Uniform Resource Identifiers (URI) that include a trust domain and a workload identifier.
The SPIFFE IDs are contained in the SPIFFE Verifiable Identity Document (SVID). SVIDs are used by workloads to verify their identity to other workloads so that the workloads can communicate with each other. The two main SVID formats are:
- X.509-SVIDs: X.509 certificates where the SPIFFE ID is embedded in the Subject Alternative Name (SAN) field.
-
JWT-SVIDs: JSON Web Tokens (JWTs) where the SPIFFE ID is included as the
subclaim.
For more information, see SPIFFE Overview.
10.1.2. SPIRE Server Copiar enlaceEnlace copiado en el portapapeles!
A SPIRE Server is responsible for managing and issuing SPIFFE identities within a trust domain. It stores registration entries (selectors that determine under what conditions a SPIFFE ID should be issued) and signing keys. The SPIRE Server works in conjunction with the SPIRE Agent to perform node attestion via node plugins. For more information, see About the SPIRE Server.
10.1.3. SPIRE Agent Copiar enlaceEnlace copiado en el portapapeles!
The SPIRE Agent is responsible for workload attestation, ensuring that workloads receive a verified identity when requesting authentication through the SPIFFE Workload API. It accomplishes this by using configured workload attestor plugins. In Kubernetes environments, the Kubernetes workload attestor plugin is used.
SPIRE and the SPIRE Agent perform node attestation via node plugins. The plugins are used to verify the identity of the node on which the agent is running. For more information, see About the SPIRE Agent.
10.1.4. Attestation Copiar enlaceEnlace copiado en el portapapeles!
Attestation is the process by which the identity of nodes and workloads are verified before SPIFFE IDs and SVIDs are issued. The SPIRE Server gathers attributes of both the workload and node that the SPIRE Agent runs on, and then compares them to a set of selectors defined when the workload was registered. If the comparison is successful, the entities are provided with credentials. This ensures that only legitimate and expected entities within the trust domain receive cryptographic identities. The two main types of attestation in SPIFFE/SPIRE are:
- Node attestation: verifies the identity of a machine or a node on a system, before a SPIRE Agent running on that node can be trusted to request identities for workloads.
- Workload attestation: verifies the identity of an application or service running on an attested node before the SPIRE Agent on that node can provide it with a SPIFFE ID and SVID.
For more information, see Attestation.
10.2. Zero Trust Workload Identity Manager components Copiar enlaceEnlace copiado en el portapapeles!
Review the components available in the initial release of Zero Trust Workload Identity Manager to understand the architecture. These components provide the foundation for identifying and securing your workloads.
10.2.1. SPIFFE CSI Driver Copiar enlaceEnlace copiado en el portapapeles!
The SPIFFE Container Storage Interface (CSI) driver helps pods securely obtain their SPIFFE Verifiable Identity Document (SVID) by delivering the Workload API socket. By using Kubernetes ephemeral inline volumes, the driver simplifies how applications request temporary storage for identity management.
When the pod starts, the Kubelet calls the SPIFFE CSI driver to provision and mount a volume into the pod’s containers. The SPIFFE CSI driver mounts a directory that contains the SPIFFE Workload API into the pod. Applications in the pod then communicate with the Workload API to obtain their SVIDs. The driver guarantees that each SVID is unique.
10.2.2. SPIRE OpenID Connect Discovery Provider Copiar enlaceEnlace copiado en el portapapeles!
Use the SPIRE OpenID Connect (OIDC) Discovery Provider to integrate SPIRE workload identities with OIDC-compliant systems. This component exposes endpoints for token verification. It helps ensure compatibility between SPIRE-issued credentials and external APIs requiring standard OIDC tokens.
While SPIRE primarily issues identities for workloads, additional workload-related claims can be embedded into JWT-SVIDs through the configuration of SPIRE, which these claims to be included in the token and verified by OIDC-compliant clients.
10.2.3. SPIRE Controller Manager Copiar enlaceEnlace copiado en el portapapeles!
Use the SPIRE Controller Manager to automate workload registration with custom resource definitions (CRDs). The manager monitors pods and CRDs to create, update, or delete entries on the SPIRE Server. This process helps ensure that your SPIRE entries accurately reflect your active resources.
The SPIRE Controller Manager is designed to be deployed on the same pod as the SPIRE Server. The manager communicates with the SPIRE Server API using a private UNIX Domain Socket within a shared volume.
10.2.4. SPIRE Server and Agent telemetry Copiar enlaceEnlace copiado en el portapapeles!
Use the SPIRE Controller Manager to register workloads by using custom resource definitions (CRDs). The manager monitors pods and CRDs for changes and triggers a reconciliation process. This process creates, updates, or deletes SPIRE Server entries to help ensure they match your configuration.
10.2.5. About the Zero Trust Workload Identity Manager workflow Copiar enlaceEnlace copiado en el portapapeles!
Understand the high-level workflow of Zero Trust Workload Identity Manager to help you manage secure identities. This process relies on SPIRE components and custom resource definitions (CRDs) to validate nodes and workloads.
The following is a high-level workflow of the Zero Trust Workload Identity Manager within the Red Hat OpenShift cluster.
- The SPIRE, SPIRE Agent, SPIFFE CSI Driver, and the SPIRE OIDC Discovery Provider operands are deployed and managed by Zero Trust Workload Identity Manager via associated customer resource definitions (CRDs).
- Watches are then registered for relevant Kubernetes resources and the necessary SPIRE CRDs are applied to the cluster.
-
The CR for the ZeroTrustWorkloadIdentityManager resource named
clusteris deployed and managed by a controller. To deploy the SPIRE Server, SPIRE Agent, SPIFFE CSI Driver, and SPIRE OIDC Discovery Provider, you need to create a custom resource of a each certain type and name it
cluster. The custom resource types are as follows:-
SPIRE Server -
SpireServer -
SPIRE Agent -
SpireAgent -
SPIFFE CSI Driver -
SpiffeCSIDriver -
SPIRE OIDC discovery provider -
SpireOIDCDiscoveryProvider
-
SPIRE Server -
- When a node starts, the SPIRE Agent initializes, and connects to the SPIRE Server.
- The SPIRE Agent begins the node attestation process. The agent collects information on the node’s identity such as label name and namespace. The agent securely provides the information it gathered through the attestation to the SPIRE Server.
- The SPIRE Server then evaluates this information against its configured attestation policies and registration entries. If successful, the server generates an agent SVID and the Trust Bundle (CA Certificate) and securely sends this back to the SPIRE Agent.
- A workload starts on the node and needs a secure identity. The workload connects to the agent’s Workload API and requests a SVID.
- The SPIRE Agent receives the request and begins a workload attestation to gather information about the workload.
- After the SPIRE Agent gathers the information, the information is sent to the SPIRE Server and the server checks its configured registration entries.
- The SPIRE Agent receives the workload SVID and Trust Bundle and passes it on to the workload. The workload can now present their SVIDs to other SPIFFE-aware devices to communicate with them.
10.3. Zero Trust Workload Identity Manager release notes Copiar enlaceEnlace copiado en el portapapeles!
The Zero Trust Workload Identity Manager leverages Secure Production Identity Framework for Everyone (SPIFFE) and the SPIFFE Runtime Environment (SPIRE) to provide a comprehensive identity management solution for distributed systems.
These release notes track the development of Zero Trust Workload Identity Manager.
10.3.1. Zero Trust Workload Identity Manager 1.0.0 (General Availability) Copiar enlaceEnlace copiado en el portapapeles!
Issued: 2025-12-17
This release introduces capabilities for enterprise readiness, security, and operational flexibility. It includes SPIRE federation for cross-cluster identity, PostgreSQL support for production persistence, and enhanced security through stricter constraints and API validation.
The following advisories are available for the Zero Trust Workload Identity Manager.
Zero Trust Workload Identity Manager supports the following components and versions:
| Component | Version |
|---|---|
| SPIRE Server | 1.13.3 |
| SPIRE Agent | 1.13.3 |
| SPIRE Controller Manager | 0.6.3 |
| SPIRE OIDC Discovery Provider | 1.13.3 |
| SPIFFE CSI Driver | 0.2.8 |
10.3.1.1. New features and enhancements Copiar enlaceEnlace copiado en el portapapeles!
- SPIRE federation support
The Operator now includes support for SPIRE federation, enabling workloads across distinct trust domains to securely communicate and authenticate with each other.
Key capabilities:
-
Configuration of bundle endpoints using
https_spiffe(TLS) orhttps_web(Web PKI) profiles. - Automatic certificate management via the ACME protocol (e.g., Let’s Encrypt).
- Automatic OpenShift Container Platform route creation for federation endpoints.
- Ability to configure relationships with multiple federated trust domains.
-
Configuration of bundle endpoints using
Customer action required:
-
Review the
federationconfiguration within theSpireServerCustom Resource (CR). - Ensure proper DNS resolution and network connectivity to federated trust domains.
-
Review the
- PostgreSQL database support
SPIRE Server now supports PostgreSQL as an external database backend, accommodating production deployments that necessitate enterprise-grade data persistence and high availability.
-
Supported Types:
sqlite3(default),postgres,mysql. Customer action required:
- For production, evaluation of migration from SQLite to PostgreSQL is recommended.
- Creation and configuration of Kubernetes Secrets for database TLS certificates and credentials are required.
-
Supported Types:
- Configurable agent socket path and Container Storage Interface (CSI) plugin name
The SPIRE Agent socket path and the SPIFFE CSI Driver plugin name are now configurable, providing operational flexibility for environments with specific directory requirements or co-existence with multiple SPIFFE deployments.
Key configuration points:
-
SpireAgent.spec.socketPath -
SpiffeCSIDriver.spec.agentSocketPath -
SpiffeCSIDriver.spec.pluginName
-
Customer action required:
-
Ensure consistency between
socketPathin theSpireAgentCR andagentSocketPathin theSpiffeCSIDriverCR.
-
Ensure consistency between
- Workload attestors verification API
A new API has been introduced to configure kubelet certificate verification for workload attestation, enhancing security and supporting various OpenShift configurations.
Verification types:
-
auto(default): Verification utilizes OpenShift defaults (/etc/kubernetes/kubelet-ca.crt). -
hostCert: Uses a custom CA certificate path. -
skip: Skips TLS verification (not recommended for production use).
-
- Configurable Certificate Authority and JSON Web Token key types
Administrators can now configure the cryptographic key types used for the SPIRE Server Certificate Authority (CA) and JSON Web Token (JWT) signing, ensuring compliance with organizational security policies.
-
Supported Key Types:
rsa-2048(default),rsa-4096,ec-p256,ec-p384. Customer action required:
- Review organizational security policies to determine required key types.
-
Supported Key Types:
- Custom namespace deployment
- The Operator and all associated operands can now be deployed within a custom namespace, providing flexibility for organizations with specific namespace governance requirements.
- Proxy-aware Operator and operands
- The Operator and all managed operands are now proxy-aware and automatically inherit cluster-wide proxy settings when configured.
- Enhanced Security Context Constraints
- SPIRE Agent and SPIFFE CSI Driver now run with Security Context Constraints (SCC) that prevent root user execution, though privileged container mode remains enabled for necessary host-level operations.
-
The Operator and all operand containers are configured with the
ReadOnlyRootFilesystemset totrue.
- Enhanced API validation
Comprehensive Common Expression Language (CEL) validation has been integrated into all Custom Resource Definitions (CRDs) to prevent configuration errors during admission control.
Key validations:
-
All Operator CRDs are enforced as singletons (must be named
cluster). -
Immutable Fields: Fields including
trustDomain,clusterName,bundleConfigMap,federation,bundleEndpointprofile, and allPersistencesettings (size,accessMode, andstorageClass) are now immutable after initial creation.
-
All Operator CRDs are enforced as singletons (must be named
Customer action required:
- Review existing CR configurations to ensure compliance with the new validation rules.
- Common configuration consolidation
-
Standard configuration options (
labels,resources,affinity,tolerations,nodeSelector) are now standardized across all operand CRs via a sharedCommonConfigstructure.
-
Standard configuration options (
- Configuring log level and log format for the operands
This release introduces flexible logging controls to improve observability and debugging across the platform:
-
SPIRE Components: Users can now configure the
logLevel(debug, info, warn, error) andlogFormat(text, JSON) independently forSpireServer,SpireAgent, andSpireOIDCDiscoveryProviderdirectly within their CR specifications. The defaults are set to "info" for thelogLeveland "text" for thelogFormat. -
Operator: The operator’s log verbosity is now configurable via the
OPERATOR_LOG_LEVELenvironment variable using klog’stextlogger.
-
SPIRE Components: Users can now configure the
- Refactor for create-only mode
-
By setting the
CREATE_ONLY_MODEenvironment variable, users can prevent the operator from reconciling updates. This allows for manual resource modification without interference. If this mode is disabled, the Operator resumes enforcing the state and overwrites any manual changes.
10.3.1.2. Status and observability improvements Copiar enlaceEnlace copiado en el portapapeles!
- Enhanced status reporting
- The main CR now aggregates status information from all operand CRs.
- New status conditions include Upgradeable (indicating a safe upgrade path) and Progressing (detailing deployment progress).
- Operator metrics
- Operator metrics are now exposed and secured with appropriate RBAC configuration.
- Integration is supported with the OpenShift monitoring stack.
10.3.1.3. Fixed issues Copiar enlaceEnlace copiado en el portapapeles!
- Enhanced Security Context Constraints for SPIRE Agent
Before this update, the SPIRE Agent and SPIFFE CSI Driver containers were running as root user, leading to potential security violations. With this release, Security Context Constraints (SCC) have been configured to ensure these components no longer run as root. While privileged container mode is still required for necessary capabilities, this change reduces potential security risks for the end user.
(SPIRE-60)
- SpireServer updates now propagate without operator restart
Before this update, the operator failed to trigger reconciliation after updating the operand CR spec. As a consequence, user updates to SpireServer CR resources were not propagated to the StatefulSet, causing reconciliation to fail and changes to be ignored, leading to inconsistent resource allocation. With this release, the race condition between the manager and reconciler’s cache to trigger reconciliation after CR updates has been fixed. As a result, day2 patch operations on SpireServer CRs will reliably trigger reconciliation, ensuring updated values are applied to the StatefulSet without manual operator restart.
(SPIRE-68)
- Removed unnecessary security context constraint for OpenID Connect discovery provider
Before this update, the system unnecessarily created a custom security context constraint (SCC) for the OpenID Connect (OIDC) discovery provider, which increased the security footprint and configuration complexity even though the deployment did not require it. With this release, the custom SCC creation logic has been removed, resulting in a configuration where the OIDC discovery provider operates successfully without the extra security constraints.
- Fixed ConfigMap Reconciliation for SPIRE Controller Manager
Before this update, Spire-controller manager ConfigMap reconciliation failed due to an unhandled edge case in the previous implementation. As a consequence, users experienced configuration inconsistencies. With this release, the Spire-controller manager ConfigMap reconciliation issue has been resolved. As a result, end users now experience seamless Spire-controller manager configuration.
- OIDC discovery provider now restarts automatically on configuration changes
Before this update, the SPIRE OIDC discovery provider failed to automatically restart following
configmapchanges, leading to persistent authentication failures. With this release, updates to the CR now trigger an automatic pod restart, ensuring thatconfigmapchanges are applied immediately, providing a seamless experience for end users.
- Corrected update rollback for DaemonSets, Deployments, and StatefulSets
Before this update,
daemonset,deployment, andstatefulsetswere not properly reverted to their original form in all valid scenarios due to an oversight in the update logic. As a consequence, user data loss or inconsistency occurred in valid scenarios. With this release, the update logic has been corrected, ensuring all valid scenarios revert to their original form.Other bug fixes included:
- Fixed issues related to continuous reconciliation and unnecessary updates.
- Eliminated requeue logic for user input validation errors.
10.3.2. Zero Trust Workload Identity Manager 0.2.0 (Technology Preview) Copiar enlaceEnlace copiado en el portapapeles!
Issued: 2025-09-08
The following advisories are available for the Zero Trust Workload Identity Manager.
This release of Zero Trust Workload Identity Manager is a Technology Preview.
10.3.2.1. New features and enhancements Copiar enlaceEnlace copiado en el portapapeles!
- Support for the managed OIDC Discovery Provider Route
-
The Operator exposes the
SPIREOIDCDiscoveryProviderspec through OpenShift Routes under the domain*.apps.<cluster_domain>for the selected default installation. -
The
managedRouteandexternalSecretReffields have been added to thespireOidcDiscoveryProviderspec. -
The
managedRoutefield is boolean and is set totrueby default. If set tofalse, the Operator stops managing the route and the existing route will not be deleted automatically. If set back totrue, the Operator resumes managing the route. If a route does not exist, the Operator creates a new one. If a route already exists, the Operator will override the user configuration if a conflict exists. -
The
externalSecretRefreferences an externally managed Secret that has the TLS certificate for theoidc-discovery-providerRoute host. When provided, this populates the route’s.Spec.TLS.ExternalCertificatefield. For more information, see Creating a route with externally managed certificate
-
The Operator exposes the
- Enabling the custom Certificate Authority Time-To-Live for the SPIRE bundle
The following Time-To-Live (TTL) fields have been added to the
SpireServercustom resource definition (CRD) API for SPIRE Server certificate management:-
CAValidity(default: 24h) -
DefaultX509Validity(default: 1h) -
DefaultJWTValidity(default: 5m)
-
- The default values can be replaced in the server configuration with user-configurable options that give users the flexibility to customize certificate and SPIFFE Verifiable Identity Document (SVID) lifetimes based on their security requirements.
- Enabling Manual User Configurations
-
The Operator controller switches to
create-onlymode once theztwim.openshift.io/create-only=trueannotation is present on the Operator’s APIs. This allows resource creation while skipping the updates. A user can update the resources manually to test their configuration. This annotation supports APIs such asSpireServer,SpireAgents,SpiffeCSIDriver,SpireOIDCDiscoveryProvider, andZeroTrustWorkloadIdentityManager. - When the annotation is applied, all derived resources including resources created and managed by the Operator.
- Once the annotation is removed and the pod restarts, the operator tries to come back to the required state. The annotation is applied only once during start or a restart.
-
The Operator controller switches to
10.3.2.2. Fixed issues Copiar enlaceEnlace copiado en el portapapeles!
- JSON Web Token Issuer field now requires a valid URL
Before this update, the
JwtIssuerfield for both theSpireServerand theSpireOidcDiscoveryProviderdid not need to be a URL causing an error in configurations. With this release, the user must manually enter an issuer URL in theJwtIssuerfield in both custom resources.
10.3.3. Zero Trust Workload Identity Manager 0.1.0 (Technology Preview) Copiar enlaceEnlace copiado en el portapapeles!
The Zero Trust Workload Identity Manager is a Technology Preview feature only. Technology Preview features are not supported with Red Hat production service level agreements (SLAs) and might not be functionally complete. Red Hat does not recommend using them in production. These features provide early access to upcoming product features, enabling customers to test functionality and provide feedback during the development process.
For more information about the support scope of Red Hat Technology Preview features, see Technology Preview Features Support Scope.
Issued: 2025-06-16
The following advisories are available for the Zero Trust Workload Identity Manager:
This initial release of Zero Trust Workload Identity Manager is a Technology Preview. This version has the following known limitations:
- Support for SPIRE federation is not enabled.
-
Key manager supports only the
diskstorage type. - Telemetry is supported only through Prometheus.
- High availability (HA) configuration for SPIRE Servers or the OpenID Connect (OIDC) Discovery provider is not supported.
-
External datastore is not supported. This version uses the internal
sqlitedatastore deployed by SPIRE. - This version operates using a fixed configuration. User-defined configurations are not allowed.
-
The log level of operands are not configurable. The default value is
DEBUG.
10.4. Installing the Zero Trust Workload Identity Manager Copiar enlaceEnlace copiado en el portapapeles!
Install Zero Trust Workload Identity Manager to help ensure secure communication between your workloads. You can install the Zero Trust Workload Identity Manager by using either the web console or CLI.
If you install the Operator into a custom namespace (for example, my-custom-namespace), all managed operand resources are deployed within that same namespace. All secrets and ConfigMaps referenced by the Custom Resources (CRs) must also exist in that custom namespace.
The Operator installation is not supported in the openshift-* namespaces and the default namespace.
10.4.1. Installing the Zero Trust Workload Identity Manager by using the web console Copiar enlaceEnlace copiado en el portapapeles!
Use the OperatorHub in the OpenShift Container Platform web console to install the Zero Trust Workload Identity Manager. This process streamlines deployment and helps ensure the Operator is installed in the correct namespace with the appropriate installation mode.
A minimum of 1Gi persistent volume is required to install the SPIRE Server.
Prerequisites
-
You have access to the cluster with
cluster-adminprivileges. - You have access to the OpenShift Container Platform web console.
Procedure
- Log in to the OpenShift Container Platform web console.
-
Go to Ecosystem
Software Catalog. - Search for Zero Trust Workload Identity Manager.
On the Install Operator page:
-
Update the Update channel, if necessary. The channel defaults to
stable-v1, which installs the lateststable-v1release of the Zero Trust Workload Identity Manager. Choose the Installed Namespace for the Operator. The default Operator namespace is
zero-trust-workload-identity-manager.If the
zero-trust-workload-identity-managernamespace does not exist, it is created for you.NoteThe Operator and operands are deployed in the same namespace.
Select an Update Approval strategy
- The Automatic strategy allows Operator Lifecycle Manager (OLM) to automatically update the Operator when a new version is available.
- The Manual strategy requires a user with appropriate credentials to approve the Operator update.
-
Update the Update channel, if necessary. The channel defaults to
- Click Install.
Verification
Navigate to Ecosystem
Installed Operators. -
Verify that Zero Trust Workload Identity Manager is listed with a Status of Succeeded in the
zero-trust-workload-identity-managernamespace. Verify that Zero Trust Workload Identity Manager controller manager deployment is ready and available by running the following command:
oc get deployment -l name=zero-trust-workload-identity-manager -n zero-trust-workload-identity-manager
$ oc get deployment -l name=zero-trust-workload-identity-manager -n zero-trust-workload-identity-managerCopy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
NAME READY UP-TO-DATE AVAILABLE AGE zero-trust-workload-identity-manager-controller-manager-6c4djb 1/1 1 1 43m
NAME READY UP-TO-DATE AVAILABLE AGE zero-trust-workload-identity-manager-controller-manager-6c4djb 1/1 1 1 43mCopy to Clipboard Copied! Toggle word wrap Toggle overflow
-
Verify that Zero Trust Workload Identity Manager is listed with a Status of Succeeded in the
To check the Operator logs, run the following command:
oc logs -f deployment/zero-trust-workload-identity-manager -n zero-trust-workload-identity-manager
$ oc logs -f deployment/zero-trust-workload-identity-manager -n zero-trust-workload-identity-managerCopy to Clipboard Copied! Toggle word wrap Toggle overflow
10.4.2. Installing the Zero Trust Workload Identity Manager by using the CLI Copiar enlaceEnlace copiado en el portapapeles!
Prerequisites
-
You have access to the cluster with
cluster-adminprivileges.
A minimum of 1Gi persistent volume is required to install the SPIRE Server.
Procedure
Create a new project named
zero-trust-workload-identity-managerby running the following command:oc new-project zero-trust-workload-identity-manager
$ oc new-project zero-trust-workload-identity-managerCopy to Clipboard Copied! Toggle word wrap Toggle overflow Create an
OperatorGroupobject:Create a YAML file, for example,
operatorGroup.yaml, with the following content:Example
operatorGroup.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow Create the
OperatorGroupobject by running the following command:oc create -f operatorGroup.yaml
$ oc create -f operatorGroup.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Create a
Subscriptionobject:Create a YAML file, for example,
subscription.yaml, that defines theSubscriptionobject:Example
subscription.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow Create the
Subscriptionobject by running the following command:oc create -f subscription.yaml
$ oc create -f subscription.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
Verify that the OLM subscription is created by running the following command:
oc get subscription -n zero-trust-workload-identity-manager
$ oc get subscription -n zero-trust-workload-identity-managerCopy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
NAME PACKAGE SOURCE CHANNEL openshift-zero-trust-workload-identity-manager zero-trust-workload-identity-manager redhat-operators stable-v1
NAME PACKAGE SOURCE CHANNEL openshift-zero-trust-workload-identity-manager zero-trust-workload-identity-manager redhat-operators stable-v1Copy to Clipboard Copied! Toggle word wrap Toggle overflow Verify whether the Operator is successfully installed by running the following command:
oc get csv -n zero-trust-workload-identity-manager
$ oc get csv -n zero-trust-workload-identity-managerCopy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
NAME DISPLAY VERSION PHASE zero-trust-workload-identity-manager.v1.0.0 Zero Trust Workload Identity Manager 1.0.0 Succeeded
NAME DISPLAY VERSION PHASE zero-trust-workload-identity-manager.v1.0.0 Zero Trust Workload Identity Manager 1.0.0 SucceededCopy to Clipboard Copied! Toggle word wrap Toggle overflow Verify that the Zero Trust Workload Identity Manager controller manager is ready by running the following command:
oc get deployment -l name=zero-trust-workload-identity-manager -n zero-trust-workload-identity-manager
$ oc get deployment -l name=zero-trust-workload-identity-manager -n zero-trust-workload-identity-managerCopy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
NAME READY UP-TO-DATE AVAILABLE AGE zero-trust-workload-identity-manager-controller-manager 1/1 1 1 43m
NAME READY UP-TO-DATE AVAILABLE AGE zero-trust-workload-identity-manager-controller-manager 1/1 1 1 43mCopy to Clipboard Copied! Toggle word wrap Toggle overflow
10.5. Deploying Zero Trust Workload Identity Manager operands Copiar enlaceEnlace copiado en el portapapeles!
You can deploy the following operands by creating the respective custom resources (CRs). You must deploy the operands in the following sequence to ensure successful installation.
-
ZeroTrustWorkloadIdentityManagerCR* SPIRE Server - SPIRE Agent
- SPIFFE CSI driver
- SPIRE OIDC discovery provider
10.5.1. About the ZeroTrustWorkloadIdentityManager custom resource Copiar enlaceEnlace copiado en el portapapeles!
The ZeroTrustWorkloadIdentityManager is the primary custom resource that initializes the SPIRE deployments. This primary resource defines the trust domain and cluster name to help ensure secure workload identity management.
Reference the complete YAML specification to correctly structure the ZeroTrustWorkloadIdentityManager CR. This example helps you identify required fields and immutable parameters for your configuration.
where:
- trustDomain
- Specifies tThe trust domain to be used for the SPIFFE identifiers. Must be a valid SPIFFE trust domain (lowercase alphanumeric, hyphens, and dots). Maximum length is 255 characters. Once set, this field is immutable.
- clusterName
- Specifies tThe name that identifies this cluster within the trust domain. Must be a valid DNS-1123 subdomain with a maximum length of 63 characters. Once set, this field is immutable.
- bundleConfigMap
-
Specifies the name of the ConfigMap that stores the SPIRE trust bundle. This ConfigMap contains the root certificates for the trust domain and is created and maintained by the Operator. Must be a valid Kubernetes name with a maximum length of 253 characters. This field is optional (defaults to
spire-bundle) and once set, is immutable.
10.5.2. Deploying the SPIRE Server Copiar enlaceEnlace copiado en el portapapeles!
You can configure the SpireServer custom resource (CR) to deploy and configure a SPIRE Server.
Prerequisites
-
You have access to the cluster as a user with the
cluster-adminrole. - You have installed Zero Trust Workload Identity Manager in the cluster.
Procedure
Create the
SpireServerCR:Create a YAML file that defines the
SpireServerCR, for example,SpireServer.yaml:Example
SpireServer.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow where:
- name
- Specifies that the value mmust be 'cluster'.
- logLevel
-
Specifies the logging level for the SPIRE Server. The valid options are
debug,info,warn, anderror. - logFormat
-
Specifies the logging format for the SPIRE Server. The valid options are
textandjson. - jwtIssuer
- Specifies the JWT issuer URL. Must be a valid HTTPS or HTTP URL with a maximum length of 512 characters.
- caValidity
-
Specifies the validity period (Time to Live (TTL)) for the SPIRE Server’s CA certificate. This determines how long the server’s root or intermediate certificate is valid. The format is a duration string (for example,
24h,168h). - defaultX509Validity
- Specifies the default validity period (TTL) for X.509 SVIDs issued to workloads. This value is used if a specific TTL is not configured for a registration entry.
- defaultJWTValidity
- Specifies thedefault validity period (TTL) for JWT SVIDs issued to workloads. This value is used if a specific TTL is not configured for a registration entry.
- jwtKeyType
-
Specifies the key type used for JWT signing. The valid options are
rsa-2048,rsa-4096,ec-p256, andec-p384. This field is optional. - country
- Specifies the country for the SPIRE Server certificate authority (CA). Must be an ISO 3166-1 alpha-2 country code (2 characters).
- organization
- Specifies the organization for the SPIRE Server CA. Maximum length is 64 characters.
- commonName
- Specifies the common name for the SPIRE Server CA. Maximum length is 255 characters.
- size
-
Specifies the size of the persistent volume (for example,
1Gi,5Gi). Once set, this field is immutable. - accessMode
-
Specifies the access mode for the persistent volume. The valid options are
ReadWriteOnce,ReadWriteOncePod, andReadWriteMany. Once set, this field is immutable. - storageClass
- Specifies the storage class to be used for the PVC. Once set, this field is immutable.
- databaseType
-
Specifies the type of database to use for the datastore. The valid options are
sql,sqlite3,postgres,mysql,aws_postgresql, andaws_mysql. - connectionString
-
Specifies the connection string for the database. For PostgreSQL with SSL, include
sslmodeand certificate paths (for example,dbname=spire user=spire host=postgres.example.com sslmode=verify-full). - tlsSecretName
-
Specifies the name of a Kubernetes Secret containing TLS certificates for database connections. The Secret will be mounted at
/run/spire/db/certs. This field is optional. - maxOpenConns
- Specifies the maximum number of open database connections. Must be between 1 and 10000.
- maxIdleConns
- Specifies the maximum number of idle database connections in the pool. Must be between 0 and 10000.
- connMaxLifetime
- Specifies the maximum lifetime of a database connection in seconds. A value of 0 means connections are not closed due to age.
- disableMigration
-
Specifies whether to disable automatic database migration. The valid options are
trueandfalse. - profile
-
Specifies the bundle endpoint authentication profile for federation. The valid options are
https_spiffeandhttps_web. - refreshHint
- Specifies the hint for bundle refresh interval in seconds. Must be between 60 and 3600.
- federatesWith
-
Specifies the list of trust domains this cluster federates with. Each entry requires
trustDomain,bundleEndpointUrl, andbundleEndpointProfile. - managedRoute
-
Specifies either enabling or disabling automatic route creation for the federation endpoint. Set to
trueto allow automatic exposure through a managed OpenShift Route, orfalseto manually configure routing.
Apply the configuration by running the following command:
oc apply -f SpireServer.yaml
$ oc apply -f SpireServer.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
Verify that the stateful set of SPIRE Server is ready and available by running the following command:
oc get statefulset -l app.kubernetes.io/name=server -n zero-trust-workload-identity-manager
$ oc get statefulset -l app.kubernetes.io/name=server -n zero-trust-workload-identity-managerCopy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
NAME READY AGE spire-server 1/1 65s
NAME READY AGE spire-server 1/1 65sCopy to Clipboard Copied! Toggle word wrap Toggle overflow Verify that the status of the SPIRE Server pod is
Runningby running the following command:oc get po -l app.kubernetes.io/name=server -n zero-trust-workload-identity-manager
$ oc get po -l app.kubernetes.io/name=server -n zero-trust-workload-identity-managerCopy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
NAME READY STATUS RESTARTS AGE spire-server-0 2/2 Running 1 (108s ago) 111s
NAME READY STATUS RESTARTS AGE spire-server-0 2/2 Running 1 (108s ago) 111sCopy to Clipboard Copied! Toggle word wrap Toggle overflow Verify that the persistent volume claim (PVC) is bound, by running the following command:
oc get pvc -l app.kubernetes.io/name=server -n zero-trust-workload-identity-manager
$ oc get pvc -l app.kubernetes.io/name=server -n zero-trust-workload-identity-managerCopy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTECLASS AGE spire-data-spire-server-0 Bound pvc-27a36535-18a1-4fde-ab6d-e7ee7d3c2744 5Gi RW0 gp3-csi <unset> 22m
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTECLASS AGE spire-data-spire-server-0 Bound pvc-27a36535-18a1-4fde-ab6d-e7ee7d3c2744 5Gi RW0 gp3-csi <unset> 22mCopy to Clipboard Copied! Toggle word wrap Toggle overflow
10.5.3. Deploying the SPIRE Agent Copiar enlaceEnlace copiado en el portapapeles!
Use the SpireAgent custom resource to configure the SPIRE Agent DaemonSet on your nodes. This defines how the agent verifies workloads and manages identity attestation across your OpenShift Container Platform cluster.
Prerequisites
-
You have access to the cluster as a user with the
cluster-adminrole. - You have installed Zero Trust Workload Identity Manager in the cluster.
Procedure
Create the
SpireAgentCR:Create a YAML file that defines the
SpireAgentCR, for example,SpireAgent.yaml:Example
SpireAgent.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow where:
- name
- Must be named 'cluster'.
- socketPath
-
Specifies the directory on the host where the SPIRE agent socket is created. This directory is shared with the SPIFFE CSI driver via the
hostPathvolume. Must match theSpiffeCSIDriver.spec.agentSocketPathfor workloads to access the socket. Must be an absolute path with a maximum length of 256 characters. - logLevel
-
Specifies the logging level for the SPIRE Server. The valid options are
debug,info,warn, anderror. - logFormat
-
Specifies the logging format for the SPIRE Server. The valid options are
textandjson. - k8sPSATEnabled
-
Specifies whether Kubernetes Projected Service Account Token (PSAT) node attestation is enabled. When enabled, the SPIRE agent uses K8s PSATs to prove its identity to the SPIRE server during node attestation. The valid options are
trueandfalse. - k8sEnabled
-
Specifies whether the Kubernetes workload attestor is enabled. When enabled, the SPIRE agent can verify workload identities using Kubernetes pod information and service account tokens. The valid options are
trueandfalse. - type
-
Specifies the kubelet certificate verification mode. The valid options are
auto,hostCert, andskip. - hostCertBasePath
-
Specifies the directory containing the kubelet CA certificate. Required when type is
hostCert. Optional when type isauto(defaults to /etc/kubernetes if not specified). - hostCertFileName
-
Specifies the file name for the kubelet’s CA certificate. When combined with
hostCertBasePath, forms the full path. Required when type ishostCert. Optional when type isauto. Defaults tokubelet-ca.crtif not specified. - disableContainerSelectors
-
Specifies whether to disable container selectors in the Kubernetes workload attestor. Set to
trueif usingholdApplicationUntilProxyStartsin Istio. The valid options aretrueandfalse. - useNewContainerLocator
-
Specifies enabling the new container locator algorithm that has support for cgroups v2. The valid options are
trueandfalse.
Apply the configuration by running the following command:
oc apply -f SpireAgent.yaml
$ oc apply -f SpireAgent.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
Verify that the daemon set of the SPIRE Agent is ready and available by running the following command:
oc get daemonset -l app.kubernetes.io/name=agent -n zero-trust-workload-identity-manager
$ oc get daemonset -l app.kubernetes.io/name=agent -n zero-trust-workload-identity-managerCopy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE spire-agent 3 3 3 3 3 <none> 10m
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE spire-agent 3 3 3 3 3 <none> 10mCopy to Clipboard Copied! Toggle word wrap Toggle overflow Verify that the status of SPIRE Agent pods is
Runningby running the following command:oc get po -l app.kubernetes.io/name=agent -n zero-trust-workload-identity-manager
$ oc get po -l app.kubernetes.io/name=agent -n zero-trust-workload-identity-managerCopy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
NAME READY STATUS RESTARTS AGE spire-agent-dp4jb 1/1 Running 0 12m spire-agent-nvwjm 1/1 Running 0 12m spire-agent-vtvlk 1/1 Running 0 12m
NAME READY STATUS RESTARTS AGE spire-agent-dp4jb 1/1 Running 0 12m spire-agent-nvwjm 1/1 Running 0 12m spire-agent-vtvlk 1/1 Running 0 12mCopy to Clipboard Copied! Toggle word wrap Toggle overflow
10.5.4. Deploying the SPIFFE Container Storage Interface driver Copiar enlaceEnlace copiado en el portapapeles!
Configure the Container Storage Interface (CSI) driver using the SpiffeCSIDriver CR. This configuration mounts SPIFFE sockets directly into workload pods, which allows your applications to access the SPIFFE Workload API securely.
Prerequisites
-
You have access to the cluster as a user with the
cluster-adminrole. - You have installed Zero Trust Workload Identity Manager in the cluster.
Procedure
Create the
SpiffeCSIDriverCR:Create a YAML file that defines the
SpiffeCSIDriverCR object, for example,SpiffeCSIDriver.yaml:Example
SpiffeCSIDriver.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow where:
- name
- Specifies that the name must be 'cluster'.
- agentSocketPath
-
Specifies the path to the directory containing the SPIRE agent’s Workload API socket. This directory is bind-mounted into workload containers by the CSI driver. The directory is shared between the SPIRE agent and CSI driver via a
hostPathvolume. Must be an absolute path with a maximum length of 256 characters. This value must matchSpireAgent.spec.socketPathfor workloads to access the socket. - pluginName
-
Specifies the name of the CSI plugin. This sets the CSI driver name that is deployed to the cluster and used in
VolumeMountconfigurations. Must match the driver name referenced in the workload pods. Must be a valid domain name format (for example,csi.spiffe.io) with a maximum length of 127 characters.
Apply the configuration by running the following command:
oc apply -f SpiffeCSIDriver.yaml
$ oc apply -f SpiffeCSIDriver.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
Verify that the daemon set of the SPIFFE CSI driver is ready and available by running the following command:
oc get daemonset -l app.kubernetes.io/name=spiffe-csi-driver -n zero-trust-workload-identity-manager
$ oc get daemonset -l app.kubernetes.io/name=spiffe-csi-driver -n zero-trust-workload-identity-managerCopy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE spire-spiffe-csi-driver 3 3 3 3 3 <none> 114s
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE spire-spiffe-csi-driver 3 3 3 3 3 <none> 114sCopy to Clipboard Copied! Toggle word wrap Toggle overflow Verify that the status of SPIFFE Container Storage Interface (CSI) Driver pods is
Runningby running the following command:oc get po -l app.kubernetes.io/name=spiffe-csi-driver -n zero-trust-workload-identity-manager
$ oc get po -l app.kubernetes.io/name=spiffe-csi-driver -n zero-trust-workload-identity-managerCopy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
NAME READY STATUS RESTARTS AGE spire-spiffe-csi-driver-gpwcp 2/2 Running 0 2m37s spire-spiffe-csi-driver-rrbrd 2/2 Running 0 2m37s spire-spiffe-csi-driver-w6s6q 2/2 Running 0 2m37s
NAME READY STATUS RESTARTS AGE spire-spiffe-csi-driver-gpwcp 2/2 Running 0 2m37s spire-spiffe-csi-driver-rrbrd 2/2 Running 0 2m37s spire-spiffe-csi-driver-w6s6q 2/2 Running 0 2m37sCopy to Clipboard Copied! Toggle word wrap Toggle overflow
10.5.5. Deploying the SPIRE OpenID Connect Discovery Provider Copiar enlaceEnlace copiado en el portapapeles!
Deploy the SPIRE OpenID Connect (OIDC) Discovery Provider by configuring the SpireOIDCDiscoveryProvider CR. This allows you to define the trust domain and JSON web token (JWT) issuer for your cluster.
Prerequisites
-
You have access to the cluster as a user with the
cluster-adminrole. - You have installed Zero Trust Workload Identity Manager in the cluster.
Procedure
Create the
SpireOIDCDiscoveryProviderCR:Create a YAML file that defines the
SpireOIDCDiscoveryProviderCR, for example,SpireOIDCDiscoveryProvider.yaml:Example
SpireOIDCDiscoveryProvider.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow where:
- name
- Specifies that the value must be 'cluster'.
- logLevel
-
Specifies the logging level for the SPIRE Server. The valid options are
debug,info,warn, anderror. - logFormat
-
Specifies the logging format for the SPIRE Server. The valid options are
textandjson. - csiDriverName
-
Specifies the name of the CSI driver to use for mounting the Workload API socket. This must match the
SpiffeCSIDriver.spec.pluginNamevalue for the OIDC provider to access SPIFFE identities. Must be a valid DNS subdomain format (for example,csi.spiffe.io) with a maximum length of 127 characters. - jwtIssuer
-
Specifies the JWT issuer URL. Must be a valid HTTPS or HTTP URL with a maximum length of 512 characters. This value must match the
SpireServer.spec.jwtIssuervalue. - replicaCount
- Specifies the number of replicas for the OIDC Discovery Provider deployment. Must be between 1 and 5.
- managedRoute
-
Specifies whether the Operator automatically creates an OpenShift route for the OIDC Discovery Provider endpoints. Set to
trueto have the Operator automatically create and maintain an OpenShift route for OIDC discovery endpoints (*.apps.). Set tofalsefor administrators to manually configure routes or ingress. - externalSecretRef
- Specifies a reference to an externally managed secret that contains the TLS certificate for the OIDC Discovery Provider route host. Must be a valid Kubernetes secret reference name with a maximum length of 253 characters. This field is optional.
Apply the configuration by running the following command:
oc apply -f SpireOIDCDiscoveryProvider.yaml
$ oc apply -f SpireOIDCDiscoveryProvider.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
Verify that the deployment of OIDC Discovery Provider is ready and available by running the following command:
oc get deployment -l app.kubernetes.io/name=spiffe-oidc-discovery-provider -n zero-trust-workload-identity-manager
$ oc get deployment -l app.kubernetes.io/name=spiffe-oidc-discovery-provider -n zero-trust-workload-identity-managerCopy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
NAME READY UP-TO-DATE AVAILABLE AGE spire-spiffe-oidc-discovery-provider 1/1 1 1 2m58s
NAME READY UP-TO-DATE AVAILABLE AGE spire-spiffe-oidc-discovery-provider 1/1 1 1 2m58sCopy to Clipboard Copied! Toggle word wrap Toggle overflow Verify that the status of OIDC Discovery Provider pods is
Runningby running the following command:oc get po -l app.kubernetes.io/name=spiffe-oidc-discovery-provider -n zero-trust-workload-identity-manager
$ oc get po -l app.kubernetes.io/name=spiffe-oidc-discovery-provider -n zero-trust-workload-identity-managerCopy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
NAME READY STATUS RESTARTS AGE spire-spiffe-oidc-discovery-provider-64586d599f-lcc94 2/2 Running 0 7m15s
NAME READY STATUS RESTARTS AGE spire-spiffe-oidc-discovery-provider-64586d599f-lcc94 2/2 Running 0 7m15sCopy to Clipboard Copied! Toggle word wrap Toggle overflow
10.5.6. Verify the health of the operands Copiar enlaceEnlace copiado en el portapapeles!
View the status fields to verify the operational health of managed components. This information helps you confirm that the SPIRE Server, SPIRE Agent, SPIFFE CSI driver, and the SPIRE OIDC discovery provider operands are ready and functioning correctly.
To verify the operands, run the following command:
oc get ZeroTrustWorkloadIdentityManager cluster -o yaml
oc get ZeroTrustWorkloadIdentityManager cluster -o yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
This status is reflected when all operands are healthy and stable.
The Operator adds the owner reference for the ZeroTrustWorkloadIdentityManager CR on the other operands' CRs. This causes the operands' resources to be deleted once the ZeroTrustWorkloadIdentityManager CRs are deleted.
10.6. Configuring the egress proxy for the Zero Trust Workload Identity Manager Copiar enlaceEnlace copiado en el portapapeles!
Operator Lifecycle Manager (OLM) automatically configures managed Operators with proxy settings when you use a cluster-wide egress proxy. To support proxying HTTPS connections, you can inject certificate authority (CA) certificates into the Zero Trust Workload Identity Manager.
10.6.1. Injecting a custom CA certificate for the Zero Trust Workload Identity Manager Copiar enlaceEnlace copiado en el portapapeles!
Inject certificate authority (CA) certificates into the Zero Trust Workload Identity Manager to support proxying HTTPS connections. This configuration helps ensure that the Identity Manager can communicate securely when you enable a cluster-wide proxy.
Prerequisites
-
You have access to the cluster as a user with the
cluster-adminrole. - You have enabled the cluster-wide proxy for OpenShift Container Platform.
- You have installed Zero Trust Workload Identity Manager 1.0.0 or later.
- You have deployed the SPIRE Server, SPIRE Agent, SPIFFEE CSI Driver, and the SPIRE OIDC Discovery Provider operands in the cluster.
Procedure
Create a config map in the
zero-trust-workload-identity-managernamespace by running the following command:oc create configmap trusted-ca -n zero-trust-workload-identity-manager
$ oc create configmap trusted-ca -n zero-trust-workload-identity-managerCopy to Clipboard Copied! Toggle word wrap Toggle overflow Inject the CA bundle that is trusted by OpenShift Container Platform into the config map by running the following command:
oc label cm trusted-ca config.openshift.io/inject-trusted-cabundle=true -n zero-trust-workload-identity-manager
$ oc label cm trusted-ca config.openshift.io/inject-trusted-cabundle=true -n zero-trust-workload-identity-managerCopy to Clipboard Copied! Toggle word wrap Toggle overflow Update the subscription for the Zero Trust Workload Identity Manager to use the config map by running the following command:
oc -n zero-trust-workload-identity-manager patch subscription openshift-zero-trust-workload-identity-manager --type='merge' -p '{"spec":{"config":{"env":[{"name":"TRUSTED_CA_BUNDLE_CONFIGMAP","value":"trusted-ca"}]}}}'$ oc -n zero-trust-workload-identity-manager patch subscription openshift-zero-trust-workload-identity-manager --type='merge' -p '{"spec":{"config":{"env":[{"name":"TRUSTED_CA_BUNDLE_CONFIGMAP","value":"trusted-ca"}]}}}'Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
Verify that the operands have finished rolling out by running the following command:
oc rollout status deployment/zero-trust-workload-identity-manager-controller-manager -n zero-trust-workload-identity-manager && \ $ oc rollout status statefulset/spireserver -n zero-trust-workload-identity-manager && \ $ oc rollout status daemonset/spire-agent -n zero-trust-workload-identity-manager && \ $ oc rollout status deployment/spire-spiffe-oidc-discovery-provider -n zero-trust-workload-identity-manager
$ oc rollout status deployment/zero-trust-workload-identity-manager-controller-manager -n zero-trust-workload-identity-manager && \ $ oc rollout status statefulset/spireserver -n zero-trust-workload-identity-manager && \ $ oc rollout status daemonset/spire-agent -n zero-trust-workload-identity-manager && \ $ oc rollout status deployment/spire-spiffe-oidc-discovery-provider -n zero-trust-workload-identity-managerCopy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
deployment "zero-trust-workload-identity-manager-controller-manager" successfully rolled out statefulset "spire-server" successfully rolled out daemonset "spire-agent" successfully rolled out deployment "spire-spiffe-oidc-discovery-provider" successfully rolled out
deployment "zero-trust-workload-identity-manager-controller-manager" successfully rolled out statefulset "spire-server" successfully rolled out daemonset "spire-agent" successfully rolled out deployment "spire-spiffe-oidc-discovery-provider" successfully rolled outCopy to Clipboard Copied! Toggle word wrap Toggle overflow Verify that the CA bundle was mounted as a volume by running the following command:
oc get deployment zero-trust-workload-identity-manager -n zero-trust-workload-identity-manager -o=jsonpath={.spec.template.spec.'containers[0].volumeMounts'}$ oc get deployment zero-trust-workload-identity-manager -n zero-trust-workload-identity-manager -o=jsonpath={.spec.template.spec.'containers[0].volumeMounts'}Copy to Clipboard Copied! Toggle word wrap Toggle overflow oc get statefulset spire-server -n zero-trust-workload-identity-manager -o jsonpath='{.spec.template.spec.containers[*].volumeMounts[?(@.name=="trusted-ca-bundle")]}'$ oc get statefulset spire-server -n zero-trust-workload-identity-manager -o jsonpath='{.spec.template.spec.containers[*].volumeMounts[?(@.name=="trusted-ca-bundle")]}'Copy to Clipboard Copied! Toggle word wrap Toggle overflow oc get daemonset spire-agent -n zero-trust-workload-identity-manager -o jsonpath='{.spec.template.spec.containers[*].volumeMounts[?(@.name=="trusted-ca-bundle")]}'$ oc get daemonset spire-agent -n zero-trust-workload-identity-manager -o jsonpath='{.spec.template.spec.containers[*].volumeMounts[?(@.name=="trusted-ca-bundle")]}'Copy to Clipboard Copied! Toggle word wrap Toggle overflow oc get daemonset spire-spiffe-csi-driver -n zero-trust-workload-identity-manager -o jsonpath='{.spec.template.spec.containers[*].volumeMounts[?(@.name=="trusted-ca-bundle")]}'$ oc get daemonset spire-spiffe-csi-driver -n zero-trust-workload-identity-manager -o jsonpath='{.spec.template.spec.containers[*].volumeMounts[?(@.name=="trusted-ca-bundle")]}'Copy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
[{{"mountPath":"/etc/pki/ca-trust/extracted/pem","name":"trusted-ca-bundle","readOnly":true}][{{"mountPath":"/etc/pki/ca-trust/extracted/pem","name":"trusted-ca-bundle","readOnly":true}]Copy to Clipboard Copied! Toggle word wrap Toggle overflow Verify that the source of the CA bundle is the
trusted-caconfig map by running the following command:oc get deployment zero-trust-workload-identity-manager -n zero-trust-workload-identity-manager -o=jsonpath={.spec.template.spec.volumes}$ oc get deployment zero-trust-workload-identity-manager -n zero-trust-workload-identity-manager -o=jsonpath={.spec.template.spec.volumes}Copy to Clipboard Copied! Toggle word wrap Toggle overflow oc get statefulset spire-server -n zero-trust-workload-identity-manager -o=jsonpath='{.spec.template.spec.volumes}' | jq '.[] | select(.name=="trusted-ca-bundle")'$ oc get statefulset spire-server -n zero-trust-workload-identity-manager -o=jsonpath='{.spec.template.spec.volumes}' | jq '.[] | select(.name=="trusted-ca-bundle")'Copy to Clipboard Copied! Toggle word wrap Toggle overflow oc get daemonset spire-agent -n zero-trust-workload-identity-manager -o=jsonpath='{.spec.template.spec.volumes}' | jq '.[] | select(.name=="trusted-ca-bundle")'$ oc get daemonset spire-agent -n zero-trust-workload-identity-manager -o=jsonpath='{.spec.template.spec.volumes}' | jq '.[] | select(.name=="trusted-ca-bundle")'Copy to Clipboard Copied! Toggle word wrap Toggle overflow oc get deployment spire-spiffe-oidc-discovery-provider -n zero-trust-workload-identity-manager -o=jsonpath='{.spec.template.spec.volumes}' | jq '.[] | select(.name=="trusted-ca-bundle")'$ oc get deployment spire-spiffe-oidc-discovery-provider -n zero-trust-workload-identity-manager -o=jsonpath='{.spec.template.spec.volumes}' | jq '.[] | select(.name=="trusted-ca-bundle")'Copy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
10.7. Zero Trust Workload Identity Manager OIDC federation Copiar enlaceEnlace copiado en el portapapeles!
Zero Trust Workload Identity Manager integrates with OpenID Connect (OIDC) by allowing a SPIRE server to act as an OIDC provider. This enables workloads to request and receive verifiable JSON Web Tokens - SPIFFE Verifiable Identity Documents (JWT-SVIDs) from the local SPIRE agent. External systems, such as cloud providers, can then use the OIDC discovery endpoint exposed by the SPIRE server to retrieve public keys.
The following providers are verified to work with SPIRE OIDC federation:
- Azure Entra ID
- Vault
10.7.1. About the Entra ID OpenID Connect Copiar enlaceEnlace copiado en el portapapeles!
Entra ID is a cloud-based identity and access management service that centralizes user management and access control. Entra ID serves as the identify provider, verifying user identities and issuing and ID token to the application. This token has essential user information, allowing the application to confirm who the user is without managing their credentials.
Integrating Entra ID OpenID Connect (OIDC) with SPIRE provides workloads with automatic, short-lived cryptographic identities. The SPIRE-issued identities are sent to Entra ID to securely authenticate the service without any static secrets.
10.7.1.1. Configuring the external certificate for the managed OIDC discovery provider route Copiar enlaceEnlace copiado en el portapapeles!
The managed route uses the External Route Certificate feature to set the tls.externalCertificate field to an externally managed Transfer Layer Security (TLS) secret’s name.
Prerequisites
- You have installed Zero Trust Workload Identity Manager 0.2.0 or later.
- You have deployed the SPIRE Server, SPIRE Agent, SPIFFEE CSI Driver, and the SPIRE OIDC Discovery Provider operands in the cluster.
- You have installed the cert-manager Operator for Red Hat OpenShift. For more information, Installing the cert-manager Operator for Red Hat OpenShift.
-
You have created a
ClusterIssuerorIssuerconfigured with a publicly trusted CA service. For example, an Automated Certificate Management Environment (ACME) typeIssuerwith the "Let’s Encrypt ACME" service. For more information, see Configuring an ACME issuer
Procedure
Create a
Roleto provide the router service account permissions to read the referenced secret by running the following command:oc create role secret-reader \ --verb=get,list,watch \ --resource=secrets \ --resource-name=$TLS_SECRET_NAME \ -n zero-trust-workload-identity-manager
$ oc create role secret-reader \ --verb=get,list,watch \ --resource=secrets \ --resource-name=$TLS_SECRET_NAME \ -n zero-trust-workload-identity-managerCopy to Clipboard Copied! Toggle word wrap Toggle overflow Create a
RoleBindingresource to bind the router service account with the newly created Role resource by running the following command:oc create rolebinding secret-reader-binding \ --role=secret-reader \ --serviceaccount=openshift-ingress:router \ -n zero-trust-workload-identity-manager
$ oc create rolebinding secret-reader-binding \ --role=secret-reader \ --serviceaccount=openshift-ingress:router \ -n zero-trust-workload-identity-managerCopy to Clipboard Copied! Toggle word wrap Toggle overflow Configure the
SpireOIDCDIscoveryProviderCustom Resource (CR) object to reference the Secret generated in the earlier step by running the following command:oc patch SpireOIDCDiscoveryProvider cluster --type=merge -p=' spec: externalSecretRef: ${TLS_SECRET_NAME} '$ oc patch SpireOIDCDiscoveryProvider cluster --type=merge -p=' spec: externalSecretRef: ${TLS_SECRET_NAME} 'Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
In the
SpireOIDCDiscoveryProviderCR, check if theManageRouteReadycondition is set toTrueby running the following command:oc wait --for=jsonpath='{.status.conditions[?(@.type=="ManagedRouteReady")].status}'=True SpireOIDCDiscoveryProvider/cluster --timeout=120s$ oc wait --for=jsonpath='{.status.conditions[?(@.type=="ManagedRouteReady")].status}'=True SpireOIDCDiscoveryProvider/cluster --timeout=120sCopy to Clipboard Copied! Toggle word wrap Toggle overflow Verify that the OIDC endpoint can be accessed securely through HTTPS by running the following command:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
10.7.1.2. Disabling a managed route Copiar enlaceEnlace copiado en el portapapeles!
If you want to fully control the behavior of exposing the OIDC Discovery Provider service, you can disable the managed Route based on your requirements.
Procedure
To manually configure the OIDC Discovery Provider, set
managedRoutetofalseby running the following command:oc patch SpireOIDCDiscoveryProvider cluster --type=merge -p=' spec: managedRoute: "false"
$ oc patch SpireOIDCDiscoveryProvider cluster --type=merge -p=' spec: managedRoute: "false"Copy to Clipboard Copied! Toggle word wrap Toggle overflow
10.7.1.3. Using Entra ID with Microsoft Azure Copiar enlaceEnlace copiado en el portapapeles!
After the Entra ID configuration is complete, you can set up Entra ID to work with Azure.
Prerequisites
- You have configured the SPIRE OIDC Discovery Provider Route to serve the TLS certificates from a publicly trusted CA.
Procedure
Log in to Azure by running the following command:
az login
$ az loginCopy to Clipboard Copied! Toggle word wrap Toggle overflow Configure variables for your Azure subscription and tenant by running the following commands:
export SUBSCRIPTION_ID=$(az account list --query "[?isDefault].id" -o tsv)
$ export SUBSCRIPTION_ID=$(az account list --query "[?isDefault].id" -o tsv)1 Copy to Clipboard Copied! Toggle word wrap Toggle overflow export TENANT_ID=$(az account list --query "[?isDefault].tenantId" -o tsv)
$ export TENANT_ID=$(az account list --query "[?isDefault].tenantId" -o tsv)1 Copy to Clipboard Copied! Toggle word wrap Toggle overflow export LOCATION=centralus
$ export LOCATION=centralus1 Copy to Clipboard Copied! Toggle word wrap Toggle overflow Define resource variable names by running the following commands:
export NAME=ztwim
$ export NAME=ztwim1 Copy to Clipboard Copied! Toggle word wrap Toggle overflow export RESOURCE_GROUP="${NAME}-rg"$ export RESOURCE_GROUP="${NAME}-rg"1 Copy to Clipboard Copied! Toggle word wrap Toggle overflow export STORAGE_ACCOUNT="${NAME}storage"$ export STORAGE_ACCOUNT="${NAME}storage"1 Copy to Clipboard Copied! Toggle word wrap Toggle overflow export STORAGE_CONTAINER="${NAME}storagecontainer"$ export STORAGE_CONTAINER="${NAME}storagecontainer"1 Copy to Clipboard Copied! Toggle word wrap Toggle overflow export USER_ASSIGNED_IDENTITY_NAME="${NAME}-identity"$ export USER_ASSIGNED_IDENTITY_NAME="${NAME}-identity"1 Copy to Clipboard Copied! Toggle word wrap Toggle overflow Create the resource group by running the following command:
az group create \ --name "${RESOURCE_GROUP}" \ --location "${LOCATION}"$ az group create \ --name "${RESOURCE_GROUP}" \ --location "${LOCATION}"Copy to Clipboard Copied! Toggle word wrap Toggle overflow
10.7.1.4. Configuring Azure blob storage Copiar enlaceEnlace copiado en el portapapeles!
You need to create a new storage account to be used to store content.
Procedure
Create a new storage account that is used to store content by running the following command:
az storage account create \ --name ${STORAGE_ACCOUNT} \ --resource-group ${RESOURCE_GROUP} \ --location ${LOCATION} \ --encryption-services blob$ az storage account create \ --name ${STORAGE_ACCOUNT} \ --resource-group ${RESOURCE_GROUP} \ --location ${LOCATION} \ --encryption-services blobCopy to Clipboard Copied! Toggle word wrap Toggle overflow Obtain the storage ID for the newly created storage account by running the following command:
export STORAGE_ACCOUNT_ID=$(az storage account show -n ${STORAGE_ACCOUNT} -g ${RESOURCE_GROUP} --query id --out tsv)$ export STORAGE_ACCOUNT_ID=$(az storage account show -n ${STORAGE_ACCOUNT} -g ${RESOURCE_GROUP} --query id --out tsv)Copy to Clipboard Copied! Toggle word wrap Toggle overflow Create a storage container inside the newly created storage account to provide a location to support the storage of blobs by running the following command:
az storage container create \ --account-name ${STORAGE_ACCOUNT} \ --name ${STORAGE_CONTAINER} \ --auth-mode login$ az storage container create \ --account-name ${STORAGE_ACCOUNT} \ --name ${STORAGE_CONTAINER} \ --auth-mode loginCopy to Clipboard Copied! Toggle word wrap Toggle overflow
10.7.1.5. Configuring an Azure user managed identity Copiar enlaceEnlace copiado en el portapapeles!
You need to Create a new User Managed Identity and then obtain the Client ID of the related Service Principal associated with the User Managed Identity.
Procedure
Create a new User Managed Identity and then obtain the Client ID of the related Service Principal associated with the User Managed Identity by running the following command:
az identity create \ --name ${USER_ASSIGNED_IDENTITY_NAME} \ --resource-group ${RESOURCE_GROUP}$ az identity create \ --name ${USER_ASSIGNED_IDENTITY_NAME} \ --resource-group ${RESOURCE_GROUP}Copy to Clipboard Copied! Toggle word wrap Toggle overflow export IDENTITY_CLIENT_ID=$(az identity show --resource-group "${RESOURCE_GROUP}" --name "${USER_ASSIGNED_IDENTITY_NAME}" --query 'clientId' -otsv)$ export IDENTITY_CLIENT_ID=$(az identity show --resource-group "${RESOURCE_GROUP}" --name "${USER_ASSIGNED_IDENTITY_NAME}" --query 'clientId' -otsv)Copy to Clipboard Copied! Toggle word wrap Toggle overflow Retrieve the
CLIENT_IDof an Azure user-assigned managed identity and save it as an environment variable by running the following command:export IDENTITY_CLIENT_ID=$(az identity show --resource-group "${RESOURCE_GROUP}" --name "${USER_ASSIGNED_IDENTITY_NAME}" --query 'clientId' -otsv)$ export IDENTITY_CLIENT_ID=$(az identity show --resource-group "${RESOURCE_GROUP}" --name "${USER_ASSIGNED_IDENTITY_NAME}" --query 'clientId' -otsv)Copy to Clipboard Copied! Toggle word wrap Toggle overflow Associate a role with the Service Principal associated with the User Managed Identity by running the following command:
az role assignment create \ --role "Storage Blob Data Contributor" \ --assignee "${IDENTITY_CLIENT_ID}" \ --scope ${STORAGE_ACCOUNT_ID}$ az role assignment create \ --role "Storage Blob Data Contributor" \ --assignee "${IDENTITY_CLIENT_ID}" \ --scope ${STORAGE_ACCOUNT_ID}Copy to Clipboard Copied! Toggle word wrap Toggle overflow
10.7.1.6. Creating the demonstration application Copiar enlaceEnlace copiado en el portapapeles!
The demonstration application provides you a way to see if the entire system works.
Procedure
To create the demonstration application, complete the following steps:
Set the application name and namespace by running the following commands:
export APP_NAME=workload-app
$ export APP_NAME=workload-appCopy to Clipboard Copied! Toggle word wrap Toggle overflow export APP_NAMESPACE=demo
$ export APP_NAMESPACE=demoCopy to Clipboard Copied! Toggle word wrap Toggle overflow Create the namespace by running the following command:
oc create namespace $APP_NAMESPACE
$ oc create namespace $APP_NAMESPACECopy to Clipboard Copied! Toggle word wrap Toggle overflow Create the application Secret by running the following command:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
10.7.1.7. Deploying the workload application Copiar enlaceEnlace copiado en el portapapeles!
Once the demonstration application has been created.
Prerequisites
- The demonstration application has been created and deployed.
Procedure
To deploy the application, copy the entire command block provided and paste it directly into your terminal. Press Enter.
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
Ensure that the
workload-apppod is running successfully by running the following command:oc get pods -n $APP_NAMESPACE
$ oc get pods -n $APP_NAMESPACECopy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
NAME READY STATUS RESTARTS AGE workload-app-5f8b9d685b-abcde 1/1 Running 0 60s
NAME READY STATUS RESTARTS AGE workload-app-5f8b9d685b-abcde 1/1 Running 0 60sCopy to Clipboard Copied! Toggle word wrap Toggle overflow Retrieve the SPIFFE JWT Token (SVID-JWT):
Get the pod name dynamically by running the following command:
POD_NAME=$(oc get pods -n $APP_NAMESPACE -l app=$APP_NAME -o jsonpath='{.items[0].metadata.name}')$ POD_NAME=$(oc get pods -n $APP_NAMESPACE -l app=$APP_NAME -o jsonpath='{.items[0].metadata.name}')Copy to Clipboard Copied! Toggle word wrap Toggle overflow Run the script inside the pod by running the following command:
oc exec -it $POD_NAME -n $APP_NAMESPACE -- \ /opt/app-root/src/get-spiffe-token.py -a "api://AzureADTokenExchange"
$ oc exec -it $POD_NAME -n $APP_NAMESPACE -- \ /opt/app-root/src/get-spiffe-token.py -a "api://AzureADTokenExchange"Copy to Clipboard Copied! Toggle word wrap Toggle overflow
10.7.1.8. Configuring Azure with the SPIFFE identity federation Copiar enlaceEnlace copiado en el portapapeles!
You can configure Azure with the SPIFFE identity federation to enable password-free and automated authentication to the demonstration application.
Procedure
Federate the identities between the User Managed Identity and the SPIFFE identity associated with the workload application by running the following command:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
10.7.1.9. Verifying that the application workload can access the content in the Azure Blob Storage Copiar enlaceEnlace copiado en el portapapeles!
You can check if the application workload can access the Azure Blob Storage.
Prerequisites
- An Azure Blob Storage has been created.
Procedure
Retrieve a JWT token from the SPIFFE Workload API by running the following command:
oc rsh -n $APP_NAMESPACE deployment/$APP_NAME
$ oc rsh -n $APP_NAMESPACE deployment/$APP_NAMECopy to Clipboard Copied! Toggle word wrap Toggle overflow Create and export an environment variable named
TOKENby running the following command:export TOKEN=$(/opt/app-root/src/get-spiffe-token.py --audience=$AZURE_AUDIENCE)
$ export TOKEN=$(/opt/app-root/src/get-spiffe-token.py --audience=$AZURE_AUDIENCE)Copy to Clipboard Copied! Toggle word wrap Toggle overflow Log in to Azure CLI included within the pod by running the following command:
az login --service-principal \ -t ${AZURE_TENANT_ID} \ -u ${AZURE_CLIENT_ID} \ --federated-token ${TOKEN}$ az login --service-principal \ -t ${AZURE_TENANT_ID} \ -u ${AZURE_CLIENT_ID} \ --federated-token ${TOKEN}Copy to Clipboard Copied! Toggle word wrap Toggle overflow Create a new file with the application workload pod and upload the file to the Blob Storage by running the following command:
echo “Hello from OpenShift” > openshift-spire-federated-identities.txt
$ echo “Hello from OpenShift” > openshift-spire-federated-identities.txtCopy to Clipboard Copied! Toggle word wrap Toggle overflow Upload a file to the Azure Blog Storage by running the following command:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
Confirm the file uploaded successfully by listing the files contained by running the following command:
az storage blob list \ --account-name ${BLOB_STORE_ACCOUNT} \ --container-name ${BLOB_STORE_CONTAINER} \ --auth-mode login \ -o table$ az storage blob list \ --account-name ${BLOB_STORE_ACCOUNT} \ --container-name ${BLOB_STORE_CONTAINER} \ --auth-mode login \ -o tableCopy to Clipboard Copied! Toggle word wrap Toggle overflow
10.7.2. About Vault OpenID Connect Copiar enlaceEnlace copiado en el portapapeles!
Vault OpenID Connect (OIDC) with SPIRE creates a secure authentication method where Vault uses SPIRE as a trusted OIDC provider. A workload requests a JWT-SVID from its local SPIRE Agent, which has a unique SPIFFE ID. The workload then presents this token to Vault, and Vault validates it against the public keys on the SPIRE Server. If all conditions are met, Vault issues a short-lived Vault token to the workload which the workload can now use to access secrets and perform actions within Vault.
10.7.2.1. Installing Vault Copiar enlaceEnlace copiado en el portapapeles!
Before Vault is used as an OIDC, you need to install Vault.
Prerequisites
- Configure a route. For more information, see Route configuration
- Helm is installed.
- A command-line JSON processor for easily reading the output from the Vault API.
- A HashiCorp Helm repository is added.
Procedure
Create the
vault-helm-value.yamlfile.Copy to Clipboard Copied! Toggle word wrap Toggle overflow Run the
helm installcommand:helm install vault hashicorp/vault \ --create-namespace -n vault \ --values ./vault-helm-value.yaml
$ helm install vault hashicorp/vault \ --create-namespace -n vault \ --values ./vault-helm-value.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow Expose the Vault service by running the following command:
oc expose service vault -n vault
$ oc expose service vault -n vaultCopy to Clipboard Copied! Toggle word wrap Toggle overflow Set the
VAULT_ADDRenvironment variable to retrieve the hostname from the new route and then export it by running the following command:export VAULT_ADDR="http://$(oc get route vault -n vault -o jsonpath='{.spec.host}')"$ export VAULT_ADDR="http://$(oc get route vault -n vault -o jsonpath='{.spec.host}')"Copy to Clipboard Copied! Toggle word wrap Toggle overflow Notehttp://is prepended because TLS is disabled.
Verification
To ensure your Vault instance is running, run the following command:
curl -s $VAULT_ADDR/v1/sys/health | jq
$ curl -s $VAULT_ADDR/v1/sys/health | jqCopy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
10.7.2.2. Initializing and unsealing Vault Copiar enlaceEnlace copiado en el portapapeles!
A newly installed Vault is sealed. This means that the primary encryption key, which protects all other encryption keys, is not loaded into the server memory upon startup. You need to initialize Vault to unseal it.
The steps to initialize a Vault server are:
- Initialize and unseal Vault
- Enable the key-value (KV) secrets engine and store a test secret
- Configure JSON Web Token (JWT) authentication with SPIRE
- Deploy a demonstration application
- Authenticate and retrieve the secret
Prerequisites
- Ensure that Vault is running.
- Ensure that Vault is not initialized. You can only initialize a Vault server once.
Procedure
Open a remote shell into the
vaultpod by running the following command:oc rsh -n vault statefulset/vault
$ oc rsh -n vault statefulset/vaultCopy to Clipboard Copied! Toggle word wrap Toggle overflow Initialize Vault to get your unseal key and root token by running the following command:
vault operator init -key-shares=1 -key-threshold=1 -format=json
$ vault operator init -key-shares=1 -key-threshold=1 -format=jsonCopy to Clipboard Copied! Toggle word wrap Toggle overflow Export the unseal key and root token you received from the earlier command by running the following commands:
export UNSEAL_KEY=<Your-Unseal-Key>
$ export UNSEAL_KEY=<Your-Unseal-Key>Copy to Clipboard Copied! Toggle word wrap Toggle overflow export ROOT_TOKEN=<Your-Root-Token>
$ export ROOT_TOKEN=<Your-Root-Token>Copy to Clipboard Copied! Toggle word wrap Toggle overflow Unseal Vault using your unseal key by running the following command:
vault operator unseal -format=json $UNSEAL_KEY
$ vault operator unseal -format=json $UNSEAL_KEYCopy to Clipboard Copied! Toggle word wrap Toggle overflow -
Exit the pod by entering
exit.
Verification
To verify that the Vault pod is ready, run the following command:
oc get pod -n vault
$ oc get pod -n vaultCopy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
NAME READY STATUS RESTARTS AGE vault-0 1/1 Running 0 65d
NAME READY STATUS RESTARTS AGE vault-0 1/1 Running 0 65dCopy to Clipboard Copied! Toggle word wrap Toggle overflow
10.7.2.3. Enabling the key-value secrets engine and store a test secret Copiar enlaceEnlace copiado en el portapapeles!
You enable the key-value secrets engine to establish a secure, centralized location for managing credentials.
Prerequisites
- Make sure that Vault is initialized and unsealed.
Procedure
Open another shell session in the
Vaultpod by running the following command:oc rsh -n vault statefulset/vault
$ oc rsh -n vault statefulset/vaultCopy to Clipboard Copied! Toggle word wrap Toggle overflow Export your root token again within this new session and log in by running the following command:
export ROOT_TOKEN=<Your-Root-Token>
$ export ROOT_TOKEN=<Your-Root-Token>Copy to Clipboard Copied! Toggle word wrap Toggle overflow vault login "${ROOT_TOKEN}"$ vault login "${ROOT_TOKEN}"Copy to Clipboard Copied! Toggle word wrap Toggle overflow Enable the KV secrets engine at the
secret/path and create a test secret by running the following commands:export NAME=ztwim
$ export NAME=ztwimCopy to Clipboard Copied! Toggle word wrap Toggle overflow vault secrets enable -path=secret kv
$ vault secrets enable -path=secret kvCopy to Clipboard Copied! Toggle word wrap Toggle overflow vault kv put secret/$NAME version=v0.1.0
$ vault kv put secret/$NAME version=v0.1.0Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
To verify that the secret is stored correctly, run the following command:
vault kv get secret/$NAME
$ vault kv get secret/$NAMECopy to Clipboard Copied! Toggle word wrap Toggle overflow
10.7.2.4. Configuring JSON Web Token authentication with SPIRE Copiar enlaceEnlace copiado en el portapapeles!
You need to set up JSON Web Token (JWT) authentication so your applications can securely log in to Vault by using SPIFFE identities.
Prerequisites
- Make sure that Vault is initialized and unsealed.
- Ensure that a test secret is stored in the key-value secrets engine.
Procedure
On your local machine, retrieve the SPIRE Certificate Authority (CA) bundle and save it to a file by running the following command:
oc get cm -n zero-trust-workload-identity-manager spire-bundle -o jsonpath='{ .data.bundle\.crt }' > oidc_provider_ca.pem$ oc get cm -n zero-trust-workload-identity-manager spire-bundle -o jsonpath='{ .data.bundle\.crt }' > oidc_provider_ca.pemCopy to Clipboard Copied! Toggle word wrap Toggle overflow Back in the Vault pod shell, create a temporary file and paste the contents of
oidc_provider_ca.peminto it by running the following command:cat << EOF > /tmp/oidc_provider_ca.pem -----BEGIN CERTIFICATE----- <Paste-Your-Certificate-Content-Here> -----END CERTIFICATE----- EOF
$ cat << EOF > /tmp/oidc_provider_ca.pem -----BEGIN CERTIFICATE----- <Paste-Your-Certificate-Content-Here> -----END CERTIFICATE----- EOFCopy to Clipboard Copied! Toggle word wrap Toggle overflow Set up the necessary environment variables for the JWT configuration by running the following commands:
export APP_DOMAIN=<Your-App-Domain>
$ export APP_DOMAIN=<Your-App-Domain>Copy to Clipboard Copied! Toggle word wrap Toggle overflow export JWT_ISSUER_ENDPOINT="oidc-discovery.$APP_DOMAIN"
$ export JWT_ISSUER_ENDPOINT="oidc-discovery.$APP_DOMAIN"Copy to Clipboard Copied! Toggle word wrap Toggle overflow export OIDC_URL="https://$JWT_ISSUER_ENDPOINT"
$ export OIDC_URL="https://$JWT_ISSUER_ENDPOINT"Copy to Clipboard Copied! Toggle word wrap Toggle overflow export OIDC_CA_PEM="$(cat /tmp/oidc_provider_ca.pem)"
$ export OIDC_CA_PEM="$(cat /tmp/oidc_provider_ca.pem)"Copy to Clipboard Copied! Toggle word wrap Toggle overflow Crate a new environment variable by running the following command:
export ROLE="${NAME}-role"$ export ROLE="${NAME}-role"Copy to Clipboard Copied! Toggle word wrap Toggle overflow Enable the JWT authentication method by running the following command:
vault auth enable jwt
$ vault auth enable jwtCopy to Clipboard Copied! Toggle word wrap Toggle overflow Configure you ODIC authentication method by running the following command:
vault write auth/jwt/config \ oidc_discovery_url=$OIDC_URL \ oidc_discovery_ca_pem="$OIDC_CA_PEM" \ default_role=$ROLE
$ vault write auth/jwt/config \ oidc_discovery_url=$OIDC_URL \ oidc_discovery_ca_pem="$OIDC_CA_PEM" \ default_role=$ROLECopy to Clipboard Copied! Toggle word wrap Toggle overflow Create a policy named
ztwim-policyby running the following command:export POLICY="${NAME}-policy"$ export POLICY="${NAME}-policy"Copy to Clipboard Copied! Toggle word wrap Toggle overflow Grant read access to the secret you created earlier by running the following command:
vault policy write $POLICY -<<EOF path "secret/$NAME" { capabilities = ["read"] } EOF$ vault policy write $POLICY -<<EOF path "secret/$NAME" { capabilities = ["read"] } EOFCopy to Clipboard Copied! Toggle word wrap Toggle overflow Create the following environment variables by running the following commands:
export APP_NAME=client
$ export APP_NAME=clientCopy to Clipboard Copied! Toggle word wrap Toggle overflow export APP_NAMESPACE=demo
$ export APP_NAMESPACE=demoCopy to Clipboard Copied! Toggle word wrap Toggle overflow export AUDIENCE=$APP_NAME
$ export AUDIENCE=$APP_NAMECopy to Clipboard Copied! Toggle word wrap Toggle overflow Create a JWT role that binds the policy to workload with a specific SPIFFE ID by running the following command:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
10.7.2.5. Deploying a demonstration application Copiar enlaceEnlace copiado en el portapapeles!
When you deploy a demonstration application, you create a simple client application that uses its SPIFFE identity to authenticate with Vault.
Procedure
On your local machine, set the environment variables for your application by running the following commands:
export APP_NAME=client
$ export APP_NAME=clientCopy to Clipboard Copied! Toggle word wrap Toggle overflow export APP_NAMESPACE=demo
$ export APP_NAMESPACE=demoCopy to Clipboard Copied! Toggle word wrap Toggle overflow export AUDIENCE=$APP_NAME
$ export AUDIENCE=$APP_NAMECopy to Clipboard Copied! Toggle word wrap Toggle overflow Apply the Kubernetes manifest to create the namespace, service account, and deployment for the demo app by running the following command. This deployment mounts the SPIFFE CSI driver socket.
oc apply -f - <<EOF # ... (paste the full YAML from your provided code here) ... EOF
$ oc apply -f - <<EOF # ... (paste the full YAML from your provided code here) ... EOFCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
Verify that the client deployment is ready by running the following command:
oc get deploy -n $APP_NAMESPACE
$ oc get deploy -n $APP_NAMESPACECopy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
NAME READY UP-TO-DATE AVAILABLE AGE frontend-app 2/2 2 2 120d backend-api 3/3 3 3 120d
NAME READY UP-TO-DATE AVAILABLE AGE frontend-app 2/2 2 2 120d backend-api 3/3 3 3 120dCopy to Clipboard Copied! Toggle word wrap Toggle overflow
10.7.2.6. Authenticating and retrieving the secret Copiar enlaceEnlace copiado en el portapapeles!
You use the demonstration application to fetch a JWT token from the SPIFFE Workload API and use it to log in to Vault and retrieve the secret.
Procedure
Fetch a JWT-SVID by running the following command inside the running client pod:
oc -n $APP_NAMESPACE exec -it $(oc get pod -o=jsonpath='{.items[*].metadata.name}' -l app=$APP_NAME -n $APP_NAMESPACE) \ -- /opt/spire/bin/spire-agent api fetch jwt \ -socketPath /run/spire/sockets/spire-agent.sock \ -audience $AUDIENCE$ oc -n $APP_NAMESPACE exec -it $(oc get pod -o=jsonpath='{.items[*].metadata.name}' -l app=$APP_NAME -n $APP_NAMESPACE) \ -- /opt/spire/bin/spire-agent api fetch jwt \ -socketPath /run/spire/sockets/spire-agent.sock \ -audience $AUDIENCECopy to Clipboard Copied! Toggle word wrap Toggle overflow Copy the token from the output and export it as an environment variable on your local machine by running the following command:
export IDENTITY_TOKEN=<Your-JWT-Token>
$ export IDENTITY_TOKEN=<Your-JWT-Token>Copy to Clipboard Copied! Toggle word wrap Toggle overflow Crate a new environment variable by running the following command:
export ROLE="${NAME}-role"$ export ROLE="${NAME}-role"Copy to Clipboard Copied! Toggle word wrap Toggle overflow Use
curlto send the JWT token to the Vault login endpoint to get a Vault client token by running the following command:VAULT_TOKEN=$(curl -s --request POST --data '{ "jwt": "'"${IDENTITY_TOKEN}"'", "role": "'"${ROLE}"'"}' "${VAULT_ADDR}"/v1/auth/jwt/login | jq -r '.auth.client_token')$ VAULT_TOKEN=$(curl -s --request POST --data '{ "jwt": "'"${IDENTITY_TOKEN}"'", "role": "'"${ROLE}"'"}' "${VAULT_ADDR}"/v1/auth/jwt/login | jq -r '.auth.client_token')Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
Use the newly acquired Vault token to read the secret from the KV store by running the following command:
curl -s -H "X-Vault-Token: $VAULT_TOKEN" $VAULT_ADDR/v1/secret/$NAME | jq
$ curl -s -H "X-Vault-Token: $VAULT_TOKEN" $VAULT_ADDR/v1/secret/$NAME | jqCopy to Clipboard Copied! Toggle word wrap Toggle overflow You should see the contents of the secret (
"version": "v0.1.0") in the output, confirming the entire workflow is successful
10.8. Zero Trust Workload Identity Manager SPIRE federation Copiar enlaceEnlace copiado en el portapapeles!
Configure SPIRE federation to enable workloads in different trust domains to securely authenticate each other across clusters, cloud providers, and organizational boundaries. By establishing trust relationships between separate SPIRE deployments, you can build a zero-trust architecture that spans multiple environments without compromising security or sharing secrets.
Federation works by securely sharing trust bundles between SPIRE servers through dedicated federation endpoints. Each SPIRE deployment maintains its own trust domain and cryptographic identity, while being able to verify identities from federated trust domains. This approach enables cross-cluster communication, multi-cloud deployments, and secure integration with external partners.
Setting up SPIRE federation involves the following high-level steps:
-
Choose an authentication profile: Select either
https_spiffeorhttps_web. - Configure the bundle endpoints: Each cluster exposes its trust bundle through a federation endpoint secured by the chosen authentication profile.
- Bootstrap the initial trust: Manually fetch and configure the initial trust bundle from each remote cluster.
-
Establish federation relationships: Create
ClusterFederatedTrustDomainresources to define which clusters trust each other. - Configure automatic synchronization: The SPIRE Controller Manager automatically keeps trust bundles synchronized after initial setup.
10.8.1. Understanding bundle endpoint profiles Copiar enlaceEnlace copiado en el portapapeles!
The bundle endpoint profile determines how your cluster exposes its trust bundle to other SPIRE deployments and how it authenticates remote clusters accessing the bundle. Choose the profile that best matches your security requirements and infrastructure.
The Zero Trust Workload Identity Manager supports two authentication profiles for federation:
- https_spiffe
- Uses SPIFFE-based TLS authentication. The SPIRE server presents its own SVID (SPIFFE Verifiable Identity Document) to authenticate itself to remote SPIRE servers. This profile provides strong cryptographic identity verification and is ideal for federation between SPIRE deployments.
- https_web
- Uses standard Web PKI (X.509 certificates from public or private certificate Authorities). This profile supports both automatic certificate management via ACME (Let’s Encrypt) and manual certificate management using tools like cert-manager.
The following table summarizes the key differences between the two profiles:
| Criteria | https_spiffe | https_web |
|---|---|---|
| Authentication method | SPIFFE SVID (TLS) | X.509 certificate from CA |
| Certificate management | Automatic (SPIRE-managed) | ACME (automatic) or manual |
| Trust model | SPIFFE trust domain | Web PKI / CA trust |
| Best for | Internal SPIRE-to-SPIRE federation | External federation, public endpoints |
| Security level | Very high (cryptographic identity) | High (CA-based trust) |
| Setup complexity | Medium (requires SPIFFE IDs) | Low (ACME) to Medium (manual certs) |
After enablement, federation cannot be disabled. The bundle endpoint profile is immutable once configured. Changing the profile or disabling federation requires reinstallation of the system. However, peer configurations (federatesWith) remain dynamic and can be added or removed at any time. Plan your profile selection carefully based on your long-term federation requirements.
10.8.2. Federation configuration examples Copiar enlaceEnlace copiado en el portapapeles!
The following examples demonstrate different SPIRE federation configurations. Use these as templates when setting up federation between your clusters.
- Example 1: Using ACME for automatic certificate management
The following example shows how to configure federation using Let’s Encrypt for automatic certificate provisioning and renewal:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow -
The
profilefield useshttps_webprofile for Web PKI certificate-based authentication. -
The
directoryURLfield is used for the production directory. For testing, use staging URLhttps://acme-staging-v02.api.letsencrypt.org/directory
-
The
- Example 2: Using manual certificate management with cert-manager
The following example shows how to configure federation using externally managed certificates:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow -
The
fileSyncIntervalfield checks for certificate updates every 24 hours. -
The
externalSecretReffield is the name of the Kubernetes Secret containingtls.crtandtls.key
-
The
- Example 3: Using https_spiffe profile for SPIRE-to-SPIRE federation
The following example shows how to configure federation using SPIFFE-based TLS authentication:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow -
The
profilefield useshttps_spiffeprofile for SPIFFE-based TLS authentication. -
The
endpointSiffeIdfield contains the SPIFFE ID of the remote SPIRE server, required for identity validation.
-
The
- Example 4: Mixed federation with multiple authentication profiles
The following example shows a cluster federating with multiple remote clusters using different authentication profiles:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow -
The
profilefield cluster exposes its bundle usinghttps_spiffeprofile. -
The
bundleEndpointProfilefield cluster exposes its bundle usinghttps_spiffeprofile.
-
The
10.8.3. Configuring SPIRE federation with the https_spiffe profile Copiar enlaceEnlace copiado en el portapapeles!
The Zero Trust Workload Identity Manager includes SPIRE Federation support, allowing multiple independent SPIRE deployments to establish trust relationships. This procedure demonstrates how to configure federation using the https_spiffe profile, which uses SPIFFE-based TLS authentication between SPIRE servers.
Prerequisites
-
You have installed the OpenShift CLI (
oc). - You have installed the Zero Trust Workload Identity Manager on all clusters that will participate in the federation.
-
You have
cluster-adminprivileges on all participating clusters. - You have network connectivity between the clusters you intend to federate.
Procedure
Configure the
SpireServercustom resource on each cluster to enable federation with thehttps_spiffeprofile. Thehttps_spiffeprofile uses SPIFFE-based TLS authentication, where SPIRE servers authenticate to each other using their own SVIDs (SPIFFE Verifiable Identity Documents).Copy to Clipboard Copied! Toggle word wrap Toggle overflow -
The
trustDomainfield sets a unique trust domain for each cluster. -
The
profilefield uses thehttps_spiffeprofile for SPIFFE-based TLS authentication. -
The
refreshHintfield suggests intervals (in seconds) for remote servers to refresh the trust bundle. Range: 60-3600 seconds. -
The
managedRoutefield enables automatic route creation by the Operator.
-
The
Apply the configuration changes by running the following command:
oc apply -f spire-server.yaml
$ oc apply -f spire-server.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow Check the status of the SPIRE Server by entering the following command. Wait for the
Readystatus to be returned.oc get spireserver cluster -w
$ oc get spireserver cluster -wCopy to Clipboard Copied! Toggle word wrap Toggle overflow Verify that the federation route has been created:
oc get route -n zero-trust-workload-identity-manager | grep federation
$ oc get route -n zero-trust-workload-identity-manager | grep federationCopy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
NAME HOST/PORT PATH SERVICES PORT TERMINATION spire-server-federation federation.apps.cluster1.example.com spire-server 8443 passthrough
NAME HOST/PORT PATH SERVICES PORT TERMINATION spire-server-federation federation.apps.cluster1.example.com spire-server 8443 passthroughCopy to Clipboard Copied! Toggle word wrap Toggle overflow Fetch the trust bundle from each remote cluster’s federation endpoint:
curl -k https://federation.apps.cluster2.example.com > cluster2-bundle.json
$ curl -k https://federation.apps.cluster2.example.com > cluster2-bundle.jsonCopy to Clipboard Copied! Toggle word wrap Toggle overflow NoteFor
https_spiffeprofile, you might need to use-kflag if the certificate is not trusted by your system’s CA bundle:The response contains the trust bundle in JSON Web Key Set (JWKS) format:
Example trust bundle
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Create
ClusterFederatedTrustDomainresources for each remote trust domain.On Cluster 1, create a resource to federate with Cluster 2:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow -
The
endpointSPIFFEIDfield contains the SPIFFE ID of the remote SPIRE server. Required forhttps_spiffeprofile to validate the remote server’s identity. -
The
trustDomainBundlecontains the complete trust bundle JSON that you fetched in the previous step.
-
The
Apply the
ClusterFederatedTrustDomainresource by running the following command:oc apply -f clusterfederatedtrustdomain.yaml
$ oc apply -f clusterfederatedtrustdomain.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow -
Repeat steps 5-7 on each cluster for every remote cluster it should federate with. For bidirectional federation, each cluster needs a
ClusterFederatedTrustDomainresource for every other cluster. Update the
SpireServerresource on each cluster to add thefederatesWithconfiguration:Copy to Clipboard Copied! Toggle word wrap Toggle overflow -
The
federatesWithfield lists all remote trust domains this cluster should federate with.
-
The
Apply the updated configuration by running the following command:
oc apply -f spireserver.yaml
$ oc apply -f spireserver.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
Verify that the
ClusterFederatedTrustDomainresources have been created by running the following command:oc get clusterfederatedtrustdomains
$ oc get clusterfederatedtrustdomainsCopy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
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
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 5mCopy to Clipboard Copied! Toggle word wrap Toggle overflow Check the status of a
ClusterFederatedTrustDomainto ensure bundle synchronization is working by running the following command:oc describe clusterfederatedtrustdomain cluster2-federation
$ oc describe clusterfederatedtrustdomain cluster2-federationCopy to Clipboard Copied! Toggle word wrap Toggle overflow Look for successful status conditions indicating that the trust bundle has been synchronized.
Verify that the federation endpoint is accessible by running the following command:
curl https://federation.apps.cluster1.example.com
$ curl https://federation.apps.cluster1.example.comCopy to Clipboard Copied! Toggle word wrap Toggle overflow 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:
oc logs -n zero-trust-workload-identity-manager \ deployment/spire-server -c spire-server --tail=50$ oc logs -n zero-trust-workload-identity-manager \ deployment/spire-server -c spire-server --tail=50Copy to Clipboard Copied! Toggle word wrap Toggle overflow Look for log messages indicating successful bundle synchronization with federated trust domains.
10.8.4. Using SPIRE federation with Automatic Certificate Management Environment protocol Copiar enlaceEnlace copiado en el portapapeles!
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 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.
Procedure
Configure the
SpireServercustom resource on each cluster to enable federation with ACME certificate management.Create or update your
SpireServerresource with the federation configuration:Copy to Clipboard Copied! Toggle word wrap Toggle overflow -
The
trustDomainfield sets a unique trust domain for each cluster (for example,cluster1.example.com,cluster2.example.com). -
The
profilefield uses thehttps_webprofile for ACME-based certificate management. -
The
directoryUrlfield contains the Let’s Encrypt production directory URL. For testing, use:https://acme-staging-v02.api.letsencrypt.org/directory. -
The
domainNamefield is the domain name where your federation endpoint is accessible. This automatically sets tofederation.<cluster-apps-domain>ifmanagedRouteis set to "true". -
The
emailfield is your email address for ACME account registration and certificate expiration notifications. -
The
tosAcceptedfield accepts the Let’s Encrypt Terms of Service. -
The
managedRoutefield enables an automatic route creation by the operator for the federation bundle endpoint.
-
The
Apply the configuration to each cluster by running the following command:
oc apply -f spireserver.yaml
$ oc apply -f spireserver.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow 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 -w
$ oc get spireserver cluster -wCopy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
NAME STATUS AGE cluster Ready 5m
NAME STATUS AGE cluster Ready 5mCopy to Clipboard Copied! Toggle word wrap Toggle overflow Verify that the federation route has been created by running the following command:
oc get route -n zero-trust-workload-identity-manager | grep federation
$ oc get route -n zero-trust-workload-identity-manager | grep federationCopy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
NAME HOST/PORT PATH SERVICES PORT TERMINATION spire-server-federation federation.apps.cluster1.example.com spire-server 8443 passthrough
NAME HOST/PORT PATH SERVICES PORT TERMINATION spire-server-federation federation.apps.cluster1.example.com spire-server 8443 passthroughCopy to Clipboard Copied! Toggle word wrap Toggle overflow 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.json
$ curl https://federation.apps.cluster1.example.com > cluster1-bundle.jsonCopy to Clipboard Copied! Toggle word wrap Toggle overflow The response contains the trust bundle in JSON Web Key Set (JWKS) format:
Example trust bundle
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Create
ClusterFederatedTrustDomainresources to establish federation relationships.On Cluster 1, create resources to federate with Cluster 2 and Cluster 3:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow -
The
trustDomainBundlefield contains the complete trust bundle JSON that you fetched usingcurlin step 5.
-
The
Apply the
ClusterFederatedTrustDomainresources by running the following command:oc apply -f cluster-federated-trust-domains.yaml
$ oc apply -f cluster-federated-trust-domains.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow -
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:Copy to Clipboard Copied! Toggle word wrap Toggle overflow -
The
federatesWithfield lists all remote trust domains this cluster should federate with.
-
The
Apply the updated configuration by running the following command:
oc apply -f spireserver.yaml
$ oc apply -f spireserver.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
Verify that the
ClusterFederatedTrustDomainresources have been created by running the following command:oc get clusterfederatedtrustdomains
$ oc get clusterfederatedtrustdomainsCopy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
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
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 5mCopy to Clipboard Copied! Toggle word wrap Toggle overflow Check the status of a
ClusterFederatedTrustDomainto ensure bundle synchronization is working by running the following command:oc describe clusterfederatedtrustdomain cluster2-federation
$ oc describe clusterfederatedtrustdomain cluster2-federationCopy to Clipboard Copied! Toggle word wrap Toggle overflow Look 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.com
$ curl https://federation.apps.cluster1.example.comCopy to Clipboard Copied! Toggle word wrap Toggle overflow 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:
oc logs -n zero-trust-workload-identity-manager deployment/spire-server -c spire-server --tail=50
$ oc logs -n zero-trust-workload-identity-manager deployment/spire-server -c spire-server --tail=50Copy to Clipboard Copied! Toggle word wrap Toggle overflow Look 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-manager
$ oc get pods -n zero-trust-workload-identity-managerCopy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
NAME READY STATUS RESTARTS AGE spire-agent-abcde 1/1 Running 0 10m spire-server-0 2/2 Running 0 10m
NAME READY STATUS RESTARTS AGE spire-agent-abcde 1/1 Running 0 10m spire-server-0 2/2 Running 0 10mCopy to Clipboard Copied! Toggle word wrap Toggle overflow - 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.
10.8.5. Using SPIRE federation with manual certificate management Copiar enlaceEnlace copiado en el portapapeles!
You can use SPIRE federation with custom certificate management using cert-manager or other certificate providers. This approach provides flexibility for organizations that require control over certificate issuance, support for internal certificate authorities (CAs), or integration with existing certificate management infrastructure.
Prerequisites
- 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. - You have installed the cert-manager Operator for Red Hat OpenShift. For more information, see cert-manager Operator for Red Hat OpenShift.
- Your federation endpoints must be publicly accessible for certificate validation.
- You have network connectivity between all federated clusters.
Procedure
Install the cert-manager Operator on the cluster where you want to use externally managed certificates.
Create a namespace and install the operator:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Apply the cert-manager installation by running the following command:
oc apply -f cert-manager-install.yaml
$ oc apply -f cert-manager-install.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow Check the status of the cert-manager Operator by entering the following command:
oc get pods -n cert-manager
$ oc get pods -n cert-managerCopy to Clipboard Copied! Toggle word wrap Toggle overflow All cert-manager pods should be in
Runningstatus.Create an Issuer for certificate provisioning.
For Let’s Encrypt with HTTP-01 challenge:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Alternatively, for an internal CA:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Apply the Issuer by running the following command:
oc apply -f issuer.yaml
$ oc apply -f issuer.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow Determine the federation endpoint domain name.
The federation route follows a predictable naming pattern if
managedRouteis set totrue. Get your cluster’s application domain by running the following command:CLUSTER_DOMAIN=$(oc get ingresses.config/cluster -o jsonpath='{.spec.domain}') FEDERATION_DOMAIN="federation.${CLUSTER_DOMAIN}" echo "Federation domain will be: $FEDERATION_DOMAIN"$ CLUSTER_DOMAIN=$(oc get ingresses.config/cluster -o jsonpath='{.spec.domain}') $ FEDERATION_DOMAIN="federation.${CLUSTER_DOMAIN}" $ echo "Federation domain will be: $FEDERATION_DOMAIN"Copy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
Federation domain will be: federation.apps.cluster1.example.com
Federation domain will be: federation.apps.cluster1.example.comCopy to Clipboard Copied! Toggle word wrap Toggle overflow NoteThe federation route is created automatically if
managedRouteis set totruewhen you apply theSpireServerconfiguration in a later step. The route name isspire-server-federationand the hostname isfederation.<cluster-apps-domain>.Create a Certificate resource to request a TLS certificate.
Use the federation domain determined in the previous step:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow -
The
secretNamefield must match theexternalSecretRefvalue in SpireServer. -
The
durationfield shows how long a certificate is valid. Certificates are valid for 90 days. -
The
renewBeforefield shows how many days a certificate must be renewed before it expires. Renew a certificate 15 days before expiration. -
The
commonNamefield must be replaced with your actual federation domain from the previous step. -
The
dnsNamesfield must match thecommonNameand the actual routehostnamethat was created. -
The
namefield must reference the Issuer that was created earlier.
-
The
Apply the Certificate resource by running the following command:
oc apply -f certificate.yaml
$ oc apply -f certificate.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow Monitor the certificate issuance by running the following command:
oc get certificate spire-server-federation-tls \ -n zero-trust-workload-identity-manager -w$ oc get certificate spire-server-federation-tls \ -n zero-trust-workload-identity-manager -wCopy to Clipboard Copied! Toggle word wrap Toggle overflow Example output when ready
NAME READY SECRET AGE spire-server-federation-tls True spire-server-federation-tls 2m
NAME READY SECRET AGE spire-server-federation-tls True spire-server-federation-tls 2mCopy to Clipboard Copied! Toggle word wrap Toggle overflow Create RBAC permissions for the OpenShift Ingress Router to access the certificate secret.
Create a Role by running the following command:
oc create role secret-reader \ --verb=get,list,watch \ --resource=secrets \ --resource-name=spire-server-federation-tls \ -n zero-trust-workload-identity-manager$ oc create role secret-reader \ --verb=get,list,watch \ --resource=secrets \ --resource-name=spire-server-federation-tls \ -n zero-trust-workload-identity-managerCopy to Clipboard Copied! Toggle word wrap Toggle overflow Create a
RoleBindingby running the following command:oc create rolebinding secret-reader-binding \ --role=secret-reader \ --serviceaccount=openshift-ingress:router \ -n zero-trust-workload-identity-manager$ oc create rolebinding secret-reader-binding \ --role=secret-reader \ --serviceaccount=openshift-ingress:router \ -n zero-trust-workload-identity-managerCopy to Clipboard Copied! Toggle word wrap Toggle overflow Configure the
SpireServercustom resource to use manual certificate management.Now that the certificate is ready, configure the SpireServer to reference it:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow -
The
profilefield must usehttps_webprofile for certificate-based authentication. -
The
fileSyncIntervalfield checks for certificate updates every 24 hours (86400 seconds). Range: 3600-7776000 seconds. -
The
externalSecretReffield is the name of the secret containing the TLS certificate and private key. Must match the certificate secret created in the previous steps.
-
The
Apply the configuration by running the following command:
oc apply -f spireserver.yaml
$ oc apply -f spireserver.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow Wait for the SPIRE Server to be ready:
oc get spireserver cluster -n zero-trust-workload-identity-manager -w
$ oc get spireserver cluster -n zero-trust-workload-identity-manager -wCopy to Clipboard Copied! Toggle word wrap Toggle overflow Wait until the status shows
Ready.Verify that the federation route was created by running the following command:
oc get route spire-server-federation -n zero-trust-workload-identity-manager
$ oc get route spire-server-federation -n zero-trust-workload-identity-managerCopy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
NAME HOST/PORT PATH SERVICES PORT TERMINATION spire-server-federation federation.apps.cluster1.example.com spire-server 8443 reencrypt
NAME HOST/PORT PATH SERVICES PORT TERMINATION spire-server-federation federation.apps.cluster1.example.com spire-server 8443 reencryptCopy to Clipboard Copied! Toggle word wrap Toggle overflow Verify that the route hostname matches the domain name used in your certificate.
Verify that the federation endpoint is accessible by running the following command:
curl https://$(oc get route spire-server-federation \ -n zero-trust-workload-identity-manager \ -o jsonpath='{.spec.host}')$ curl https://$(oc get route spire-server-federation \ -n zero-trust-workload-identity-manager \ -o jsonpath='{.spec.host}')Copy to Clipboard Copied! Toggle word wrap Toggle overflow You should receive a JSON response containing the trust bundle.
Fetch the trust bundle from each federation endpoint that you want to federate with.
For each remote cluster, fetch its trust bundle by running the following commands:
curl https://federation.apps.cluster1.example.com > cluster1-bundle.json curl https://federation.apps.cluster2.example.com > cluster2-bundle.json
$ curl https://federation.apps.cluster1.example.com > cluster1-bundle.json $ curl https://federation.apps.cluster2.example.com > cluster2-bundle.jsonCopy to Clipboard Copied! Toggle word wrap Toggle overflow The trust bundle is in JSON Web Key Set (JWKS) format:
Example trust bundle
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Create
ClusterFederatedTrustDomainresources for each remote trust domain you want to federate with:Copy to Clipboard Copied! Toggle word wrap Toggle overflow -
The
trustDomainBundlefield contains the complete trust bundle JSON that you fetched in the previous step.
-
The
Apply the
ClusterFederatedTrustDomainresources by running the following command:oc apply -f clusterfederatedtrustdomains.yaml
$ oc apply -f clusterfederatedtrustdomains.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow Update the
SpireServerresource to add thefederatesWithconfiguration:Copy to Clipboard Copied! Toggle word wrap Toggle overflow -
The
federatesWithfield lists all remote trust domains this cluster should federate with.
-
The
Apply the updated configuration by running the following command:
oc apply -f spireserver.yaml
$ oc apply -f spireserver.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow Repeat steps 1-15 on each cluster that participates in the federation, ensuring that:
- Each cluster has cert-manager installed and configured
-
Each cluster has its own certificate created and ready before applying the
SpireServerconfiguration - Each cluster has the RBAC for the ingress router configured
-
Each cluster has
ClusterFederatedTrustDomainresources for every other cluster it federates with -
Each cluster’s
SpireServerhas the completefederatesWithlist
Verification
Verify that the certificate has been issued successfully by running the following command:
oc get certificate spire-server-federation-tls \ -n zero-trust-workload-identity-manager$ oc get certificate spire-server-federation-tls \ -n zero-trust-workload-identity-managerCopy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
NAME READY SECRET AGE spire-server-federation-tls True spire-server-federation-tls 5m
NAME READY SECRET AGE spire-server-federation-tls True spire-server-federation-tls 5mCopy to Clipboard Copied! Toggle word wrap Toggle overflow Check the certificate details and expiration by running the following command:
oc get secret spire-server-federation-tls \ -n zero-trust-workload-identity-manager \ -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -dates$ oc get secret spire-server-federation-tls \ -n zero-trust-workload-identity-manager \ -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -datesCopy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
notBefore=Dec 16 10:00:00 2025 GMT notAfter=Mar 16 10:00:00 2026 GMT
notBefore=Dec 16 10:00:00 2025 GMT notAfter=Mar 16 10:00:00 2026 GMTCopy to Clipboard Copied! Toggle word wrap Toggle overflow Verify that the RBAC permissions are configured correctly by running the following command:
oc get role,rolebinding -n zero-trust-workload-identity-manager \ | grep secret-reader$ oc get role,rolebinding -n zero-trust-workload-identity-manager \ | grep secret-readerCopy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
role.rbac.authorization.k8s.io/secret-reader rolebinding.rbac.authorization.k8s.io/secret-reader-binding
role.rbac.authorization.k8s.io/secret-reader rolebinding.rbac.authorization.k8s.io/secret-reader-bindingCopy to Clipboard Copied! Toggle word wrap Toggle overflow Verify the RoleBinding references the correct ServiceAccount by running the following command:
oc describe rolebinding secret-reader-binding \ -n zero-trust-workload-identity-manager$ oc describe rolebinding secret-reader-binding \ -n zero-trust-workload-identity-managerCopy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Verify that the
ClusterFederatedTrustDomainresources have been created by running the following command:oc get clusterfederatedtrustdomains
$ oc get clusterfederatedtrustdomainsCopy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
NAME TRUST DOMAIN ENDPOINT URL AGE cluster1-federation cluster1.example.com https://federation.apps.cluster1.example.com 5m cluster2-federation cluster2.example.com https://federation.apps.cluster2.example.com 5m
NAME TRUST DOMAIN ENDPOINT URL AGE cluster1-federation cluster1.example.com https://federation.apps.cluster1.example.com 5m cluster2-federation cluster2.example.com https://federation.apps.cluster2.example.com 5mCopy to Clipboard Copied! Toggle word wrap Toggle overflow Check the status of a
ClusterFederatedTrustDomainto ensure bundle synchronization is working by running the following command:oc describe clusterfederatedtrustdomain cluster1-federation
$ oc describe clusterfederatedtrustdomain cluster1-federationCopy to Clipboard Copied! Toggle word wrap Toggle overflow Look for successful status conditions indicating that the trust bundle has been synchronized.
Verify that the federation endpoint is accessible and using the correct certificate by running the following command:
curl -v https://$(oc get route spire-server-federation \ -n zero-trust-workload-identity-manager \ -o jsonpath='{.spec.host}')$ curl -v https://$(oc get route spire-server-federation \ -n zero-trust-workload-identity-manager \ -o jsonpath='{.spec.host}')Copy to Clipboard Copied! Toggle word wrap Toggle overflow In the output, verify that the certificate presented is issued by your configured CA (Let’s Encrypt or internal CA).
Check the SPIRE Server logs to confirm that by running the following command:
- Federation is active with remote trust domains
- Trust bundles are being synchronized
The bundle endpoint is serving correctly
oc logs -n zero-trust-workload-identity-manager \ statefulset/spire-server -c spire-server --tail=100$ oc logs -n zero-trust-workload-identity-manager \ statefulset/spire-server -c spire-server --tail=100Copy to Clipboard Copied! Toggle word wrap Toggle overflow Look for log messages indicating successful federation bundle synchronization.
Verify that all SPIRE components are running by running the following command:
oc get pods -n zero-trust-workload-identity-manager
$ oc get pods -n zero-trust-workload-identity-managerCopy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
NAME READY STATUS RESTARTS AGE spire-agent-abc123 1/1 Running 0 10m spire-server-0 2/2 Running 0 10m
NAME READY STATUS RESTARTS AGE spire-agent-abc123 1/1 Running 0 10m spire-server-0 2/2 Running 0 10mCopy to Clipboard Copied! Toggle word wrap Toggle overflow - 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.
10.8.6. Federation configuration field reference Copiar enlaceEnlace copiado en el portapapeles!
This reference provides detailed information about all configuration fields available for SPIRE federation in the SpireServer custom resource. Use this reference when customizing your federation setup.
- Top-level federation fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
|
| object | Yes | N/A | Configuration for this cluster’s federation endpoint that exposes the trust bundle to remote clusters. |
|
| array | No |
| List of remote trust domains to federate with. |
|
| string | No |
|
Enable or disable automatic OpenShift Route creation. Set to |
- bundleEndpoint configuration fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
|
| string (enum) | Yes |
|
Authentication profile for the bundle endpoint. Valid values: |
|
| integer | No |
| Suggested interval (in seconds) for remote servers to refresh the trust bundle. Valid range: 60-3600. |
|
| object | Conditional | N/A |
Required when |
- httpsWeb configuration fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
|
| object | Conditional | N/A |
ACME configuration for automatic certificate management. Mutually exclusive with |
|
| object | Conditional | N/A |
Manual certificate configuration. Mutually exclusive with |
- ACME configuration fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
|
| string | Yes | N/A |
ACME directory URL. For Let’s Encrypt production: |
|
| string | Yes | N/A | Fully qualified domain name for the certificate. Typically the federation endpoint hostname. |
|
| string | Yes | N/A | Email address for ACME account registration and certificate expiration notifications. |
|
| string | No |
|
Accept the ACME provider’s Terms of Service. Must be |
- servingCert configuration fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
|
| integer | No |
| Interval (in seconds) to check for certificate updates. Valid range: 3600-7776000 (1 hour to 90 days). |
|
| string | Yes | N/A |
Name of the Kubernetes Secret containing the TLS certificate ( |
- federatesWith configuration fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
|
| string | Yes | N/A |
Trust domain name of the remote SPIRE deployment (for example, |
|
| string | Yes | N/A |
HTTPS URL of the remote federation endpoint (for example, |
|
| string (enum) | Yes | N/A |
Authentication profile of the remote endpoint. Valid values: |
|
| string | Conditional | N/A |
SPIFFE ID of the remote SPIRE server (for example, |
- Field validation rules
The following validation rules are enforced by the operator:
-
Profile immutability: The
bundleEndpoint.profilefield cannot be changed after initial configuration. Changing it requires deleting and recreating theSpireServerresource (re-installation of the system). -
Mutual exclusivity: Within
httpsWeb, only one ofacmeorservingCertcan be specified. -
Conditional requirements: When
profileishttps_web, thehttpsWebobject must be present with eitheracmeorservingCertconfigured. -
SPIFFE ID requirement: When
bundleEndpointProfileishttps_spiffein thefederatesWithlist, theendpointSpiffeIdfield is required. -
Array limits: The
federatesWitharray supports a maximum of 50 entries. Numeric ranges:
-
refreshHint: 60-3600 seconds -
fileSyncInterval: 3600-7776000 seconds
-
-
Profile immutability: The
10.9. Enabling create-only mode for the Zero Trust Workload Identity Manager Copiar enlaceEnlace copiado en el portapapeles!
By enabling the create-only mode, you can pause the Operator reconciliation, which allows you to perform manual configurations or debug without the controller overwriting your changes. This is done by annotating the API resources which are managed by the Operator. The following scenarios are examples of when the create-only mode might be of use:
Manual Customization Required: You need to customize operator-managed resources (ConfigMaps, Deployments, DaemonSets, etc.) with specific configurations that differ from the operator’s defaults
Day 2 Operations: After initial deployment, you want to prevent the operator from overwriting their manual changes during subsequent reconciliation cycles
Configuration Drift Prevention: You want to maintain control over certain resource configurations while still benefiting from the operator’s lifecycle management
10.9.1. Pausing Operator reconciliation by annotation Copiar enlaceEnlace copiado en el portapapeles!
Reconciliation by annotation supports the SpireServer, SpireAgent, SpiffeCSIDriver, SpireOIDCDiscoveryProvider, and the ZeroTrustWorkloadIdentityManager custom resources. You can pause the reconciliation process by adding an annotation.
Prerequisites
- You have installed Zero Trust Workload Identity Manager on your machine.
- You have installed the SPIRE Servers, Agents, SPIFFE Container Storage Interface (CSI), and an OpenID Connect (OIDC) Discovery Provider and are in running status.
Procedure
To pause reconciling the
SpireServercustom resource, add thecreate-onlyannotation to the namedclusterby running the following command:oc annotate SpireServer cluster -n zero-trust-workload-identity-manager ztwim.openshift.io/create-only=true
$ oc annotate SpireServer cluster -n zero-trust-workload-identity-manager ztwim.openshift.io/create-only=trueCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
Check the status of the
SpireServerresource to confirm that thecreate-onlymode is active. Thestatusmust betrueand thereasonmust beCreateOnlyModeEnabled.oc get SpireServer cluster -o yaml
$ oc get SpireServer cluster -o yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Example output
10.9.2. Resuming Operator reconciliation by annotation Copiar enlaceEnlace copiado en el portapapeles!
Procedure
Follow these steps to restart the reconciliation process:
Run the
oc annotatecommand, adding a hyphen (-) at the end of the annotation name. This removes the annotation from the cluster resource.oc annotate SpireServer cluster -n zero-trust-workload-identity-manager ztwim.openshift.io/create-only-
$ oc annotate SpireServer cluster -n zero-trust-workload-identity-manager ztwim.openshift.io/create-only-Copy to Clipboard Copied! Toggle word wrap Toggle overflow Restart the controller by running the following command:
oc rollout restart deploy/zero-trust-workload-identity-manager-controller-manager -n zero-trust-workload-identity-manager
$ oc rollout restart deploy/zero-trust-workload-identity-manager-controller-manager -n zero-trust-workload-identity-managerCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
Check the status of the
SpireServerresource to confirm that thecreate-onlymode is disabled. Thestatusmust befalseand thereasonmust beCreateOnlyModeDisabled.oc get SpireServer cluster -o yaml
$ oc get SpireServer cluster -o yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Example output
Once create-only mode is enabled, it persists until the Operator pod restarts, even if the annotation is removed. To exit this mode, you might need to remove or unset the annotation and restart the Operator pod.
10.10. Monitoring Zero Trust Workload Identity Manager Copiar enlaceEnlace copiado en el portapapeles!
By default, the SPIRE Server and SPIRE Agent components of the Zero Trust Workload Identity Manager emit metrics. You can configure OpenShift Monitoring to collect these metrics by using the Prometheus Operator format.
10.10.1. Enabling user workload monitoring Copiar enlaceEnlace copiado en el portapapeles!
You can enable monitoring for user-defined projects by configuring user workload monitoring in the cluster.
Prerequisites
-
You have access to the cluster as a user with the
cluster-admincluster role.
Procedure
Create the
cluster-monitoring-config.yamlfile to define and configure theConfigMap:Copy to Clipboard Copied! Toggle word wrap Toggle overflow Apply the
ConfigMapby running the following command:oc apply -f cluster-monitoring-config.yaml
$ oc apply -f cluster-monitoring-config.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
Verify that the monitoring components for user workloads are running in the
openshift-user-workload-monitoringnamespace:oc -n openshift-user-workload-monitoring get pod
$ oc -n openshift-user-workload-monitoring get podCopy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
The status of the pods such as prometheus-operator, prometheus-user-workload, and thanos-ruler-user-workload must be Running.
10.10.2. Configuring metrics collection for SPIRE Server by using a ServiceMonitor Copiar enlaceEnlace copiado en el portapapeles!
To collect custom metrics from the SPIRE Server, create a ServiceMonitor custom resource (CR). This configuration enables the Prometheus Operator to scrape metrics from the default endpoint, which helps you monitor your SPIRE deployment.
The SPIRE Server operand exposes metrics by default on port 9402 at the /metrics endpoint. You can configure metrics collection for the SPIRE Server by creating a ServiceMonitor custom resource (CR) that enables the Prometheus Operator to collect custom metrics.
Prerequisites
-
You have access to the cluster as a user with the
cluster-admincluster role. - You have installed the Zero Trust Workload Identity Manager.
- You have deployed the SPIRE Server operand in the cluster.
- You have enabled the user workload monitoring.
Procedure
Create the
ServiceMonitorCR:Create the YAML file that defines the
ServiceMonitorCR:Example
servicemonitor-spire-serverfileCopy to Clipboard Copied! Toggle word wrap Toggle overflow Create the
ServiceMonitorCR by running the following command:oc create -f servicemonitor-spire-server.yaml
$ oc create -f servicemonitor-spire-server.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow After the
ServiceMonitorCR is created, the user workload Prometheus instance begins metrics collection from the SPIRE Server. The collected metrics are labeled withjob="spire-server".
Verification
-
In the OpenShift Container Platform web console, navigate to Observe
Targets. In the Label filter field, enter the following label to filter the metrics targets:
service=zero-trust-workload-identity-manager-metrics-service
$ service=zero-trust-workload-identity-manager-metrics-serviceCopy to Clipboard Copied! Toggle word wrap Toggle overflow -
Confirm that the Status column shows
Upfor thespire-server-metricsentry.
10.10.3. Configuring metrics collection for SPIRE Agent by using a Service Monitor Copiar enlaceEnlace copiado en el portapapeles!
The SPIRE Agent operand exposes metrics by default on port 9402 at the /metrics endpoint. You can configure metrics collection for the SPIRE Agent by creating a ServiceMonitor custom resource (CR), which enables the Prometheus Operator to collect custom metrics.
Prerequisites
-
You have access to the cluster as a user with the
cluster-admincluster role. - You have installed the Zero Trust Workload Identity Manager.
- You have deployed the SPIRE Agent operand in the cluster.
- You have enabled the user workload monitoring.
Procedure
Create the
ServiceMonitorCR:Create the YAML file that defines the
ServiceMonitorCR:Example
servicemonitor-spire-agent.yamlfileCopy to Clipboard Copied! Toggle word wrap Toggle overflow Create the
ServiceMonitorCR by running the following command:oc create -f servicemonitor-spire-agent.yaml
$ oc create -f servicemonitor-spire-agent.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow After the
ServiceMonitorCR is created, the user workload Prometheus instance begins metrics collection from the SPIRE Agent. The collected metrics are labeled withjob="spire-agent".
Verification
-
In the OpenShift Container Platform web console, navigate to Observe
Targets. In the Label filter field, enter the following label to filter the metrics targets:
service=spire-agent
$ service=spire-agentCopy to Clipboard Copied! Toggle word wrap Toggle overflow -
Confirm that the Status column shows
Upfor thespire-agent-metricsentry.
10.10.4. Configuring metrics collection for the Operator by using a ServiceMonitor Copiar enlaceEnlace copiado en el portapapeles!
The Zero Trust Workload Identity Manager exposes metrics by default on port 8443 at the /metrics service endpoint. You can configure metrics collection for the Operator by creating a ServiceMonitor custom resource (CR) that enables the Prometheus Operator to collect custom metrics. For more information, see "Configuring user workload monitoring".
The SPIRE Server operand exposes metrics by default on port 9402 at the /metrics endpoint. You can configure metrics collection for the SPIRE Server by creating a ServiceMonitor custom resource (CR) that enables the Prometheus Operator to collect custom metrics.
Prerequisites
-
You have access to the cluster as a user with the
cluster-admincluster role. - You have installed the Zero Trust Workload Identity Manager.
- You have enabled the user workload monitoring.
Procedure
Configure the Operator to use HTTP or HTTPS protocols for the metrics server.
Update the subscription object for Zero Trust Workload Identity Manager to configure the HTTP protocol by running the following command:
oc -n zero-trust-workload-identity-manager patch subscription zero-trust-workload-identity-manager-subscription --type='merge' -p '{"spec":{"config":{"env":[{"name":"METRICS_BIND_ADDRESS","value":":8080"}, {"name": "METRICS_SECURE", "value": "false"}]}}}'$ oc -n zero-trust-workload-identity-manager patch subscription zero-trust-workload-identity-manager-subscription --type='merge' -p '{"spec":{"config":{"env":[{"name":"METRICS_BIND_ADDRESS","value":":8080"}, {"name": "METRICS_SECURE", "value": "false"}]}}}'Copy to Clipboard Copied! Toggle word wrap Toggle overflow Verify the Zero Trust Workload Identity Manager pod is redeployed and that the configured values for
METRICS_BIND_ADDRESSandMETRICS_SECUREis updated by running the following command:oc set env --list deployment/zero-trust-workload-identity-manager-controller-manager -n zero-trust-workload-identity-manager | grep -e METRICS_BIND_ADDRESS -e METRICS_SECURE -e container
$ oc set env --list deployment/zero-trust-workload-identity-manager-controller-manager -n zero-trust-workload-identity-manager | grep -e METRICS_BIND_ADDRESS -e METRICS_SECURE -e containerCopy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
deployments/zero-trust-workload-identity-manager-controller-manager, container manager METRICS_BIND_ADDRESS=:8080 METRICS_SECURE=false
deployments/zero-trust-workload-identity-manager-controller-manager, container manager METRICS_BIND_ADDRESS=:8080 METRICS_SECURE=falseCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Create the
Secretresource withkubernetes.io/service-account.nameannotation to inject the token required for authenticating with the metrics server.Create the
secret-zero-trust-workload-identity-manager.yamlYAML file:Copy to Clipboard Copied! Toggle word wrap Toggle overflow Create the
Secretresource by running the following command:oc apply -f secret-zero-trust-workload-identity-manager.yaml
$ oc apply -f secret-zero-trust-workload-identity-manager.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Create the
ClusterRoleBindingresource required for granting permissions to access the metrics.Create the
clusterrolebinding-zero-trust-workload-identity-manager.yamlYAML file:Copy to Clipboard Copied! Toggle word wrap Toggle overflow Create the
ClusterRoleBindingresource by running the following command:oc apply -f clusterrolebinding-zero-trust-workload-identity-manager.yaml
$ oc apply -f clusterrolebinding-zero-trust-workload-identity-manager.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Create the following
ServiceMonitorCR if the metrics server is configured to usehttp.Create the
servicemonitor-zero-trust-workload-identity-manager-http.yamlYAML file:Copy to Clipboard Copied! Toggle word wrap Toggle overflow Create the
ServiceMonitorCR by running the following command:oc apply -f servicemonitor-zero-trust-workload-identity-manager-http.yaml
$ oc apply -f servicemonitor-zero-trust-workload-identity-manager-http.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Create the following
ServiceMonitorCR if the metrics server is configured to usehttps.Create the
servicemonitor-zero-trust-workload-identity-manager-https.yamlYAML file:Copy to Clipboard Copied! Toggle word wrap Toggle overflow Create the
ServiceMonitorCR by running the following command:oc apply -f servicemonitor-zero-trust-workload-identity-manager-https.yaml
$ oc apply -f servicemonitor-zero-trust-workload-identity-manager-https.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow After the
ServiceMonitorCR is created, the user workload Prometheus instance begins metrics collection from the SPIRE Server. The collected metrics are labeled withjob="zero-trust-workload-identity-manager-metrics-service".
Verification
-
In the OpenShift Container Platform web console, navigate to Observe
Targets. In the Label filter field, enter the following label to filter the metrics targets:
service=zero-trust-workload-identity-manager-metrics-service
$ service=zero-trust-workload-identity-manager-metrics-serviceCopy to Clipboard Copied! Toggle word wrap Toggle overflow -
Confirm that the Status column shows
Upfor thezero-trust-workload-identity-managerentry.
10.10.5. Querying metrics for the Zero Trust Workload Identity Manager Copiar enlaceEnlace copiado en el portapapeles!
As a cluster administrator, or as a user with view access to all namespaces, you can query SPIRE Agent and SPIRE Server metrics by using the OpenShift Container Platform web console or the command line. The query retrieves all the metrics collected from the SPIRE components that match the specified job labels.
Prerequisites
-
You have access to the cluster as a user with the
cluster-adminrole. - You have installed the Zero Trust Workload Identity Manager.
- You have deployed the SPIRE Server and SPIRE Agent operands in the cluster.
-
You have enabled monitoring and metrics collection by creating
ServiceMonitorobjects.
Procedure
-
In the OpenShift Container Platform web console, navigate to Observe
Metrics. In the query field, enter the following PromQL expression to query SPIRE Server metrics:
{job="spire-server"}{job="spire-server"}Copy to Clipboard Copied! Toggle word wrap Toggle overflow In the query field, enter the following PromQL expression to query SPIRE Agent metrics.
{job="spire-agent"}{job="spire-agent"}Copy to Clipboard Copied! Toggle word wrap Toggle overflow
10.10.6. Zero Trust Workload Identity Manager monitoring available metrics Copiar enlaceEnlace copiado en el portapapeles!
Monitor the health and performance of Zero Trust Workload Identity Manager components by reviewing exposed metrics. This reference describes controller, certificate, and runtime metrics that help you maintain system health and troubleshoot errors.
The Zero Trust Workload Identity Manager exposes the following metrics:
- Controller runtime metrics
-
controller_runtime_active_workers: Number of currently used workers per controller -
controller_runtime_max_concurrent_reconciles: Maximum number of concurrent reconciles per controller -
controller_runtime_reconcile_errors_total: Total number of reconciliation errors per controller -
controller_runtime_reconcile_time_seconds: Length of time per reconciliation per controller -
controller_runtime_reconcile_total: Total number of reconciliations per controller
-
- Certificate watcher metrics
-
certwatcher_read_certificate_errors_total: Total number of certificate read errors -
certwatcher_read_certificate_total: Total number of certificates read
-
- Go runtime metrics
Standard Go runtime metrics including:
-
go_gc_duration_seconds: Garbage collection duration -
go_goroutines: Number of goroutines -
go_memstats_*: Memory statistics -
process_*: Process statistics
-
- Custom Operator metrics
The operator also exposes custom metrics related to:
- SPIRE Server status and health
- SPIRE Agent deployment status
- SPIFFE CSI Driver status
- OIDC Discovery Provider status
- Workload identity management operations
10.11. Uninstalling the Zero Trust Workload Identity Manager Copiar enlaceEnlace copiado en el portapapeles!
You can remove the Zero Trust Workload Identity Manager from OpenShift Container Platform by uninstalling the Operator and removing its related resources.
10.11.1. Uninstalling the Zero Trust Workload Identity Manager Copiar enlaceEnlace copiado en el portapapeles!
You can uninstall the Zero Trust Workload Identity Manager by using the web console.
Prerequisites
-
You have access to the cluster with
cluster-adminprivileges. - You have access to the OpenShift Container Platform web console.
- The Zero Trust Workload Identity Manager is installed.
Procedure
- Log in to the OpenShift Container Platform web console.
Uninstall the Zero Trust Workload Identity Manager.
-
Go to Ecosystem
Installed Operators. - Click the Options menu next to the Zero Trust Workload Identity Manager entry, and then click Uninstall Operator.
- In the confirmation dialog, click Uninstall.
-
Go to Ecosystem
10.11.2. Uninstalling Zero Trust Workload Identity Manager resources by using the CLI Copiar enlaceEnlace copiado en el portapapeles!
After you have uninstalled the Zero Trust Workload Identity Manager, you have the option to delete its associated resources from your cluster.
Prerequisites
-
You have access to the cluster with
cluster-adminprivileges.
Procedure
Uninstall the operands by running each of the following commands:
Delete the
SpireOIDCDiscoveryProvidercluster by running the following command:oc delete SpireOIDCDiscoveryProvider cluster
$ oc delete SpireOIDCDiscoveryProvider clusterCopy to Clipboard Copied! Toggle word wrap Toggle overflow Delete the
SpiffeCSIDrivercluster by running the following command:oc delete SpiffeCSIDriver cluster -l=app.kubernetes.io/name=zero-trust-workload-identity-manager
$ oc delete SpiffeCSIDriver cluster -l=app.kubernetes.io/name=zero-trust-workload-identity-managerCopy to Clipboard Copied! Toggle word wrap Toggle overflow Delete the
SpireAgentcluster by running the following command:oc delete SpireAgent cluster
$ oc delete SpireAgent clusterCopy to Clipboard Copied! Toggle word wrap Toggle overflow Delete the
SpireServercluster by running the following command:oc delete SpireServer cluster
$ oc delete SpireServer clusterCopy to Clipboard Copied! Toggle word wrap Toggle overflow Delete the
ZeroTrustWorkloadIdentityManagercluster by running the following command:oc delete ZeroTrustWorkloadIdentityManager cluster
$ oc delete ZeroTrustWorkloadIdentityManager clusterCopy to Clipboard Copied! Toggle word wrap Toggle overflow Delete the persistent volume claim (PVC) by running the following command:
oc delete pvc -l=app.kubernetes.io/name=spire-server
$ oc delete pvc -l=app.kubernetes.io/name=spire-serverCopy to Clipboard Copied! Toggle word wrap Toggle overflow Delete the service by running the following command:
oc delete service -l=app.kubernetes.io/name=zero-trust-workload-identity-manager -n zero-trust-workload-identity-manager
$ oc delete service -l=app.kubernetes.io/name=zero-trust-workload-identity-manager -n zero-trust-workload-identity-managerCopy to Clipboard Copied! Toggle word wrap Toggle overflow Delete the namespace by running the following command:
oc delete ns zero-trust-workload-identity-manager
$ oc delete ns zero-trust-workload-identity-managerCopy to Clipboard Copied! Toggle word wrap Toggle overflow Delete the cluster role by running the following command:
oc delete clusterrole -l=app.kubernetes.io/name=zero-trust-workload-identity-manager
$ oc delete clusterrole -l=app.kubernetes.io/name=zero-trust-workload-identity-managerCopy to Clipboard Copied! Toggle word wrap Toggle overflow Delete the admission wehhook configuration by running the following command:
oc delete validatingwebhookconfigurations -l=app.kubernetes.io/name=zero-trust-workload-identity-manager
$ oc delete validatingwebhookconfigurations -l=app.kubernetes.io/name=zero-trust-workload-identity-managerCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Delete the custom resource definitions (CRDs) by running each of the following commands:
Delete the SPIRE Server CRD by running the following command:
oc delete crd spireservers.operator.openshift.io
$ oc delete crd spireservers.operator.openshift.ioCopy to Clipboard Copied! Toggle word wrap Toggle overflow Delete the SPIRE Agent CRD by running the following command:
oc delete crd spireagents.operator.openshift.io
$ oc delete crd spireagents.operator.openshift.ioCopy to Clipboard Copied! Toggle word wrap Toggle overflow Delete the SPIFFEE CSI Drivers CRD by running the following command:
oc delete crd spiffecsidrivers.operator.openshift.io
$ oc delete crd spiffecsidrivers.operator.openshift.ioCopy to Clipboard Copied! Toggle word wrap Toggle overflow Delete the SPIRE OIDC Discovery Provider CRD by running the following command:
oc delete crd spireoidcdiscoveryproviders.operator.openshift.io
$ oc delete crd spireoidcdiscoveryproviders.operator.openshift.ioCopy to Clipboard Copied! Toggle word wrap Toggle overflow Delete the SPIRE and SPIFFE cluster federated trust domains CRD by running the following command:
oc delete crd clusterfederatedtrustdomains.spire.spiffe.io
$ oc delete crd clusterfederatedtrustdomains.spire.spiffe.ioCopy to Clipboard Copied! Toggle word wrap Toggle overflow Delete the cluster SPIFFE IDs CRD by running the following command:
oc delete crd clusterspiffeids.spire.spiffe.io
$ oc delete crd clusterspiffeids.spire.spiffe.ioCopy to Clipboard Copied! Toggle word wrap Toggle overflow Delete the SPIRE and SPIFFE cluster static entries CRD by running the following command:
oc delete crd clusterstaticentries.spire.spiffe.io
$ oc delete crd clusterstaticentries.spire.spiffe.ioCopy to Clipboard Copied! Toggle word wrap Toggle overflow Delete the Zero Trust Workload Identity Manager CRD by running the following command:
oc delete crd zerotrustworkloadidentitymanagers.operator.openshift.io
$ oc delete crd zerotrustworkloadidentitymanagers.operator.openshift.ioCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
To verify that the resources have been deleted, replace each oc delete command with oc get, and then run the command. If no resources are returned, the deletion was successful.