---
title: SPIRE UpstreamAuthority plugins for Zero Trust Workload Identity Manager
---

# SPIRE UpstreamAuthority plugins for Zero Trust Workload Identity Manager {#zero-trust-manager-plugins}

To integrate SPIFFE Runtime Environment (SPIRE) with your existing certificate management infrastructure and keep Secure Production Identity Framework for Everyone (SPIFFE) (SPIFFE) identity standards, configure SPIRE Server with UpstreamAuthority plugins. These plugins obtain intermediate signing certificates from external certificate authorities.

You can configure SPIRE Server to use one of the following UpstreamAuthority plugins:

**cert-manager UpstreamAuthority plugin**
:   Integrates SPIRE with cert-manager Operator for Red Hat OpenShift running in Kubernetes or OpenShift Container Platform clusters. The cert-manager Operator for Red Hat OpenShift instance can use various issuer types to provide signing certificates for SPIRE intermediate CAs.

**Vault UpstreamAuthority plugin**
:   Integrates SPIRE with the HashiCorp Vault Public Key Infrastructure (PKI) secrets engine. This plugin supports many Vault authentication methods and enables SPIRE to use Vault’s security features for certificate management.

Choose the plugin that matches your certificate management infrastructure. You can configure only one UpstreamAuthority plugin at a time. The `SpireServer` CR rejects configurations that specify both `certManager` and `vault` simultaneously.

## About the cert-manager upstream authority plugin {#zero-trust-manager-plugins-cert-manager-about_zero-trust-manager-plugins}

The cert-manager Operator for Red Hat OpenShift upstream authority plugin connects SPIRE Server to cert-manager Operator for Red Hat OpenShift for automated intermediate certificate provisioning.

When you configure this plugin, SPIRE Server creates a `CertificateRequest` resource in the cluster. The configured Issuer or ClusterIssuer signs the request and the certificate. The SPIRE Server then uses the signed intermediate certificate to issue workload identities.

### How the cert-manager plugin works {#cert-manager-plugin-workflow_zero-trust-manager-plugins}

1. SPIRE Server generates a certificate signing request for an intermediate signing certificate.
2. The plugin creates a `CertificateRequest` in the configured namespace.
3. The `CertificateRequest` references the configured Issuer or ClusterIssuer.
4. cert-manager Operator for Red Hat OpenShift signs the request.
5. SPIRE Server retrieves the signed certificate and CA bundle from the `CertificateRequest`.

### Requirements {#cert-manager-plugin-requirements_zero-trust-manager-plugins}

cert-manager Operator for Red Hat OpenShift
:   cert-manager Operator for Red Hat OpenShift must be installed and running in the cluster.

Issuer
:   You must configure an `Issuer` or `ClusterIssuer` that can sign intermediate CA certificates.

Permissions
:   On OpenShift Container Platform, Zero Trust Workload Identity Manager grants the SPIRE Server `ServiceAccount` permission to manage `CertificateRequest` resources when `spec.upstreamAuthority.certManager` is configured. Prepare the Issuer and namespace before you configure the `SpireServer` CR.

Supported issuers
:   The `Issuer` must support signing certificate requests for intermediate CAs.

## Preparing cert-manager for SPIRE Server {#zero-trust-manager-preparing-plugin-use_zero-trust-manager-plugins}

Install cert-manager Operator for Red Hat OpenShift and create an `Issuer` or `ClusterIssuer` that can sign SPIRE intermediate certificates. After you complete this procedure, configure `spec.upstreamAuthority.certManager` on the `SpireServer` CR.

**Prerequisites**

- You are logged in to the cluster with the `cluster-admin` role.
- You have installed Zero Trust Workload Identity Manager or plan to install it after cert-manager Operator for Red Hat OpenShift is ready.

**Procedure**

1. Create a self-signed bootstrap `ClusterIssuer`:

   1. Save the following manifest as `selfsigned-bootstrap.yaml`:

      ```yaml
      apiVersion: cert-manager.io/v1
      kind: ClusterIssuer
      metadata:
        name: selfsigned-bootstrap
      spec:
        selfSigned: {}
      ```
   2. Apply the `ClusterIssuer` by running the following command:

      ```terminal
      $ oc apply -f selfsigned-bootstrap.yaml
      ```
