Well-Architected Framework
Jenkins
Jenkins uses plugins to integrate with third-party tools. Traditionally, you would manage Jenkins secrets for pipelines with Jenkins credential management in the Jenkins Controller. This approach binds all secrets to environment variables, and masks these variables when they appear in pipeline logs. However, this conventional approach can lead to secret sprawl with external system credentials (like tokens, database credentials, and other pipeline secrets) duplicated in Jenkins. The Jenkins Controller also relies on the Jenkins user database for role based access control (RBAC) rather than implementing more secure granular access control lists (ACLs) based on credential paths.
Use a best practice approach
A more secure method to inject and use credentials during pipeline runs is to use API integration with Vault for each pipeline step. When you use this approach in your pipelines, you gain the following:
- Vault manages authorization for stored secrets based on externally authenticated identities.
- The Jenkins Credentials Plugin secures the Vault authentication process.
- Vault auth methods (like AppRole or JWT) benefit from the Credentials Management plugin's binding capabilities.
- Authenticated pipelines can make API calls to Vault, and retrieve just the necessary secrets for completing specific jobs.
This integration enables stronger security controls, while reducing secret sprawl throughout your organization.
Use the Jenkins Vault plugin and other methods
Depending on your security requirements for protecting secrets in Jenkins pipeline logs, you can choose from several approaches to authenticate to Vault:
Jenkins Vault plugin
The Jenkins Vault plugin serves as an authentication helper, and provides secret binding during pipeline execution. This approach offers significant advantages:
- Automatically masks any secret retrieved from Vault in the pipeline logs
- Provides a streamlined and declarative syntax for secret retrieval
- Seamlessly integrates with Jenkins credentials management
CloudBees CI Vault plugin
CloudBees CI provides a shared, centrally managed, self-service experience for development teams running Jenkins either on-premise or in the cloud. You can use the CloudBees HashiCorp Vault Plugin to manage the lifecycle of your Cloud Bees controller static or dynamic Vault credentials. Learn how to install and configure the HashiCorp Vault plugin with the Jenkins CLI or Plugin Manager in the CloudBees HashiCorp Vault Plugin documentation.
Here are some example code snippets that demonstrate how to use secrets in CloudBees CI pipelines.
Add a secret for the username and password auth method:
withCredentials([usernamePassword(credentialsId: 'vault-creds', passwordVariable: 'PASS', usernameVariable: 'USER')]) {
sh 'echo USER=$USER'
sh 'echo PASS=$PASS'
}
Use a static secret from a Vault key/value secrets engine:
withCredentials([string(credentialsId: 'vault-creds', variable: 'TOKEN')]) {
sh 'echo TOKEN=$TOKEN'
}
Consult the CloudBees HashiCorp Vault Plugin documentation for more details.
External resources:
Credentials binding with REST API
You can use Jenkins credentials binding to securely manage environment variables, like VAULT_TOKEN
, VAULT_ADDR
, and VAULT_NAMESPACE
. The credentials binding solution provides these features in your pipelines:
- Masks environment variables in the pipeline logs
- Allows you to make REST API calls to Vault with the bound credentials
- Offers more flexibility for complex secret retrieval patterns where an application might need several types of credentials from different paths, and which use function abstraction, structured secret organization, secret composition, and Enterprise namespaces.
Vault Agent sidecar
When you implement Vault Agent directly on Jenkins Agents, you create a powerful pattern for accessing secrets across pipelines. Some advantages from using this approach include:
- Remove the need for extra Jenkins plugins
- Works well with ephemeral agents using a Vault Agent sidecar configuration
- Simplifies secret retrieval for containerized workloads
Note
Secrets retrieved from Vault with this method can appear in pipeline logs without adding specific masking configuration.
The approach that best suits your environment depends on your organization's security requirements, infrastructure configuration, and operational preferences.
How to use Vault dynamic secrets in Jenkins
You can use the Jenkins Vault plugin to retrieve and protect dynamic Vault secrets in the pipeline logs.
These secrets include for example: Terraform API tokens, GCP keys, and database credentials. You can do this in the
pipeline as code definition by specifying the
engine version 1
specification of the plugin, like in the following example:
stage ('My Stage') {
steps {
withVault(configuration: [
vaultCredentialId: "my-vault-creds",
vaultUrl: "http://vault:8200"],
vaultSecrets: [
[
path: "terraform/creds/tfe-role",
engineVersion: 1,
secretValues: [
[envVar: "tfe_token", vaultKey: "token"]
]
]) {
curl -H "Authorization: Bearer ${env.tfe_token}" \
-H "Content-Type: application/vnd.api+json" \
-X GET \
"https://app.terraform.io/api/v2/workspaces/"
}
}
}
If you do not use the Jenkins Vault plugin, it is possible to do a REST API call to Vault and mask the
VAULT_TOKEN
environment variable in the pipeline logs. Masking the
VAULT_TOKEN
environment variable is possible using the Credentials Management in Jenkins.
You can also use the Vault Agent plugin to manage the token caching, avoiding the usage of any plugin in that case.
An external process executed in the Jenkins Agent, like an admin pipeline or init process, (it can be an admin or operator pipeline, or an init process),
can manage the Vault login that retrieves the token value specified in the
VAULT_TOKEN
environment variable and puts it in a Jenkins credential.
Community resources:
- Learn how to secure CI/CD pipeline secrets in Jenkins on Kubernetes in this project by David CaƱadillas. Code examples
Next steps
In this section of managing CI/CD secrets, you learned about Jenkins and Vault integration. Jenkins and Vault integration is part of the Secure systems pillar.