In this post, we’ll show you how to replace a Jenkins-managed SSH private key with one managed by HashiCorp Vault using AppRole authentication.
What You Gain
- Centralized secret management
- Audit logging of access
- Real-time secret updates across jobs
- Secrets usable across tools (not Jenkins-only)
Vault doesn’t automatically make your pipelines more secure — access control depends on how you scope credentials.
Prerequisites
- A working Vault OSS server (from this guide)
- Jenkins with the HashiCorp Vault Plugin installed
- Jenkins user with permission to configure credentials and pipelines
- Store Your SSH Key in Vault
Enable the KV v2 secrets engine if not already:
vault secrets enable -path=secret kv-v2
Store your SSH private key:
vault kv put secret/jenkins/gerrit/maksonlee ssh_key=- <<EOF
-----BEGIN OPENSSH PRIVATE KEY-----
<your-key>
-----END OPENSSH PRIVATE KEY-----
EOF
- Create a Vault Policy and AppRole
- Create a policy
Save to jenkins-policy.hcl:
path "secret/data/jenkins/*" {
  capabilities = ["read"]
}
Apply it:
vault policy write jenkins-policy jenkins-policy.hcl
- Create an AppRole
vault auth enable approle
vault write auth/approle/role/jenkins-role \
  token_policies="jenkins-policy" \
  token_ttl=1h \
  token_max_ttl=4h
- Get Role ID and Secret ID
vault read auth/approle/role/jenkins-role/role-id
vault write -f auth/approle/role/jenkins-role/secret-id
- Configure Vault in Jenkins
- Add Vault App Role Credential
Manage Jenkins → Credentials → (Global) → Add Credentials
| Field | Value | 
|---|---|
| Kind | Vault App Role Credential | 
| Scope | Global | 
| Role ID | From Vault CLI | 
| Secret ID | From Vault CLI | 
| Path | approle | 
| ID | vault-approle | 
| Description | Vault AppRole for Gerrit SSH key access | 
- (Optional) Global Plugin Config
Manage Jenkins → System → Vault Plugin
- Vault URL: https://vault.maksonlee.com
- Vault Credential: vault-approle
- Use the Secret in Your Pipeline
withVault([
  vaultSecrets: [[
    path: 'secret/jenkins/gerrit/maksonlee',
    engineVersion: 2,
    secretValues: [[envVar: 'GERRIT_SSH_KEY', vaultKey: 'ssh_key']]
  ]]
]) {
  sh '''
    mkdir -p ~/.ssh
    chmod 700 ~/.ssh
    echo "$GERRIT_SSH_KEY" > ~/.ssh/id_rsa
    chmod 600 ~/.ssh/id_rsa
    ssh-keyscan -p 29418 -H gerrit.maksonlee.com >> ~/.ssh/known_hosts
  '''
  sh """
    repo init -u ${manifestUrl} -b ${branch}
    repo sync -c -j1
    source build/envsetup.sh
    lunch ${lunchTarget}
    m
  """
}
Security Comparison
| Capability | Jenkins Credential | Vault AppRole Credential | 
|---|---|---|
| Folder/job isolation | ✅ Yes | ✅ Yes (via folder credential) | 
| Revocation | ❌ Manual | ✅ Vault CLI/API | 
| Rotation | ❌ Manual | ✅ Reissue Secret ID | 
| Audit logging | ❌ No | ✅ Vault logs reads | 
| Tool reuse | ❌ Jenkins only | ✅ Works with other systems | 
With folder-scoped credentials, Vault and Jenkins both offer strong isolation.
Vault adds audit logs, rotation, and centralized control.
