HashiCorp Vault
This integration guide is for configuring Vault to trust workload identity that has already been published through oidc.pub. Vault uses the JWT auth method to validate the external issuer's discovery document and JWKS, then exchanges a verified workload JWT for a Vault token.
If the issuer is still private, start with the relevant setup guide first, such as Vault, GitLab CI, or Kubernetes.
1. Enable the JWT auth method
Mount Vault's JWT auth method if you do not already have one. Each auth mount can trust one verification configuration, so if you want to trust multiple oidc.pub issuers, mount separate JWT backends at different paths.
vault auth enable jwtvault auth enable jwt2. Configure Vault to trust the oidc.pub issuer
Point the JWT auth method at the public discovery endpoint hosted on oidc.pub. Replace k8s-prod.oidc.pub with the issuer you want Vault to trust.
vault write auth/jwt/config \
oidc_discovery_url="https://k8s-prod.oidc.pub" \
bound_issuer="https://k8s-prod.oidc.pub" \
oidc_client_id="" \
oidc_client_secret=""vault write auth/jwt/config \
oidc_discovery_url="https://k8s-prod.oidc.pub" \
bound_issuer="https://k8s-prod.oidc.pub" \
oidc_client_id="" \
oidc_client_secret=""For direct JWT validation, Vault does not need an OIDC client ID or client secret. It only needs the discovery document and issuer binding.
3. Create a role for the trusted workload
Create a JWT role that matches the workload's expected aud and sub claims, then map successful logins to Vault policies.
vault write auth/jwt/role/k8s-workload \
role_type="jwt" \
user_claim="sub" \
bound_audiences="vault" \
bound_subject="system:serviceaccount:default:my-app" \
policies="app-read" \
ttl="1h"vault write auth/jwt/role/k8s-workload \
role_type="jwt" \
user_claim="sub" \
bound_audiences="vault" \
bound_subject="system:serviceaccount:default:my-app" \
policies="app-read" \
ttl="1h"Starting with Vault 1.17, if the incoming JWT contains an audience, the role's bound_audiences must exactly match at least one of the token's aud values.
4. Log in with the workload JWT
Pass the published workload JWT to Vault. If the token signature, issuer, audience, and subject all match, Vault returns a Vault token with the policies attached to the role.
vault write auth/jwt/login \
role="k8s-workload" \
jwt="$OIDC_TOKEN"vault write auth/jwt/login \
role="k8s-workload" \
jwt="$OIDC_TOKEN"Provider-specific claim examples
The exact aud and sub values depend on the workload issuer. Match the role to the actual claims in the token you expect Vault to accept.
Kubernetes
Kubernetes projected service account tokens typically use a subject of the form system:serviceaccount:<namespace>:<name>. Set the audience in the projected token to the value Vault should trust, such as vault.
# Role example
vault write auth/jwt/role/k8s-workload \
role_type="jwt" \
user_claim="sub" \
bound_audiences="vault" \
bound_subject="system:serviceaccount:default:my-app" \
policies="app-read"# Role example
vault write auth/jwt/role/k8s-workload \
role_type="jwt" \
user_claim="sub" \
bound_audiences="vault" \
bound_subject="system:serviceaccount:default:my-app" \
policies="app-read"GitLab CI
GitLab job tokens usually encode pipeline context in the subject. Restrict Vault to the exact branch, tag, or environment pattern you want to trust.
# Role example
vault write auth/jwt/role/gitlab-main \
role_type="jwt" \
user_claim="sub" \
bound_audiences="https://gitlab.oidc.pub" \
bound_subject="project_path:mygroup/myproject:ref_type:branch:ref:main" \
policies="ci-read"# Role example
vault write auth/jwt/role/gitlab-main \
role_type="jwt" \
user_claim="sub" \
bound_audiences="https://gitlab.oidc.pub" \
bound_subject="project_path:mygroup/myproject:ref_type:branch:ref:main" \
policies="ci-read"HashiCorp Vault
If another Vault cluster issues the workload identity, configure that source Vault role to mint an audience this Vault expects, then match the trusted entity identifier in bound_subject.
# Role example
vault write auth/jwt/role/external-vault \
role_type="jwt" \
user_claim="sub" \
bound_audiences="vault" \
bound_subject="vault-entity-id" \
policies="vault-federation"# Role example
vault write auth/jwt/role/external-vault \
role_type="jwt" \
user_claim="sub" \
bound_audiences="vault" \
bound_subject="vault-entity-id" \
policies="vault-federation"Related guides
Use the setup guides to publish the private issuer first, then return here to configure Vault as the relying system.
Relevant setup guides: Vault, GitLab CI, and Kubernetes.