Well-Architected Framework
Secure Jenkins CI/CD secrets with HashiCorp Vault
Jenkins does not provide a single native workload identity model in the way that Kubernetes-native or hosted CI/CD platforms do. Jenkins controllers and agents can run on virtual machines, Kubernetes, or cloud-managed infrastructure, so the best Vault auth method depends on where the workload actually runs. Vault helps you reduce secret sprawl by moving external system credentials out of Jenkins credential stores and retrieving them at runtime with short-lived Vault tokens.
Traditional Jenkins credential management can still mask environment variables in logs, but it often leads to duplicated static credentials across controllers, folders, and pipelines. Authorization decisions also stay tied to Jenkins-managed credentials rather than Vault policies scoped to secret paths. Vault shifts authorization to externally authenticated identities and lets each pipeline retrieve the secrets it needs for the job it is running.
Architecture
The pipeline-to-Vault authentication flow follows the same high-level pattern regardless of auth method, but the verification step differs by method:
- The Jenkins agent presents an identity to Vault
- Vault validates that identity directly or through the relevant platform
- Vault maps the validated identity to a role
- Vault issues a token scoped to the policies attached to that role
Unlike CI/CD platforms that provide a native workload identity model (such as GitHub Actions OIDC or GitLab JWT), Jenkins has no single preferred auth method. These steps describe the general Vault authentication flow. The specific method your pipeline uses depends on where your Jenkins agents run. Refer to Where Jenkins runs affects auth method selection for details.

