Jenkins is a high-value target. It has access to your source code, deployment credentials, and production environments. A compromised Jenkins instance can lead to supply chain attacks, data breaches, and unauthorized deployments.
Yet many Jenkins installations run with default configurations that leave them vulnerable. This checklist covers the security controls that matter, organized by priority.
Critical: Authentication and Access Control
Enable Security
This seems obvious, but we still encounter Jenkins instances with security disabled.
- Navigate to Manage Jenkins > Security
- Enable Security Realm (authentication)
- Enable Authorization (access control)
- Save and verify you can still log in
// Check via Groovy console (disable after use)
println Jenkins.instance.isUseSecurity()
// Should return: true
Use External Authentication
Do not rely on Jenkins’ built-in user database for production. Integrate with your organization’s identity provider.
Recommended options:
- LDAP plugin for Active Directory integration
- SAML plugin for SSO with Okta, Azure AD, etc.
- GitHub Authentication plugin for GitHub-based teams
- Google Login plugin for Google Workspace
Configuration example for LDAP:
# JCasC configuration
jenkins:
securityRealm:
ldap:
configurations:
- server: "ldap://ldap.example.com"
rootDN: "dc=example,dc=com"
userSearchBase: "ou=users"
userSearch: "uid={0}"
groupSearchBase: "ou=groups"
Implement Role-Based Access Control
The Role-based Authorization Strategy plugin provides granular access control.
Define roles based on job function:
| Role | Permissions |
|---|---|
| Admin | Full system access |
| Developer | Build jobs, view logs, no system config |
| Deployer | Trigger deployments, approve releases |
| Viewer | Read-only access to build results |
# JCasC configuration for role-based auth
jenkins:
authorizationStrategy:
roleBased:
roles:
global:
- name: "admin"
permissions:
- "Overall/Administer"
assignments:
- "admin-group"
- name: "developer"
permissions:
- "Job/Build"
- "Job/Read"
- "Job/Workspace"
assignments:
- "dev-group"
Enforce Strong Password Policies
If using Jenkins’ built-in database (not recommended for production):
- Install the Password Strength plugin
- Configure minimum password requirements
- Enable account lockout after failed attempts
Better: Use external authentication with your organization’s password policies.
Critical: Credentials Management
Use the Credentials Plugin Properly
Never store credentials in:
- Jenkinsfiles
- Environment variables in job config
- Shared library code
- Build parameters
Always use the Credentials plugin:
// Correct way to use credentials
pipeline {
agent any
stages {
stage('Deploy') {
steps {
withCredentials([
usernamePassword(
credentialsId: 'deploy-creds',
usernameVariable: 'DEPLOY_USER',
passwordVariable: 'DEPLOY_PASS'
)
]) {
sh './deploy.sh'
}
}
}
}
}
Scope Credentials Appropriately
Credentials can be scoped to:
- System - Available to Jenkins system operations
- Global - Available to all jobs (avoid unless necessary)
- Folder - Available only to jobs in that folder
Use folder-scoped credentials to limit blast radius:
Jenkins/
├── Production/ # Folder with prod credentials
│ ├── deploy-app-a/
│ └── deploy-app-b/
└── Development/ # Folder with dev credentials
├── build-app-a/
└── build-app-b/
Rotate Credentials Regularly
Implement credential rotation:
- Track expiration dates - Document when credentials should rotate
- Automate where possible - Use tools like HashiCorp Vault for dynamic secrets
- Test rotation - Verify jobs work with new credentials before removing old ones
The HashiCorp Vault plugin enables dynamic credential retrieval:
pipeline {
agent any
stages {
stage('Deploy') {
steps {
withVault([
vaultSecrets: [[
path: 'secret/data/deploy',
secretValues: [
[envVar: 'DB_PASSWORD', vaultKey: 'password']
]
]]
]) {
sh './deploy.sh'
}
}
}
}
}
Audit Credential Usage
Enable credential tracking:
- Install Credentials Binding plugin
- Review console output for credential bindings
- Monitor credential access in audit logs
High Priority: Plugin Security
Keep Plugins Updated
Outdated plugins are a common attack vector. Jenkins publishes security advisories regularly.
Establish an update process:
- Check weekly for security updates
- Test in staging before production updates
- Subscribe to the Jenkins security mailing list
# Check for plugin updates via CLI
java -jar jenkins-cli.jar -s http://jenkins:8080/ list-plugins | grep -i update
Remove Unused Plugins
Every plugin increases attack surface. Audit and remove plugins you do not use:
- Navigate to Manage Jenkins > Plugins > Installed
- Review each plugin’s purpose
- Uninstall unused plugins
- Restart Jenkins
Verify Plugin Sources
Only install plugins from:
- The official Jenkins Plugin Index
- Your organization’s approved plugin list
Never install plugins from:
- Random GitHub repositories
- Untrusted third parties
- Direct .hpi file uploads (unless internally developed and reviewed)
High Priority: Network Security
Enable HTTPS
Never run Jenkins over plain HTTP in production.
Using a reverse proxy (recommended):
# Nginx configuration
server {
listen 443 ssl;
server_name jenkins.example.com;
ssl_certificate /etc/ssl/certs/jenkins.crt;
ssl_certificate_key /etc/ssl/private/jenkins.key;
ssl_protocols TLSv1.2 TLSv1.3;
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Configure Jenkins to recognize the proxy:
# JCasC configuration
unclassified:
location:
url: "https://jenkins.example.com/"
Restrict Network Access
Jenkins should not be publicly accessible unless absolutely necessary.
Firewall rules:
- Allow HTTPS (443) from authorized networks only
- Allow agent connections (50000) from agent subnets only
- Block all other inbound traffic
For Kubernetes deployments:
# NetworkPolicy to restrict Jenkins access
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: jenkins-network-policy
spec:
podSelector:
matchLabels:
app: jenkins
ingress:
- from:
- namespaceSelector:
matchLabels:
name: authorized-namespace
ports:
- port: 8080
Secure Agent Communication
Configure agent-to-controller security:
- Navigate to Manage Jenkins > Security
- Under Agents, select Fixed or Random for TCP port
- Enable Agent → Controller Access Control
# JCasC configuration
jenkins:
slaveAgentPort: 50000
agentProtocols:
- "JNLP4-connect"
For Kubernetes-based agents, use in-cluster communication:
pipeline {
agent {
kubernetes {
yaml '''
apiVersion: v1
kind: Pod
spec:
containers:
- name: jnlp
image: jenkins/inbound-agent:latest
'''
}
}
}
Medium Priority: Build Security
Sandbox Pipeline Scripts
Enable the Groovy sandbox for pipeline scripts:
- Navigate to Manage Jenkins > In-process Script Approval
- Review and approve only necessary script signatures
- Reject broad approvals like
method groovy.lang.Script run
The sandbox prevents pipelines from accessing Jenkins internals or executing arbitrary code.
Restrict Script Console Access
The Groovy Script Console can execute any code on the Jenkins controller. Restrict access:
- Only administrators should access the script console
- Audit script console usage
- Consider disabling it entirely in production
# Disable script console via JCasC
jenkins:
disabledAdministrativeMonitors:
- "hudson.diagnosis.ReverseProxySetupMonitor"
Validate Pipeline Sources
For multibranch pipelines, control which branches can run pipelines:
// Only allow Jenkinsfiles from main and release branches
properties([
[$class: 'BuildDiscarderProperty',
strategy: [$class: 'LogRotator', numToKeepStr: '10']],
[$class: 'JobPropertyImpl',
branch: [
[$class: 'BranchSource',
source: [$class: 'GitSCMSource',
includes: 'main release/*']]
]]
])
Scan for Secrets in Build Output
Prevent accidental credential leakage:
- Install the Mask Passwords plugin
- Configure it to mask sensitive patterns
- Review build logs regularly for exposed secrets
# JCasC configuration
unclassified:
globalMaskPasswordsConfig:
maskPasswordsParamDefNames:
- "password"
- "secret"
- "apikey"
- "token"
Medium Priority: Audit and Monitoring
Enable Audit Logging
Track who does what:
- Install the Audit Trail plugin
- Configure logging to a file or syslog
- Integrate with your SIEM
# JCasC configuration
unclassified:
audit-trail:
logBuildCause: true
pattern: ".*/(?:configSubmit|doDelete|postBuildResult|build|toggleLogKeep)"
loggers:
- log:
name: "/var/log/jenkins/audit.log"
Monitor for Anomalies
Set up alerts for suspicious activity:
- Failed login attempts
- Credential access outside normal hours
- Configuration changes
- New admin users
- Plugin installations
We integrate Jenkins audit logs with Prometheus and Grafana for real-time security monitoring.
Regular Security Scans
Run periodic security assessments:
- Dependency scanning - Check for vulnerable dependencies in builds
- Configuration review - Verify security settings quarterly
- Penetration testing - Annual security assessment
Configuration as Code
Use JCasC for Reproducibility
The Configuration as Code plugin enables version-controlled security configuration:
# Complete security configuration
jenkins:
securityRealm:
ldap:
configurations:
- server: "ldap://ldap.example.com"
rootDN: "dc=example,dc=com"
authorizationStrategy:
roleBased:
roles:
global:
- name: "admin"
permissions:
- "Overall/Administer"
assignments:
- "jenkins-admins"
remotingSecurity:
enabled: true
slaveAgentPort: 50000
agentProtocols:
- "JNLP4-connect"
unclassified:
location:
url: "https://jenkins.example.com/"
Store this in version control (without sensitive values). Use Kubernetes secrets or environment variables for sensitive configuration.
Security Checklist Summary
Use this checklist for your Jenkins security review:
Critical
- Security is enabled (authentication + authorization)
- External authentication configured (LDAP, SAML, OAuth)
- Role-based access control implemented
- Credentials stored in Credentials plugin, not in code
- Credentials scoped appropriately (folder-level when possible)
High Priority
- All plugins updated to latest versions
- Unused plugins removed
- HTTPS enabled
- Network access restricted to authorized users
- Agent-to-controller security enabled
Medium Priority
- Pipeline sandbox enabled
- Script console access restricted
- Audit logging configured
- Build output scanned for leaked secrets
- Configuration as Code implemented
Ongoing
- Weekly plugin update review
- Quarterly configuration audit
- Annual penetration test
- Credential rotation schedule maintained
Next Steps
Security is not a one-time task. Schedule regular reviews, subscribe to Jenkins security advisories, and train your team on secure pipeline practices.
For teams implementing new Jenkins installations, our Jenkins pipeline best practices guide covers secure-by-default patterns. If you are evaluating alternatives, see our comparison of Jenkins vs GitHub Actions.
Need Help Securing Jenkins?
We help organizations harden their Jenkins installations and implement secure CI/CD practices. Our Jenkins consulting services include security assessments, hardening implementations, and ongoing support.
Book a free 30-minute consultation to discuss your Jenkins security posture.