2. Use the bootstrap `ClusterIssuer` to issue a root CA certificate into a Secret:

   1. Save the following manifest as `spire-root-ca.yaml`:

      ```yaml
      apiVersion: cert-manager.io/v1
      kind: Certificate
      metadata:
        name: spire-root-ca
        namespace: cert-manager
      spec:
        isCA: true
        secretName: spire-root-ca-secret
        issuerRef:
          name: selfsigned-bootstrap
          kind: ClusterIssuer
        commonName: "SPIRE Root CA"
        duration: 87600h
      ```
   2. Apply the `Certificate` by running the following command:

      ```terminal
      $ oc apply -f spire-root-ca.yaml
      ```
3. Create a CA `Issuer` that references the root CA Secret:

   1. Save the following manifest as `spire-ca-issuer.yaml`:

      ```yaml
      apiVersion: cert-manager.io/v1
      kind: Issuer
      metadata:
        name: spire-ca
        namespace: cert-manager
      spec:
        ca:
          secretName: spire-root-ca-secret
      ```
   2. Apply the `Issuer` by running the following command:

      ```terminal
      $ oc apply -f spire-ca-issuer.yaml
      ```

**Verification**

- Confirm that the bootstrap `ClusterIssuer`, root CA `Certificate`, and signing `Issuer` are ready by running the following commands:

  ```terminal
  $ oc get clusterissuer selfsigned-bootstrap
  ```

  ```terminal
  $ oc get certificate spire-root-ca -n cert-manager
  ```

  ```terminal
  $ oc get issuer spire-ca -n cert-manager
  ```

**Additional resources**
{._additional-resources}

