Information Security 10 min read

Integrating HashiCorp Vault with Jenkins for Secure Credential Management

This guide demonstrates how to set up a Docker‑Compose environment with Vault and Jenkins, initialize Vault, configure AppRole authentication and policies, and integrate Jenkins pipelines to securely retrieve secrets, providing a practical DevOps solution for secret management.

DevOps Cloud Academy
DevOps Cloud Academy
DevOps Cloud Academy
Integrating HashiCorp Vault with Jenkins for Secure Credential Management

This article documents a practical DevOps tutorial from the DevOps Cloud Classroom (session 20230307) that shows how to replace Jenkins' built‑in credential manager with HashiCorp Vault for improved security.

Environment preparation : Using the provided docker-compose.yml file, start Vault and Jenkins containers. Note that Jenkins does not have persistent storage by default, so users should add volumes if needed. The Vault deployment follows HashiCorp's getting‑started guide, and a config.hcl file is created to configure Raft storage and a TCP listener.

storage "raft" {
  path    = "/opt/vault/data"
  node_id = "node1"
}

listener "tcp" {
  address     = "192.168.2.11:8200"
  tls_disable = "true"
}

api_addr    = "http://192.168.2.11:8200"
cluster_addr = "http://192.168.2.11:8201"
ui = true

The accompanying docker-compose.yml defines services for Vault (image hashicorp/vault:1.11 ) and Jenkins (image jenkins/jenkins:2.346.3-2-lts-jdk11 ) with appropriate network settings.

version: '3'

services:
  vault:
    image: hashicorp/vault:1.11
    volumes:
      - ./config.hcl:/opt/vault/config.hcl
      - ./data:/opt/vault/data
    cap_add:
      - IPC_LOCK
    entrypoint: vault server -config=/opt/vault/config.hcl
    restart: always
    ports:
      - "8200:8200"
    networks:
      vault:
        ipv4_address: 192.168.2.11
  jenkins:
    image: jenkins/jenkins:2.346.3-2-lts-jdk11
    restart: always
    ports:
      - "8080:8080"
    networks:
      vault:
        ipv4_address: 192.168.2.10

networks:
  vault:
    ipam:
      config:
        - subnet: 192.168.2.0/24

Start the stack with docker-compose up -d .

Vault initialization : Access the UI at http://192.168.1.200:8200 , create a Raft cluster, and generate unseal keys and the root token. The unseal process requires entering the three keys, after which the token is used for further operations. The CLI command vault operator init -address=http://127.0.0.1:8200 also performs initialization and displays the keys and token.

vault operator init -address=http://127.0.0.1:8200

Unseal Key 1: tYITaUd3UQEV81VdA1hePTnOcAoDZn
Unseal Key 2: TMcPF704GDyeiG1V917WKuaP
Unseal Key 3: 5dLP5p/KObNnLyALeamWnRV/
Unseal Key 4: 4u+fo4dvNI3IGZQFOBMg16NRou
Unseal Key 5: h1X6fbqBkqpUq6v6PFCn02UF1f

Initial Root Token: hvs.wgFIT4mBM3V7IlyKs0c2VWD5

Vault overview : Vault is an open‑source secret management tool that stores API keys, certificates, database credentials, SSH keys, etc. It supports multiple authentication methods (user/password, LDAP, GitHub, AWS, MFA) and offers features such as key rotation, encryption algorithms, audit logging, and cloud‑provider integrations.

AppRole authentication : To let Jenkins obtain a token programmatically, the tutorial enables the approle auth method, creates a policy granting read access to devops/data/jenkins/* , and defines an AppRole named jenkins with specific TTLs and token policies.

vault auth enable approle
path "devops/data/jenkins/*" {
  capabilities = ["read"]
}
vault write auth/approle/role/jenkins \
    secret_id_ttl=10m \
    token_num_uses=10 \
    token_ttl=20m \
    token_max_ttl=30m \
    secret_id_num_uses=40 \
    token_policies="jenkins-policy"

After creating the role, the role_id and secret_id are retrieved with vault write -f auth/approle/role/jenkins/secret-id and vault read auth/approle/role/jenkins/role-id .

# Example output
secret_id = ebacb8d9-b166-96b0-da90-dc6e357eb4a8
role_id   = 0c175bca-2ced-0fd9-efa7-61ca18aed637

Jenkins configuration : Install the HashiCorp Vault plugin, add a new credential of type "Vault App Role" using the obtained role_id and secret_id , and then create a pipeline that declares the secrets to fetch.

def secrets = [
    [path: 'devops/jenkins/gitlab', engineVersion: 2, secretValues: [
        [envVar: 'USERNAME', vaultKey: 'username'],
        [envVar: 'PASSWORD', vaultKey: 'password']
    ]]
]

def configuration = [
    vaultUrl: 'http://192.168.1.200:8200',
    vaultCredentialId: 'vault-app-role',
    engineVersion: 2
]

pipeline {
    agent any
    stages {
        stage('Test') {
            steps {
                script {
                    withVault([configuration: configuration, vaultSecrets: secrets]) {
                        sh "echo ${USERNAME}"
                        sh "echo ${PASSWORD}"
                    }
                }
            }
        }
    }
}

The test run shows successful retrieval of the secret values; common errors such as "Access denied" or mismatched variable names are addressed in the FAQ section.

Retrieving secret: devops/jenkins/gitlab
Access denied to Vault Secrets at 'devops/jenkins/gitlab'

Overall, the tutorial provides a step‑by‑step method for securely managing Jenkins credentials with Vault, illustrating Docker‑based deployment, Vault initialization, AppRole policy creation, and Jenkins pipeline integration.

DevOpsinformation securitySecrets ManagementVault
DevOps Cloud Academy
Written by

DevOps Cloud Academy

Exploring industry DevOps practices and technical expertise.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.