Jenkins Integration¶
Problem Statement¶
Managing credentials in Jenkins presents unique challenges:
- Manual credential creation through Jenkins UI is time-consuming
- Difficult to track which credentials exist and their purpose
- No standardized approach to credential lifecycle management
- Synchronizing credentials across Jenkins instances requires manual work
- Lack of audit trail for credential creation and rotation
SecretZero solves this by automating Jenkins credential provisioning with declarative configuration, supporting various credential types (string, username/password, SSH keys, certificates).
Prerequisites¶
- SecretZero installed with Jenkins support:
pip install secretzero[cicd] - Jenkins API Token
- Jenkins credentials plugin installed (typically included by default)
- Admin or credentials create/update permissions
Authentication Setup¶
1. Generate Jenkins API Token¶
- Log in to Jenkins
- Click your username (top right) → Configure
- Scroll to "API Token" section
- Click "Add new Token" → Generate
- Copy the generated token
2. Configure Environment¶
export JENKINS_URL=https://jenkins.example.com
export JENKINS_USERNAME=admin
export JENKINS_TOKEN=your_jenkins_api_token_here
Configuration¶
Basic Credentials¶
Create Secretfile.yml:
version: '1.0'
metadata:
project: my-application
owner: devops-team
variables:
jenkins_url: ${JENKINS_URL}
jenkins_user: ${JENKINS_USERNAME}
providers:
jenkins:
kind: jenkins
auth:
kind: token
config:
url: ${jenkins_url}
username: ${jenkins_user}
token: ${JENKINS_TOKEN}
secrets:
# String credential (API key)
- name: api_key
kind: random_string
config:
length: 32
charset: alphanumeric
targets:
# Local development
- provider: local
kind: file
config:
path: .env
format: dotenv
merge: true
# Jenkins string credential
- provider: jenkins
kind: jenkins_credential
config:
credential_id: api-key-prod
description: Production API Key
credential_type: string
# Username/Password credential
- name: database_password
kind: random_password
config:
length: 32
special: true
exclude_characters: '"@/\`'
targets:
- provider: jenkins
kind: jenkins_credential
config:
credential_id: db-credentials
description: Database Credentials
credential_type: username_password
username: dbuser
# Secret text (similar to string)
- name: jwt_secret
kind: random_string
config:
length: 64
charset: alphanumeric
targets:
- provider: jenkins
kind: jenkins_credential
config:
credential_id: jwt-secret
description: JWT Signing Secret
credential_type: secret_text
SSH Key Credentials¶
secrets:
- name: deploy_ssh_key
kind: ssh_keypair
config:
key_type: rsa
key_size: 4096
targets:
# Store private key in Jenkins
- provider: jenkins
kind: jenkins_credential
config:
credential_id: deploy-ssh-key
description: Deployment SSH Key
credential_type: ssh_username_private_key
username: deploy
passphrase: "" # Optional passphrase
# Store public key locally
- provider: local
kind: file
config:
path: deploy_key.pub
format: raw
extract_field: public_key
Certificate Credentials¶
secrets:
- name: client_certificate
kind: certificate
config:
cert_type: client
key_size: 2048
common_name: client.example.com
targets:
- provider: jenkins
kind: jenkins_credential
config:
credential_id: client-cert
description: Client Certificate
credential_type: certificate
password: ${CERT_PASSWORD}
Step-by-Step Instructions¶
1. Validate Configuration¶
secretzero validate
# Expected output:
# ✓ Configuration is valid
# ✓ Found 3 secrets
# ✓ Jenkins provider configured correctly
2. Test Provider Connectivity¶
secretzero test
# Expected output:
# ✓ Testing Jenkins provider...
# ✓ Authentication successful
# ✓ Jenkins version: 2.401.1
# ✓ Credentials plugin available
# ✓ All providers ready
3. Preview Changes¶
secretzero sync --dry-run
# Expected output:
# [DRY RUN] Would create:
# ✓ api_key → Jenkins Credential (api-key-prod) [string]
# ✓ database_password → Jenkins Credential (db-credentials) [username_password]
# ✓ jwt_secret → Jenkins Credential (jwt-secret) [secret_text]
4. Sync Credentials to Jenkins¶
secretzero sync
# Expected output:
# ✓ Generated api_key
# ✓ Created Jenkins Credential: api-key-prod (string)
# ✓ Generated database_password
# ✓ Created Jenkins Credential: db-credentials (username_password)
# ✓ Generated jwt_secret
# ✓ Created Jenkins Credential: jwt-secret (secret_text)
# ✓ Updated .gitsecrets.lock
5. Verify in Jenkins¶
Navigate to Jenkins: - Dashboard → Manage Jenkins → Manage Credentials - Click on "(global)" domain - Verify your credentials appear in the list
Using Credentials in Jenkins Pipelines¶
Declarative Pipeline¶
pipeline {
agent any
environment {
// Bind string credential to environment variable
API_KEY = credentials('api-key-prod')
}
stages {
stage('Deploy') {
steps {
// API_KEY is automatically available
sh 'echo "API Key: $API_KEY"'
// Username/Password credential
withCredentials([
usernamePassword(
credentialsId: 'db-credentials',
usernameVariable: 'DB_USER',
passwordVariable: 'DB_PASS'
)
]) {
sh '''
echo "Database User: $DB_USER"
./deploy.sh
'''
}
}
}
}
}
Scripted Pipeline¶
node {
stage('Deploy') {
// String credential
withCredentials([string(credentialsId: 'api-key-prod', variable: 'API_KEY')]) {
sh "echo API Key: $API_KEY"
}
// Username/Password credential
withCredentials([
usernamePassword(
credentialsId: 'db-credentials',
usernameVariable: 'DB_USER',
passwordVariable: 'DB_PASS'
)
]) {
sh './connect-database.sh $DB_USER $DB_PASS'
}
// SSH key credential
withCredentials([
sshUserPrivateKey(
credentialsId: 'deploy-ssh-key',
keyFileVariable: 'SSH_KEY',
usernameVariable: 'SSH_USER'
)
]) {
sh 'ssh -i $SSH_KEY $SSH_USER@server.example.com "deploy.sh"'
}
}
}
Freestyle Job Configuration¶
- Configure job → Build Environment
- Enable "Use secret text(s) or file(s)"
- Add binding:
- Secret text: Select credential → Variable name
- Username and password: Select credential → Username/Password variables
- Use in build steps via environment variables
Advanced Scenarios¶
Multi-Instance Setup¶
Sync credentials across multiple Jenkins instances:
version: '1.0'
variables:
jenkins_prod_url: https://jenkins-prod.example.com
jenkins_staging_url: https://jenkins-staging.example.com
providers:
jenkins_prod:
kind: jenkins
auth:
kind: token
config:
url: ${jenkins_prod_url}
username: ${JENKINS_USERNAME}
token: ${JENKINS_PROD_TOKEN}
jenkins_staging:
kind: jenkins
auth:
kind: token
config:
url: ${jenkins_staging_url}
username: ${JENKINS_USERNAME}
token: ${JENKINS_STAGING_TOKEN}
secrets:
- name: api_key
kind: random_string
config:
length: 32
targets:
# Production instance
- provider: jenkins_prod
kind: jenkins_credential
config:
credential_id: api-key
description: API Key
credential_type: string
# Staging instance
- provider: jenkins_staging
kind: jenkins_credential
config:
credential_id: api-key
description: API Key
credential_type: string
Folder-Scoped Credentials¶
Store credentials in specific Jenkins folders:
secrets:
- name: project_api_key
kind: random_string
config:
length: 32
targets:
- provider: jenkins
kind: jenkins_credential
config:
credential_id: api-key
description: Project API Key
credential_type: string
folder: "MyProject/Production" # Folder path
Credential Rotation Pipeline¶
Automate credential rotation:
// Jenkinsfile
pipeline {
agent any
triggers {
// Run every 90 days
cron('0 0 */90 * *')
}
stages {
stage('Rotate Credentials') {
steps {
sh '''
pip install secretzero[cicd]
secretzero rotate --force
secretzero sync
'''
}
}
stage('Verify Rotation') {
steps {
sh 'secretzero show api_key'
}
}
stage('Commit Lockfile') {
steps {
sh '''
git config user.name "Jenkins Bot"
git config user.email "jenkins@example.com"
git add .gitsecrets.lock
git commit -m "chore: rotate Jenkins credentials"
git push origin main
'''
}
}
}
}
AWS Credentials¶
Manage AWS access keys in Jenkins:
secrets:
- name: aws_secret_key
kind: random_string
config:
length: 40
charset: alphanumeric
targets:
- provider: jenkins
kind: jenkins_credential
config:
credential_id: aws-credentials
description: AWS Credentials
credential_type: aws_credentials
access_key: ${AWS_ACCESS_KEY_ID}
# secret_key will be generated
Best Practices¶
1. Use Descriptive Credential IDs¶
Follow naming conventions:
config:
credential_id: prod-api-key # Clear and environment-specific
description: Production API Key for External Service
2. Scope Credentials Appropriately¶
Use folder-scoped credentials for project isolation:
3. Rotate Credentials Regularly¶
Implement rotation policies:
secrets:
- name: api_key
kind: random_string
rotation_period: 90d
config:
length: 32
targets:
- provider: jenkins
kind: jenkins_credential
config:
credential_id: api-key
4. Track Changes in Lockfile¶
Commit lockfile for audit trail:
5. Use Appropriate Credential Types¶
Match credential type to use case: - String/Secret Text: API keys, tokens - Username/Password: Database credentials, service accounts - SSH Key: SSH access, Git over SSH - Certificate: TLS client certificates - File: Configuration files, service account keys
Troubleshooting¶
Authentication Failed¶
Problem: Error: Jenkins authentication failed
Solutions:
# Verify environment variables
echo $JENKINS_URL
echo $JENKINS_USERNAME
echo $JENKINS_TOKEN
# Test authentication manually
curl -u "$JENKINS_USERNAME:$JENKINS_TOKEN" \
"$JENKINS_URL/api/json"
# Regenerate API token
# Jenkins → User → Configure → API Token → Add new Token
Permission Denied¶
Problem: Error: You do not have permission to create credentials
Solutions:
- Requires Administer or Credentials → Create permission
- Check permissions:
- Manage Jenkins → Manage Users → [Your User] → Configure
- Or contact Jenkins administrator for permission grant
Credential Not Appearing in Job¶
Problem: Job can't find the credential
Solutions:
// 1. Verify credential ID matches exactly
withCredentials([string(credentialsId: 'api-key-prod', variable: 'KEY')]) {
// Must match Jenkins credential ID
}
// 2. Check credential scope (global vs folder)
// Credentials in folders only available to jobs in that folder
// 3. Verify credential type matches usage
withCredentials([string(...)]) // For string/secret_text
withCredentials([usernamePassword(...)]) // For username_password
withCredentials([sshUserPrivateKey(...)]) // For SSH keys
Credentials Plugin Not Found¶
Problem: Error: Credentials plugin not available
Solutions:
# Install credentials plugin
# Manage Jenkins → Manage Plugins → Available
# Search for "Credentials Plugin" and install
# Or use Jenkins CLI
java -jar jenkins-cli.jar -s $JENKINS_URL \
install-plugin credentials \
-username $JENKINS_USERNAME \
-password $JENKINS_TOKEN
Connection Timeout¶
Problem: Error: Connection to Jenkins timed out
Solutions:
# Check Jenkins URL is accessible
curl -I $JENKINS_URL
# For self-hosted Jenkins, verify network access
ping jenkins.example.com
# Check firewall rules allow access on Jenkins port (default 8080)
# For HTTPS, verify certificate
curl -v https://jenkins.example.com
Complete Example¶
Full production-ready configuration:
version: '1.0'
metadata:
project: production-app
owner: devops-team
compliance:
- soc2
variables:
jenkins_url: https://jenkins.example.com
providers:
jenkins:
kind: jenkins
auth:
kind: token
config:
url: ${jenkins_url}
username: ${JENKINS_USERNAME}
token: ${JENKINS_TOKEN}
policies:
credential_rotation:
kind: rotation
require_rotation_period: true
max_age: 90d
severity: error
enabled: true
secrets:
# Database credentials
- name: database_creds
kind: random_password
rotation_period: 90d
config:
length: 32
special: true
targets:
- provider: jenkins
kind: jenkins_credential
config:
credential_id: prod-db-creds
description: Production Database Credentials
credential_type: username_password
username: prod_user
# API keys
- name: stripe_api_key
kind: static
rotation_period: 90d
config:
default: ${STRIPE_API_KEY}
targets:
- provider: jenkins
kind: jenkins_credential
config:
credential_id: stripe-api-key
description: Stripe API Key
credential_type: secret_text
# SSH deployment key
- name: deploy_key
kind: ssh_keypair
rotation_period: 180d
config:
key_type: ed25519
targets:
- provider: jenkins
kind: jenkins_credential
config:
credential_id: deploy-ssh-key
description: Deployment SSH Key
credential_type: ssh_username_private_key
username: deploy
# AWS credentials
- name: aws_secret
kind: random_string
rotation_period: 90d
config:
length: 40
targets:
- provider: jenkins
kind: jenkins_credential
config:
credential_id: aws-credentials
description: AWS Credentials
credential_type: aws_credentials
access_key: ${AWS_ACCESS_KEY_ID}
Deploy:
# Validate
secretzero validate
# Check compliance
secretzero policy
# Preview
secretzero sync --dry-run
# Deploy
secretzero sync
# Verify in Jenkins UI
# Manage Jenkins → Manage Credentials → (global)
Next Steps¶
- GitHub Actions - GitHub integration
- GitLab CI/CD - GitLab integration
- Multi-Cloud Setup - Sync to cloud providers