- [cert-manager Operator for Red Hat OpenShift](https://docs.redhat.com/en/documentation/openshift_container_platform/latest/html/security_and_compliance/cert-manager-operator-for-red-hat-openshift)

## Configuring the cert-manager upstream authority plugin {#zero-trust-manager-config-cert-manager_zero-trust-manager-plugins}

Configure SPIRE Server to obtain intermediate signing certificates from cert-manager Operator for Red Hat OpenShift by setting `spec.upstreamAuthority.certManager` on the `SpireServer` custom resource. Zero Trust Workload Identity Manager generates SPIRE Server configuration and reconciles the SPIRE Server \`StatefulSet.

**Prerequisites**

- You have installed Zero Trust Workload Identity Manager and deployed a `SpireServer` CR.
- You have completed preparing cert-manager Operator for Red Hat OpenShift for SPIRE Server use, including creating an `Issuer` or `ClusterIssuer`.

**Procedure**

1. Export the current `SpireServer` CR to a file by running the following command:

   ```terminal
   $ oc get spireserver cluster -o yaml > SpireServer-cert-manager.yaml
   ```
2. In the `SpireServer-cert-manager.yaml`, add the `upstreamAuthority` section under `spec:`:

   ```yaml
   apiVersion: operator.openshift.io/v1alpha1
   kind: SpireServer
   metadata:
     name: cluster
   spec:
     logLevel: "info"
     logFormat: "text"
     jwtIssuer: "https://oidc-discovery.apps.cluster.example.com"
     caValidity: "24h"
     defaultX509Validity: "1h"
     defaultJWTValidity: "5m"
     jwtKeyType: "rsa-2048"
     caSubject:
       country: "US"
       organization: "Example Corporation"
       commonName: "SPIRE Server CA"
     persistence:
       size: "5Gi"
       accessMode: "ReadWriteOnce"
       storageClass: "gp3-csi"
     datastore:
       databaseType: "sqlite3"
       connectionString: "/run/spire/data/datastore.sqlite3"
       tlsSecretName: ""
       maxOpenConns: 100
       maxIdleConns: 10
       connMaxLifetime: 0
       disableMigration: "false"
     upstreamAuthority:
       certManager:
         namespace: cert-manager
         issuerName: spire-ca
         issuerKind: Issuer
         issuerGroup: cert-manager.io
   ```

   where:

   `spec.upstreamAuthority.certManager.namespace`
   :   Specifies the namespace where SPIRE Server creates `CertificateRequest` resources. For a namespace-scoped `Issuer`, this must match the `Issuer` namespace. For a `ClusterIssuer`, any namespace is valid.

   `spec.upstreamAuthority.certManager.issuerName`
   :   Specifies the name of the `Issuer` or `ClusterIssuer`.

   `spec.upstreamAuthority.certManager.issuerKind`
   :   Specifies the `Issuer` or `ClusterIssuer`. The default is `Issuer`.

   `spec.upstreamAuthority.certManager.issuerGroup`
   :   Specifies the API group of the issuer. The default is `cert-manager.io`.

   > [!NOTE]
   > On OpenShift Container Platform, SPIRE Server uses its in-cluster `ServiceAccount`. Zero Trust Workload Identity Manager grants `CertificateRequest` permissions when `spec.upstreamAuthority.certManager` is configured.
3. Apply the updated CR by running the following command:

   ```terminal
   $ oc apply -f SpireServer-cert-manager.yaml
   ```
4. Wait for Zero Trust Workload Identity Manager to reconcile the SPIRE Server by running the following command:

   ```terminal
   $ oc rollout status statefulset/spire-server -n zero-trust-workload-identity-manager
   ```

**Verification**

1. Verify that SPIRE Server is healthy and that logs show the `UpstreamAuthority` plugin loaded by running the following commands:

   ```terminal
   $ oc exec -n zero-trust-workload-identity-manager statefulset/spire-server -c spire-server -- \
       /opt/spire/bin/spire-server healthcheck
   ```

   ```terminal
   $ oc logs statefulset/spire-server -n zero-trust-workload-identity-manager -c spire-server --tail=50
   ```
2. Confirm that a cert-manager-signed intermediate certificate is present by running the following command:

   ```terminal
   $ oc exec -n zero-trust-workload-identity-manager statefulset/spire-server -c spire-server -- \
       /opt/spire/bin/spire-server bundle show
   ```

## cert-manager upstream authority plugin reference {#zero-trust-manager-cert-manager-plugin-ref_zero-trust-manager-plugins}

This reference describes `spec.upstreamAuthority.certManager` fields on the `SpireServer` custom resource and how Zero Trust Workload Identity Manager uses them to request intermediate certificates from cert-manager Operator for Red Hat OpenShift. Use it when you configure or troubleshoot the cert-manager Operator for Red Hat OpenShift UpstreamAuthority plugin and need field descriptions or defaults.

### SpireServer CR fields {#cert-manager-plugin-spireserver-cr-reference_zero-trust-manager-plugins}

Configure cert-manager Operator for Red Hat OpenShift upstream authority under `spec.upstreamAuthority.certManager`. Zero Trust Workload Identity Manager generates the SPIRE Server configuration from these fields.

| Field | Description |
| --- | --- |
| `namespace` | Required. Namespace where SPIRE Server creates `CertificateRequest` resources. |
| `issuerName` | Required. Name of the Issuer or ClusterIssuer. |
| `issuerKind` | Optional. `Issuer` or `ClusterIssuer`. The default is `Issuer`. |
| `issuerGroup` | Optional. API group of the issuer. The default is `cert-manager.io`. |

> [!NOTE]
> On OpenShift Container Platform, SPIRE Server uses its in-cluster `ServiceAccount`. Zero Trust Workload Identity Manager grants permissions to create, get, list, and delete `CertificateRequest` resources when `spec.upstreamAuthority.certManager` is configured.

## Troubleshooting the cert-manager Operator for Red Hat OpenShift upstream authority plugin {#zero-trust-manager-cert-troubleshooting_zero-trust-manager-plugins}

Resolve the most common cert-manager Operator for Red Hat OpenShift upstream authority failures on OpenShift Container Platform.

### Quick reference {#zero-trust-manager-cert-quick-reference_zero-trust-manager-plugins}

| Symptom or error | Likely cause | Section |
| --- | --- | --- |
| `certificaterequests... is forbidden` | Missing permissions or wrong `namespace` | [cert-manager-plugin-permission-issuer_zero-trust-manager-plugins](#cert-manager-plugin-permission-issuer_zero-trust-manager-plugins) |
| `issuer ... not found` | Wrong `issuerName`, `issuerKind`, or issuer namespace | [cert-manager-plugin-permission-issuer_zero-trust-manager-plugins](#cert-manager-plugin-permission-issuer_zero-trust-manager-plugins) |
| Issuer not `READY` | Issuer misconfiguration | [cert-manager-plugin-permission-issuer_zero-trust-manager-plugins](#cert-manager-plugin-permission-issuer_zero-trust-manager-plugins) |
| `CertificateRequest` not approved or denied | Approval policy or approver configuration | [cert-manager-plugin-certificaterequest_zero-trust-manager-plugins](#cert-manager-plugin-certificaterequest_zero-trust-manager-plugins) |
| UpstreamAuthority fails to load in SPIRE Server logs | Invalid or incomplete `spec.upstreamAuthority.certManager` | [cert-manager-plugin-certificaterequest_zero-trust-manager-plugins](#cert-manager-plugin-certificaterequest_zero-trust-manager-plugins) |

### Permission and issuer errors {#cert-manager-plugin-permission-issuer_zero-trust-manager-plugins}

**Permission errors**

- Confirm `spec.upstreamAuthority.certManager.namespace` matches the namespace where SPIRE Server creates `CertificateRequest` resources.
- After you configure `spec.upstreamAuthority.certManager`, verify that Zero Trust Workload Identity Manager updated the SPIRE Server role-based access control (RBAC) and the SPIRE Server pod restarted.

**Issuer errors**

- Verify `issuerName` and `issuerKind` on the `SpireServer` CR match an existing Issuer or ClusterIssuer.
- For a namespace-scoped `Issuer`, the Issuer must exist in the namespace referenced by `CertificateRequest` resources or in the namespace where the issuer is defined, depending on your issuer configuration.
- Check that the Issuer reports `READY=True`:

  ```terminal
  $ oc get issuer,clusterissuer -A
  $ oc describe issuer spire-ca -n cert-manager
  ```

### SPIRE Server errors {#cert-manager-plugin-certificaterequest_zero-trust-manager-plugins}

**SPIRE Server errors**

- Confirm that `namespace`, `issuerName`, and `issuerKind` are set under `spec.upstreamAuthority.certManager`.
- Review SPIRE Server logs by running the following command:

```terminal
$ oc logs statefulset/spire-server -n zero-trust-workload-identity-manager -c spire-server --tail=100
```

## About the SPIRE Vault UpstreamAuthority plugin {#zero-trust-manager-about-vault-plugin_zero-trust-manager-plugins}

The Vault UpstreamAuthority plugin connects SPIRE Server to the HashiCorp Vault PKI secrets engine for automated intermediate CA certificate signing. Use this plugin when you centralize PKI in Vault and want SPIRE to obtain intermediate signing certificates through Vault policies and authentication method.

The SPIRE Vault UpstreamAuthority plugin provides the following features:

- Integration with HashiCorp Vault PKI secrets engine as an upstream certificate authority
- Support for `Kubernetes auth` Vault authentication methods
- Automatic signing of SPIRE intermediate CA certificates
- Vault Enterprise namespace support
- Secure certificate management using Vault’s security features

> [!IMPORTANT]
> The Vault UpstreamAuthority plugin does not support the `PublishJWTKey` remote procedure call (RPC) and is not appropriate for use in nested SPIRE topologies where JSON Web Token SPIFFE Verifiable Identity Document (SVID) (JWT-SVIDs) are used.

### Supported authentication method {#spire-vault-authentication-methods_zero-trust-manager-plugins}

The Vault UpstreamAuthority plugin supports only the following authentication methods for connecting to Vault:

Kubernetes authentication
:   Uses Kubernetes service account tokens to authenticate to Vault.

### Prerequisites and requirements {#spire-vault-requirements_zero-trust-manager-plugins}

Before configuring the Vault UpstreamAuthority plugin, ensure the following requirements are met:

Vault PKI secrets engine
:   A running HashiCorp Vault instance with the PKI secrets engine enabled at a configured mount point (default: `pki`). The PKI secrets engine must have a root CA certificate configured for signing intermediate certificates.

Vault policy
:   A Vault policy that grants the `update` capability for the `pki/root/sign-intermediate` endpoint, attached to the credentials SPIRE Server uses.

Authentication credentials
:   Valid credentials for one of the supported authentication methods, associated with the Vault signing policy.

TTL configuration
:   SPIRE Server `ca_ttl` must not exceed the Vault PKI secrets engine maximum lease TTL.

Network connectivity
:   SPIRE Server must reach the Vault server over the network and trust the Vault TLS certificate when TLS is enabled.

Kubernetes RBAC (when using Kubernetes authentication)
:   A `ServiceAccount` for SPIRE Server bound to the Vault Kubernetes auth role. The SPIRE Server `ServiceAccount` requires no additional RBAC. However, the Vault `ServiceAccount` must have `system:auth-delegator` permissions to validate projected tokens via the Kubernetes `TokenReview` API.

## Configuring the SPIRE Vault UpstreamAuthority plugin {#zero-trust-manager-spire-vault-config_zero-trust-manager-plugins}

Configure SPIRE Server to obtain intermediate signing certificates from HashiCorp Vault by setting `spec.upstreamAuthority.vault` on the `SpireServer` custom resource (CR). Zero Trust Workload Identity Manager generates the SPIRE Server configuration, mounts Vault credentials into the SPIRE Server pod, and reconciles the SPIRE Server `StatefulSet`.

On OpenShift Container Platform, the `SpireServer` CR supports Vault authentication only through the Kubernetes auth method. Zero Trust Workload Identity Manager mounts a projected SPIRE Server `ServiceAccount` token and, when configured, a Vault CA certificate Secret at fixed paths inside the pod.

**Prerequisites**

- You have installed Zero Trust Workload Identity Manager and deployed a `SpireServer` CR.
- You have a running HashiCorp Vault instance with the PKI secrets engine enabled at your mount point (default: `pki`) and a root CA configured to sign intermediate certificates.
- You have a Vault policy that grants the `update` capability on `<pki_mount>/root/sign-intermediate`.
- You have configured the Vault Kubernetes authentication method and created a Vault role bound to the SPIRE Server `ServiceAccount`. For example, `spire-server` in the `zero-trust-workload-identity-manager` namespace.
- The value of `spec.caValidity` on the `SpireServer` CR is less than or equal to the maximum lease Time to Live (TTL) configured on the Vault PKI secrets engine.
- If Vault uses a private or custom TLS certificate authority, you have a PEM-encoded CA certificate available to store in a Kubernetes `Secret`.

**Procedure**

1. Export the current `SpireServer` CR to a file by running the following command:

   ```terminal
   $ oc get spireserver cluster -o yaml > SpireServer-vault.yaml
   ```
2. In `SpireServer-vault.yaml`, add the `upstreamAuthority` section from the following example under `spec:`:

   ```yaml
   apiVersion: operator.openshift.io/v1alpha1
   kind: SpireServer
   metadata:
     name: cluster
   spec:
     logLevel: "info"
     logFormat: "text"
     jwtIssuer: "https://oidc-discovery.apps.cluster.example.com"
     caValidity: "24h"
     defaultX509Validity: "1h"
     defaultJWTValidity: "5m"
     jwtKeyType: "rsa-2048"
     caSubject:
       country: "US"
       organization: "Example Corporation"
       commonName: "SPIRE Server CA"
     persistence:
       size: "5Gi"
       accessMode: "ReadWriteOnce"
       storageClass: "gp3-csi"
     datastore:
       databaseType: "sqlite3"
       connectionString: "/run/spire/data/datastore.sqlite3"
       tlsSecretName: ""
       maxOpenConns: 100
       maxIdleConns: 10
       connMaxLifetime: 0
       disableMigration: "false"
     upstreamAuthority:
       vault:
         vaultAddr: "https://vault.example.com:8200"
         pkiMountPoint: "pki"
         caCertSecretRef:
           name: vault-ca-cert
           key: ca.crt
         k8sAuth:
           k8sAuthMountPoint: "kubernetes"
           k8sAuthRoleName: "spire-server"
           audience: "vault"
         vaultNamespace: "vault-namespace" # optional
   ```

   > [!NOTE]
   > For in-cluster Vault over HTTP, set `vaultAddr` to the in-cluster service URL, such as `http://vault.vault.svc:8200`, and omit `caCertSecretRef`.
   >
   > Include `caCertSecretRef` only when Vault TLS is signed by a custom CA. Omit it when Vault uses a public CA.

   where:

   `spec.caValidity`
   :   Specifies the SPIRE Server CA validity. Must be less than or equal to the Vault PKI `max_lease_ttl`. Zero Trust Workload Identity Manager maps this value to SPIRE `ca_ttl`.

   `spec.upstreamAuthority.vault.vaultAddr`
   :   Specifies the URL of the Vault server.

   `spec.upstreamAuthority.vault.pkiMountPoint`
   :   Specifies the Vault PKI secrets engine mount path. Default: `pki`.

   `spec.upstreamAuthority.vault.caCertSecretRef`
   :   Optional. Specifies the `Secret` reference when Vault TLS is signed by a custom CA. Zero Trust Workload Identity Manager mounts the Secret at `/run/spire/upstream-ca/ca.crt`.

   `spec.upstreamAuthority.vault.k8sAuth.k8sAuthRoleName`
   :   Specifies the Vault Kubernetes auth role name.

   `spec.upstreamAuthority.vault.k8sAuth.k8sAuthMountPoint`
   :   Specifies the Vault Kubernetes auth mount path. The default is `kubernetes`.

   `spec.upstreamAuthority.vault.k8sAuth.audience`
   :   Specifies the projected `ServiceAccount` token audience. This must match the Vault role. The default is `vault`.

   `spec.upstreamAuthority.vault.vaultNamespace`
   :   Optional. Specifies the Vault namespace name.
3. Apply the updated CR by running the following command:

   ```terminal
   $ oc apply -f SpireServer-vault.yaml
   ```
4. Wait for Zero Trust Workload Identity Manager to reconcile the SPIRE Server by running the following command:

   ```terminal
   $ oc rollout status statefulset/spire-server -n zero-trust-workload-identity-manager
   ```

**Verification**

1. Verify that SPIRE Server is healthy and that logs show the UpstreamAuthority plugin loaded by running the following commands:

   ```terminal
   $ oc exec -n zero-trust-workload-identity-manager statefulset/spire-server -c spire-server -- \
       /opt/spire/bin/spire-server healthcheck
   $ oc logs statefulset/spire-server -n zero-trust-workload-identity-manager -c spire-server --tail=50
   ```

   ```terminal {title="Example output"}
   Server is healthy.
   time="2026-04-07T10:15:30Z" level=info msg="Upstream authority loaded" subsystem_name=ca
   time="2026-04-07T10:15:31Z" level=info msg="Server CA activated" certificate_fingerprint="ABC123..."
   ```
2. Confirm that a Vault-signed intermediate certificate is present by running the following command:

   ```terminal
   $ oc exec -n zero-trust-workload-identity-manager statefulset/spire-server -c spire-server -- \
       /opt/spire/bin/spire-server bundle show
   ```

## SPIRE Vault UpstreamAuthority plugin reference {#zero-trust-manager-spire-vault-plugin-ref_zero-trust-manager-plugins}

Reference for `spec.upstreamAuthority.vault` on the `SpireServer` CR and the Vault signing policy SPIRE Server requires.

### SpireServer CR fields {#spire-vault-spireserver-cr-reference_zero-trust-manager-plugins}

Configure Vault upstream authority under `spec.upstreamAuthority.vault`. Zero Trust Workload Identity Manager generates SPIRE Server configuration from these fields.

| Field | Description |
| --- | --- |
| `vaultAddr` | Required. Vault server URL. Use HTTPS for external endpoints; HTTP is permitted for in-cluster services. |
| `pkiMountPoint` | PKI secrets engine mount path. Default: `pki`. |
| `caCertSecretRef` | Optional Secret reference in the `zero-trust-workload-identity-manager` namespace. Use when Vault TLS is signed by a custom CA. Zero Trust Workload Identity Manager mounts the key at `/run/spire/upstream-ca/ca.crt`. |
| `insecureSkipVerify` | Optional. Accepts any Vault server certificate when `true`. Default: `false`. Do not enable `insecureSkipVerify` in production. This setting disables TLS certificate verification and exposes the connection to man-in-the-middle attacks. Troubleshooting only. |
| `vaultNamespace` | Optional. Vault Enterprise namespace. |
| `k8sAuth.k8sAuthMountPoint` | Vault Kubernetes auth mount path. Default: `kubernetes`. |
| `k8sAuth.k8sAuthRoleName` | Required. Vault role bound to the `spire-server` ServiceAccount. |
| `k8sAuth.audience` | Token audience for the projected ServiceAccount token. Default: `vault`. Must match the `bound_audiences` configured on the Vault role. |

> [!NOTE]
> On OpenShift Container Platform, the `SpireServer` CR supports Vault Kubernetes authentication only. Zero Trust Workload Identity Manager mounts a projected `ServiceAccount` token at `/var/run/secrets/tokens/vault`.
>
> Ensure that `spec.caValidity` does not exceed the Vault PKI `max_lease_ttl`.

### Required Vault policy {#spire-vault-policy-reference_zero-trust-manager-plugins}

The Vault Kubernetes auth role must include a policy with `update` on the intermediate signing path:

```text
path "pki/root/sign-intermediate" {
  capabilities = ["update"]
}
```

Replace `pki` with your PKI mount point when different.

## Troubleshooting SPIRE Vault UpstreamAuthority plugin {#zero-trust-manager-spire-vault-troubleshooting_zero-trust-manager-plugins}

Resolve the most common SPIRE Vault upstream authority failures on OpenShift Container Platform.

### Quick reference {#zero-trust-manager-vault-quick-reference_zero-trust-manager-plugins}

| Symptom or error | Likely cause | Section |
| --- | --- | --- |
| Connection refused, timeout, or unreachable Vault | Wrong `vaultAddr` or network path from the SPIRE Server pod | [spire-vault-troubleshooting-connection-tls_zero-trust-manager-plugins](#spire-vault-troubleshooting-connection-tls_zero-trust-manager-plugins) |
| `x509: certificate signed by unknown authority` | Missing or invalid `caCertSecretRef` Secret | [spire-vault-troubleshooting-connection-tls_zero-trust-manager-plugins](#spire-vault-troubleshooting-connection-tls_zero-trust-manager-plugins) |
| Vault `403` or Kubernetes auth failure | Vault role, ServiceAccount binding, or signing policy misconfiguration | [spire-vault-troubleshooting-authentication_zero-trust-manager-plugins](#spire-vault-troubleshooting-authentication_zero-trust-manager-plugins) |
| `requested TTL ... exceeds max_lease_ttl` | `caValidity` exceeds the Vault PKI limit | [spire-vault-troubleshooting-ttl_zero-trust-manager-plugins](#spire-vault-troubleshooting-ttl_zero-trust-manager-plugins) |

### Connection and TLS errors {#spire-vault-troubleshooting-connection-tls_zero-trust-manager-plugins}

**Connection failures**

- Verify `spec.upstreamAuthority.vault.vaultAddr` on the `SpireServer` CR.
- Confirm the SPIRE Server pod can reach Vault from the `zero-trust-workload-identity-manager` namespace.
- For in-cluster Vault, use the Kubernetes service URL, such as `http://vault.vault.svc:8200`.

**TLS failures**

- When Vault uses a custom CA, set `caCertSecretRef` to a Secret in the `zero-trust-workload-identity-manager` namespace with a PEM-encoded CA certificate.
- Confirm the `Secret` name and key match `caCertSecretRef`.
- Omit `caCertSecretRef` only for a public CA or in-cluster HTTP.
- Do not use `insecureSkipVerify: true` in production.

### Authentication and signing errors {#spire-vault-troubleshooting-authentication_zero-trust-manager-plugins}

SPIRE Server uses Vault Kubernetes authentication with the `spire-server` ServiceAccount.

Check the following:

- `k8sAuth.k8sAuthRoleName` on the `SpireServer` CR matches the Vault Kubernetes auth role.
- The Vault role binds to ServiceAccount `spire-server` in namespace `zero-trust-workload-identity-manager`.
- The role policy grants `update` on `<pki_mount>/root/sign-intermediate`.
- `pkiMountPoint` matches the PKI secrets engine mount in Vault.
- `k8sAuth.audience` matches the Vault role when you changed the default from `vault`.

Review SPIRE Server logs:

```terminal
$ oc logs statefulset/spire-server -n zero-trust-workload-identity-manager -c spire-server --tail=100
```

### TTL mismatch errors {#spire-vault-troubleshooting-ttl_zero-trust-manager-plugins}

`spec.caValidity` on the `SpireServer` CR must be less than or equal to the Vault PKI `max_lease_ttl`.

- Reduce `caValidity` on the `SpireServer` CR, or increase the Vault PKI limit with `vault secrets tune -max-lease-ttl=...`.

For Vault Enterprise namespace errors, set `spec.upstreamAuthority.vault.vaultNamespace` to the correct namespace path.
