DevOps Peach

DevOps & CI/CD · Jenkins Pipeline · Lesson 2 of 5

Jenkins Credentials

Store secrets in the credentials store under an ID, use them through credentials() or withCredentials so Jenkins masks them in logs; never hard-code them or interpolate them with Groovy.

Practice interactively →

Credentials are stored (encrypted) in Jenkins; pipelines only reference them by ID.

Type Used for
Secret text API tokens, GitHub PATs
Username and password Registries, Git over HTTPS
Secret file kubeconfig, .env files
SSH Username with private key SSH to servers, Git over SSH
Certificate PKCS#12 with an optional password
Docker Host Certificate Authentication Connecting to a Docker daemon over TLS

Scope: global (all of Jenkins), one folder/item, or one user.

pipeline {
  agent any
  environment {
    REGISTRY = credentials('registry-creds')   // creates REGISTRY, REGISTRY_USR, REGISTRY_PSW
  }
  stages {
    stage('Push') {
      steps {
        sh 'echo "$REGISTRY_PSW" | docker login -u "$REGISTRY_USR" --password-stdin registry.example.com'
        withCredentials([sshUserPrivateKey(credentialsId: 'deploy-key', keyFileVariable: 'KEY')]) {
          sh 'ssh -i "$KEY" deploy@192.0.2.10 uptime'
        }
      }
    }
  }
}
flowchart LR
  S[("Credentials store<br/>encrypted")] -- "credentials('id')" --> P["Pipeline step"]
  P --> L["Console log: ****"]

The Jenkins CLI needs authentication too: read user:apitoken from a file with -auth @FILE instead of typing the token on the command line (it leaks into shell history and ps).

Traps: hard-coding tokens in the Jenkinsfile; echo-ing secrets; using a password instead of an API token for the CLI.

Command Meaning
java -jar jenkins-cli.jar -s http://localhost:8080/ -auth @/home/fresher/.jenkins-cli-auth who-am-i Check the CLI is authenticated

Binding credentials inside a stage

withCredentials limits a secret to a block of steps instead of the whole pipeline:

withCredentials([usernamePassword(credentialsId: 'registry-cred',
                                  usernameVariable: 'REG_USER',
                                  passwordVariable: 'REG_PASS')]) {
  sh 'echo "$REG_PASS" | docker login registry.example.com -u "$REG_USER" --password-stdin'
}

Other bindings include string(...) for secret text, file(...) for secret files such as a kubeconfig, and sshUserPrivateKey(...). The SSH Agent plugin's sshagent(['deploy-key']) { sh 'ssh deploy@192.0.2.20 ...' } loads a key for one block of SSH commands.

Where Jenkins keeps secrets

Credentials are encrypted on disk under JENKINS_HOME with keys in secrets/. Anyone who can copy JENKINS_HOME (including backups) and the secrets folder can decrypt them, so protect backups as carefully as the server. Restrict who can view or update credentials with folder-scoped credentials and role-based permissions.

Better than static secrets

Approach Benefit
Short-lived tokens via OIDC (cloud workload identity) No long-lived cloud keys in Jenkins at all
External secret stores (HashiCorp Vault, AWS Secrets Manager, Azure Key Vault plugins) Central rotation and audit
Separate credentials per environment A leaked dev token cannot deploy to production

Avoiding leaks

Masking only hides the exact secret string; a transformed value (base64, part of a URL, printed with set -x) can still appear in logs. Never echo secrets, avoid sh "..." with Groovy interpolation, and disable shell tracing around sensitive commands. If a secret does leak into a log, rotate it immediately: deleting the build log is not enough.

Configuration as code

The Configuration as Code (JCasC) plugin defines Jenkins settings, including credential definitions that read values from environment variables or a secret store, in a YAML file. This lets you rebuild a Jenkins controller reproducibly instead of clicking through the UI.

Practice interactively →