Where Jenkins runs affects auth method selection
Jenkins controllers usually orchestrate work, but Jenkins agents execute the pipeline steps that need secrets. For that reason, the agent runtime should determine the Vault auth method:
- If agents run on Kubernetes, use Kubernetes auth.
- If agents run on AWS, Azure, or GCP with native machine identity, use the corresponding cloud auth method.
- If agents run on long-lived VMs or bare metal in a private environment, use AppRole or TLS cert auth.
- If agents run on a platform that can issue OIDC-compatible workload tokens, use JWT/OIDC auth.
The Jenkins Vault plugin, the CloudBees HashiCorp Vault plugin, Jenkins credentials binding, and Vault Agent sidecars affect how agents retrieve secrets and mask them in pipelines. Those integrations do not change the underlying identity model. Pick the auth method based on the agent runtime, then decide how Jenkins should consume the resulting Vault token and secrets.
Authentication options
Because Jenkins can run in many environments, no single auth method fits every deployment. Use the auth method that matches the most authoritative identity the agent already has.
Jenkins integrates with Vault through the following patterns:
- The Jenkins Vault plugin provides declarative secret retrieval and masks retrieved secrets in pipeline logs, making it a practical option when teams want plugin-managed secret access.
- The CloudBees HashiCorp Vault plugin provides a similar pattern for CloudBees CI controllers that follow the same underlying Vault auth model and use the plugin as the Jenkins integration layer.
- Jenkins credentials binding can protect bootstrap material such as
VAULT_ADDR, wrapped AppRole tokens, and certificate paths when you call the Vault API or CLI directly. This is useful when jobs need flexible secret retrieval across different paths, structured secret layouts, or tenancy boundaries rather than plugin-managed bindings. - Vault Agent sidecars work well on ephemeral agents and reduce Jenkins plugin dependencies, which makes them a strong fit for containerized workloads, but file-rendered secrets are not automatically masked in Jenkins logs.
The following table summarizes when each auth method fits best.
| Auth method | Security posture | Credential lifecycle | Best suited for |
|---|---|---|---|
| JWT / OIDC | High; identity federates across trust boundaries | Token issued per job or workload, typically short-lived | Jenkins agents running on platforms that can issue OIDC-compatible workload tokens |
| Cloud provider auth methods | High when bound to native cloud identity | Short-lived cloud identity or metadata-backed login | Jenkins agents running on AWS, Azure, or GCP |
| Kubernetes | Highest for in-cluster | Short-lived projected token on modern Kubernetes; legacy patterns vary | Jenkins agents running as pods in Kubernetes |
| TLS Certificate | High; mutual authentication | Certificate with defined expiry; requires rotation process | Long-lived Jenkins agents where mTLS is already part of the security posture |
| AppRole | Moderate; requires secure secret ID delivery | Secret ID is single-use with response wrapping; RoleID is long-lived | Traditional self-hosted Jenkins agents where no stronger platform identity exists |
JWT/OIDC auth is the right choice when Jenkins agents run on a platform that can issue OIDC-compatible workload tokens. Jenkins itself does not issue these tokens natively, so this pattern depends on the surrounding platform, workload identity broker, or federation layer.
Role configuration
The security-critical configuration here is workload-specific role
constraints. bound_claims is the most flexible option, but you can also use
constraints such as bound_audiences and bound_subject. Without these
restrictions, a broader set of issuer-valid JWTs may authenticate than you
intend.
# Vault JWT role with workload-specific claim bindings
vault write auth/jwt/role/jenkins-deploy \
role_type=jwt \
bound_audiences="https://vault.example.com" \
bound_claims='{"sub": "jenkins-agent-prod", "pipeline": "deploy"}' \
user_claim=sub \
token_policies=jenkins-deploy-policy \
ttl=15m
Workflow configuration
The example assumes an external identity component writes a short-lived JWT to the agent filesystem before the build step runs.
pipeline {
agent any
environment {
WORKLOAD_JWT_FILE = '/var/run/jenkins/workload/token'
}
stages {
stage('Read secret from Vault') {
steps {
sh '''
JWT="$(cat "$WORKLOAD_JWT_FILE")"
VAULT_TOKEN="$(vault write -field=token auth/jwt/login role=jenkins-deploy jwt="$JWT")"
API_KEY="$(VAULT_TOKEN="$VAULT_TOKEN" vault kv get -field=key secret/ci/production/api)"
./deploy.sh
'''
}
}
}
}
The agent reads the short-lived workload token from the local filesystem, exchanges it for a Vault token, and retrieves only the secret required for the deployment.
Policy
The Vault policy for any role should follow least privilege. A pipeline that deploys to production should not be able to read staging secrets, and a staging pipeline should not be able to read production secrets.
An example Vault policy for a production deployment pipeline might look like this:
# Vault policy: scope to exactly the paths this pipeline needs
path "secret/data/ci/production/db" {
capabilities = ["read"]
}
# Deny access to everything else implicitly
The policy limits the job to the exact production secret path it needs. Use separate policies for other environments and job types so unrelated pipelines do not inherit broader access.
Dynamic secrets are a strong fit for Jenkins because the pipeline can retrieve database credentials, Terraform tokens, or cloud credentials immediately before use and discard the Vault token when the stage completes. This keeps short-lived credentials out of long-lived Jenkins credential stores while still fitting common Jenkins patterns such as plugin-based retrieval, direct API calls, or agent-local Vault workflows. In plugin-based pipelines, the Jenkins Vault plugin or CloudBees HashiCorp Vault plugin can surface these short-lived values as job-scoped environment variables while masking retrieved secrets in logs.
Security considerations
There are several Jenkins-specific security considerations you need to align with your organizational risk tolerance and operational constraints when designing your CI/CD secrets management strategy:
- Agent-scoped identities: Authenticate from the Jenkins agent that needs the secret, not from the controller on behalf of every job. This preserves workload-level separation and reduces lateral movement risk.
- Secret masking limitations: The Jenkins Vault plugin can mask retrieved secrets in logs, but direct API calls and Vault Agent-rendered files are not automatically masked. Avoid echoing secrets, dumping environments, or passing secrets to verbose commands.
- AppRole delivery controls: If you use AppRole, always deliver
secret_idvalues through single-use wrapping tokens. A rawsecret_idstored in Jenkins credentials becomes a bootstrap secret that must be protected like any other long-lived credential. - Shared agent isolation: Do not reuse workspaces, home directories, or cached token files across unrelated jobs on shared agents. A leftover Vault token on disk can expose another pipeline's secrets.
For a list of additional security considerations, refer to the CI/CD security considerations page.
Integrate HCP Vault Radar
Before migrating to Vault-based secrets management, Vault Radar can scan Jenkins pipeline definitions, shared libraries, and connected repositories for credentials stored as hardcoded values. This is particularly important in organizations that have accumulated years of Jenkinsfiles, helper scripts, and folder-level credentials across many teams.
After migration, Vault Radar can monitor your source code repositories continuously for new secret introductions — catching cases where developers add static tokens or passwords to Jenkinsfiles instead of retrieving them from Vault.
Refer to the HCP Vault Radar quick start tutorials to learn about HCP Vault Radar.
HashiCorp resources
Vault
- Read the Auth methods documentation to choose the right Vault authentication method for your Jenkins environment.
- Read the Response wrapping documentation to learn how to deliver single-use secret IDs securely.
- Read the Vault Agent documentation to configure Vault Agent for automatic secret injection in Jenkins pipelines.
- Follow the Dynamic secrets: database credentials tutorials to generate short-lived database credentials from Vault.
- Follow the Generate cloud provider credentials with Vault tutorial to issue temporary cloud provider credentials for pipeline jobs.
HCP Vault Radar
- Read What is HCP Vault Radar for an overview of how Vault Radar scans for exposed secrets.
- Follow the Get started with HCP Vault Radar tutorial to enable continuous scanning for your repositories.
External resources
- Read the Jenkins HashiCorp Vault plugin documentation to configure Vault secret retrieval in Jenkins pipelines.
- Read the CloudBees HashiCorp Vault plugin documentation for CloudBees CI-specific Vault integration guidance.
- Read the Jenkins Pipeline syntax reference to understand pipeline configuration options used in the examples.
- Read Secure CI/CD pipeline secrets in Jenkins on Kubernetes for example code demonstrating Vault-based secret management for Jenkins on Kubernetes.
Next steps
In this section of managing CI/CD secrets, you learned how to choose Vault auth methods for Jenkins based on where agents run and how to scope secrets to individual jobs. Secure Jenkins CI/CD secrets with HashiCorp Vault is part of the Secure systems pillar.
If your Jenkins agents already run on Kubernetes or cloud-managed compute, prefer those native platform identities over AppRole to reduce bootstrap secret distribution. If you're deciding between static and dynamic secret models for pipeline use, review CI/CD dynamic and static secrets.