Jenkins Credentials and Secrets Management

Credentials management is how Jenkins stores and uses sensitive information — passwords, API tokens, SSH keys, and certificates — without exposing them in your code or build logs.

Think of Jenkins Credentials as a secure vault inside Jenkins. You store secrets in the vault once, give each one a name tag (ID), and reference them by that tag in your pipelines. The actual secret values never appear in your Jenkinsfile or console output.

Why Never Put Secrets in a Jenkinsfile

Bad practice — hardcoded secret:
  stage('Deploy') {
      steps {
          sh "aws s3 sync dist/ s3://my-bucket --access-key AKIAIOSFODNN7 --secret-key wJalrXUtnFEMI"
      }
  }

Problems:
  1. Secret is visible in Git history to anyone with repo access
  2. Secret appears in build logs
  3. Rotating the key requires editing every Jenkinsfile that uses it
  4. If repo is accidentally made public, secret is exposed

Safe practice — use Jenkins Credentials:
  withCredentials([usernamePassword(
      credentialsId: 'aws-s3-creds',
      usernameVariable: 'AWS_KEY',
      passwordVariable: 'AWS_SECRET'
  )]) {
      sh "aws s3 sync dist/ s3://my-bucket --access-key ${AWS_KEY} --secret-key ${AWS_SECRET}"
  }

Benefits:
  1. Secret never appears in code or Git
  2. Jenkins masks the value in logs: ****
  3. Rotate by updating one record in Jenkins — no code changes
  4. Access controlled by Jenkins security

Types of Credentials Jenkins Supports

Credential TypeWhat It StoresCommon Use
Username with passwordA username and password pairDocker registry login, GitHub HTTPS, database
Secret textA single string valueAPI tokens, Slack tokens, auth tokens
Secret fileAn entire filekubeconfig files, .env files, certificates
SSH Username with private keySSH private key + optional passphraseSSH into servers, Git over SSH
CertificateA PKCS#12 keystore fileSSL certificates, code signing
AWS CredentialsAWS Access Key ID and SecretAWS API calls, S3, EC2

How to Add a Credential

Step 1: Go to Manage Jenkins → Credentials
Step 2: Click on a domain (e.g., "global")
Step 3: Click "Add Credentials" on the left
Step 4: Choose the credential type
Step 5: Fill in the fields:
        - Kind: Username with password (or other type)
        - Scope: Global (or System for internal use)
        - Username: your-username
        - Password: your-password-or-token
        - ID: github-token        ← This is what you use in the Jenkinsfile
        - Description: GitHub PAT for CI builds
Step 6: Click "Create"

The ID field is what you reference in your pipeline. Choose a clear, descriptive ID so team members understand which credential it is.

Credential Scope

Jenkins credentials have a scope that controls where they are accessible.

Global scope:
  Available to all jobs on this Jenkins instance
  Use for: shared credentials needed by many jobs

System scope:
  Available only to Jenkins itself (not to jobs)
  Use for: credentials Jenkins uses to manage nodes or plugins

Folder scope (requires Folders plugin):
  Available only to jobs inside a specific folder
  Use for: team-specific secrets that should not be
           accessible to other teams' jobs

Using Credentials in Pipelines

The withCredentials block injects credentials into the steps inside it. Jenkins automatically masks the secret values in the console output.

Using a Secret Text Credential

withCredentials([string(
    credentialsId: 'slack-token',
    variable: 'SLACK_TOKEN'
)]) {
    sh "curl -X POST -H 'Authorization: Bearer ${SLACK_TOKEN}' ..."
}

Using a Username and Password Credential

withCredentials([usernamePassword(
    credentialsId: 'docker-hub-creds',
    usernameVariable: 'DOCKER_USER',
    passwordVariable: 'DOCKER_PASS'
)]) {
    sh "docker login -u ${DOCKER_USER} -p ${DOCKER_PASS}"
    sh "docker push myimage:latest"
}

Using an SSH Key Credential

withCredentials([sshUserPrivateKey(
    credentialsId: 'deploy-ssh-key',
    keyFileVariable: 'SSH_KEY_FILE',
    usernameVariable: 'SSH_USER'
)]) {
    sh "ssh -i ${SSH_KEY_FILE} ${SSH_USER}@server 'systemctl restart app'"
    sh "scp -i ${SSH_KEY_FILE} target/app.jar ${SSH_USER}@server:/opt/app/"
}

Using a Secret File Credential

withCredentials([file(
    credentialsId: 'kubeconfig-prod',
    variable: 'KUBECONFIG_FILE'
)]) {
    sh "kubectl --kubeconfig=${KUBECONFIG_FILE} apply -f k8s/production/"
    sh "kubectl --kubeconfig=${KUBECONFIG_FILE} rollout status deployment/myapp"
}

Using Credentials in the Environment Block

For credentials needed throughout a pipeline, inject them in the environment block using the credentials() helper instead of wrapping every stage in withCredentials.

pipeline {
    agent any

    environment {
        // For a "Username with password" credential,
        // Jenkins auto-creates two variables:
        //   GITHUB_CREDS_USR = the username
        //   GITHUB_CREDS_PSW = the password/token
        GITHUB_CREDS = credentials('github-token')

        // For a "Secret text" credential
        SONAR_TOKEN = credentials('sonarqube-token')
    }

    stages {
        stage('Checkout') {
            steps {
                git url: "https://${GITHUB_CREDS_USR}:${GITHUB_CREDS_PSW}@github.com/org/repo.git"
            }
        }
        stage('Code Quality') {
            steps {
                sh "sonar-scanner -Dsonar.login=${SONAR_TOKEN}"
            }
        }
    }
}

Masked Credentials in Logs

Jenkins automatically replaces credential values with **** in the console output. Even if a step accidentally prints the value, Jenkins masks it.

Console output with masking:

  + docker login -u deployer -p ****
  Login Succeeded

  + curl -H 'Authorization: Bearer ****' https://api.example.com/deploy
  {"status": "deployed"}

Credential Rotation

When a password or token expires or is compromised, update it in one place — the Jenkins Credentials store. All jobs that reference the credential ID automatically use the new value on the next run. No code changes needed.

Rotation process:
  1. Generate a new token in GitHub/AWS/Slack/etc.
  2. Go to Manage Jenkins → Credentials
  3. Find the credential by its ID
  4. Click "Update" and paste the new value
  5. Save

All pipelines now use the new credential automatically.

Key Points

  • Never put passwords, tokens, or keys directly in Jenkinsfiles or shell commands.
  • Jenkins Credentials store secrets securely — reference them by ID in your pipeline.
  • Use withCredentials to inject secrets into steps; Jenkins masks the values in logs.
  • Different credential types cover passwords, SSH keys, API tokens, files, and certificates.
  • Rotating a credential updates it once in Jenkins — all pipelines using that ID pick up the new value automatically.

Leave a Comment