CIS Jenkins Benchmark

Security configuration recommendations for Jenkins CI/CD automation server

v1.0.0 01-2025

Overview

▶

This benchmark provides prescriptive guidance for establishing a secure configuration posture for Jenkins CI/CD automation server. It covers authentication and authorization, controller hardening, credential management, plugin governance, build agent security, audit logging, and web security using the Jenkins API, JCasC, and Groovy scripting.

16Recommendations
7Sections
2Profile Levels
SectionAreaFocus
1Authentication & AuthorizationExternal auth realms and matrix-based authorization
2Controller HardeningCSRF protection, agent access control, and script sandboxing
3Credential ManagementCredential store usage and external secret manager integration
4Plugin GovernancePlugin updates and verified update center sources
5Build Agent SecurityDedicated agents and secure connection protocols
6Audit & ComplianceAudit trail logging and dependency vulnerability scanning
7Web SecurityHTTPS enforcement and Content Security Policy headers

Profile Definitions

▶
ProfileDescriptionIntended Use
L1Level 1 — StandardEssential security for all Jenkins deployments; minimal performance impact.
L2Level 2 — HardenedAdvanced hardening for PCI-DSS, HIPAA, or high-security environments.

1 — Authentication & Authorization

▶

1.1 Security Realm & Strategy

▶
1.1.1 Ensure external security realm is configured (Automated)
L1 Auto
Description

This recommendation verifies that external security realm is configured on the Jenkins CI/CD automation server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.

Rationale

Failure to implement this control may leave the Jenkins CI/CD automation server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.

Audit
# Check security realm configuration:
curl -s -u admin:$JENKINS_TOKEN \
  'http://localhost:8080/api/json?tree=useSecurity' | jq .

# Check via Jenkins Script Console:
import jenkins.model.Jenkins
def j = Jenkins.instance
println j.securityRealm.class.name
Remediation
# Configure LDAP security realm:
# Manage Jenkins > Security > Security Realm > LDAP
# Server: ldaps://ldap.example.com
# Root DN: dc=example,dc=com
# User search base: ou=users

# Via Groovy init script:
import jenkins.model.*
import hudson.security.*
def realm = new LDAPSecurityRealm('ldaps://ldap.example.com', 'dc=example,dc=com', 'ou=users', '', '', '', '', '')
Jenkins.instance.setSecurityRealm(realm)
Jenkins.instance.save()
1.1.2 Ensure matrix-based or role-based authorization is used (Automated)
L1 Auto
Description

This recommendation verifies that matrix-based or role-based authorization is used on the Jenkins CI/CD automation server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.

Rationale

Failure to implement this control may leave the Jenkins CI/CD automation server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.

Audit
# Check authorization strategy:
curl -s -u admin:$JENKINS_TOKEN \
  http://localhost:8080/api/json?tree=authorizationStrategy | jq .

# Script Console:
println Jenkins.instance.authorizationStrategy.class.name
Remediation
# Configure Matrix Authorization:
# Manage Jenkins > Security > Authorization > Matrix-based Security
# Or use Role-Based Strategy plugin

# Via Groovy:
import jenkins.model.*
import hudson.security.*
def strategy = new ProjectMatrixAuthorizationStrategy()
strategy.add(Jenkins.ADMINISTER, 'admin-group')
strategy.add(Jenkins.READ, 'authenticated')
Jenkins.instance.setAuthorizationStrategy(strategy)
Jenkins.instance.save()

2 — Controller Hardening

▶

2.1 Controller Security

▶
2.1.1 Ensure CSRF protection is enabled (Automated)
L1 Auto
Description

This recommendation verifies that CSRF protection is enabled on the Jenkins CI/CD automation server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.

Rationale

Failure to implement this control may leave the Jenkins CI/CD automation server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.

Audit
# Check CSRF protection:
curl -s -u admin:$JENKINS_TOKEN \
  http://localhost:8080/crumbIssuer/api/json 2>/dev/null | jq .

# Script Console:
println Jenkins.instance.crumbIssuer?.class?.name
Remediation
# Enable CSRF Protection:
# Manage Jenkins > Security > CSRF Protection > Enable

# Groovy:
import jenkins.model.*
import hudson.security.csrf.*
Jenkins.instance.setCrumbIssuer(new DefaultCrumbIssuer(true))
Jenkins.instance.save()
2.1.2 Ensure agent-to-controller access control is enabled (Automated)
L1 Auto
Description

This recommendation verifies that agent-to-controller access control is enabled on the Jenkins CI/CD automation server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.

Rationale

Failure to implement this control may leave the Jenkins CI/CD automation server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.

Audit
# Check agent-to-controller access:
cat $JENKINS_HOME/secrets/slave-to-master-security-kill-switch

# Check JNLP protocols:
curl -s -u admin:$JENKINS_TOKEN \
  http://localhost:8080/computer/api/json | jq '.computer[].jnlpAgent'
Remediation
# Enable Agent-to-Controller Security:
# Manage Jenkins > Security > Agent-to-Controller Security > Enabled

# In jenkins.yaml (JCasC):
java:
  -Djenkins.security.s2m.AdminCallableMonitor.crumbExclusion=false

# Disable deprecated JNLP protocols:
echo 'jenkins.AgentProtocol.JNLP4-connect=true' >> $JENKINS_HOME/jenkins.properties
2.1.3 Ensure Script Security sandbox is enforced (Automated)
L1 Auto
Description

This recommendation ensures that Script Security sandbox is enforced on the Jenkins CI/CD automation server. Enforcing this requirement establishes a minimum security standard and prevents insecure configurations.

Rationale

Without this enforcement, the Jenkins CI/CD automation server may accept insecure configurations that weaken overall security posture. Mandating this control ensures consistent protection against common attack vectors.

Audit
# Check script approval queue:
curl -s -u admin:$JENKINS_TOKEN \
  http://localhost:8080/scriptApproval/api/json | jq .
Remediation
# Configure Script Security:
# Manage Jenkins > In-process Script Approval
# Review and approve only necessary scripts

# Restrict sandbox approval in JCasC:
security:
  scriptApproval:
    approvedSignatures: []
    approvedScriptHashes: []

3 — Credential Management

▶

3.1 Secret Storage

▶
3.1.1 Ensure credentials are stored in the credential store (Manual)
L1 Manual
Description

This recommendation verifies that credentials are stored in the credential store on the Jenkins CI/CD automation server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.

Rationale

Failure to implement this control may leave the Jenkins CI/CD automation server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.

Audit
# Check credential store:
curl -s -u admin:$JENKINS_TOKEN \
  http://localhost:8080/credentials/store/system/domain/_/api/json | \
  jq '.credentials[] | {id, typeName, displayName}'
Remediation
# Use credential binding in pipelines:
# Avoid hardcoded secrets in Jenkinsfiles

# Example Jenkinsfile:
// pipeline {
//   stages {
//     stage('Deploy') {
//       steps {
//         withCredentials([string(credentialsId: 'api-key', variable: 'API_KEY')]) {
//           sh 'deploy.sh'
//         }
//       }
//     }
//   }
// }
3.1.2 Ensure external secret managers are integrated (Manual)
L2 Manual
Description

This recommendation verifies that external secret managers are integrated on the Jenkins CI/CD automation server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.

Rationale

Failure to implement this control may leave the Jenkins CI/CD automation server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.

Audit
# Check HashiCorp Vault integration:
curl -s -u admin:$JENKINS_TOKEN \
  http://localhost:8080/credentials/store/system/domain/_/api/json | \
  jq '.credentials[] | select(.typeName | contains("Vault"))'
Remediation
# Install HashiCorp Vault Plugin:
# Manage Jenkins > Plugins > Available > HashiCorp Vault

# Configure Vault in JCasC:
credentials:
  system:
    domainCredentials:
    - credentials:
      - vaultTokenCredentialBinding:
          id: vault-token
          vaultAddr: https://vault.example.com
          engineVersion: 2

4 — Plugin Governance

▶

4.1 Plugin Management

▶
4.1.1 Ensure plugins are kept up to date (Automated)
L1 Auto
Description

This recommendation verifies that plugins are kept up to date on the Jenkins CI/CD automation server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.

Rationale

Failure to implement this control may leave the Jenkins CI/CD automation server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.

Audit
# List installed plugins with versions:
curl -s -u admin:$JENKINS_TOKEN \
  http://localhost:8080/pluginManager/api/json?depth=1 | \
  jq '.plugins[] | {shortName, version, active, hasUpdate}'
Remediation
# Update all plugins:
curl -s -X POST -u admin:$JENKINS_TOKEN \
  http://localhost:8080/pluginManager/installNecessaryPlugins \
  --data '<install plugin="git@latest" />''

# Via CLI:
java -jar jenkins-cli.jar -s http://localhost:8080 \
  -auth admin:$JENKINS_TOKEN \
  install-plugin git workflow-aggregator -restart

# Remove unused plugins:
java -jar jenkins-cli.jar -s http://localhost:8080 \
  -auth admin:$JENKINS_TOKEN \
  disable-plugin legacy-plugin
4.1.2 Ensure update center uses verified sources (Automated)
L1 Auto
Description

This recommendation verifies that update center uses verified sources on the Jenkins CI/CD automation server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.

Rationale

Failure to implement this control may leave the Jenkins CI/CD automation server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.

Audit
# Check update center configuration:
curl -s -u admin:$JENKINS_TOKEN \
  http://localhost:8080/updateCenter/api/json | \
  jq '{sites: [.sites[].url], restartRequired}'
Remediation
# Use official update center with certificate verification:
# Manage Jenkins > Plugins > Advanced > Update Site
# URL: https://updates.jenkins.io/update-center.json

# Verify update center certificate:
jenkins.model.Jenkins.instance.getUpdateCenter().getSites().each { site ->
  println "${site.url} - ${site.id}"
}

5 — Build Agent Security

▶

5.1 Agent Configuration

▶
5.1.1 Ensure builds do not execute on the controller (Automated)
L1 Auto
Description

This recommendation verifies that builds do not execute on the controller on the Jenkins CI/CD automation server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.

Rationale

Failure to implement this control may leave the Jenkins CI/CD automation server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.

Audit
# Check build execution on controller:
curl -s -u admin:$JENKINS_TOKEN \
  http://localhost:8080/computer/(built-in)/api/json | \
  jq '{numExecutors, idle, offline}'
Remediation
# Set controller executors to 0:
# Manage Jenkins > Nodes > Built-In Node > Configure
# Number of executors: 0

# Via JCasC:
jenkins:
  numExecutors: 0
  mode: EXCLUSIVE
  nodes:
  - permanent:
      name: build-agent-1
      remoteFS: /home/jenkins
      numExecutors: 4
5.1.2 Ensure agents connect via SSH or secured protocols (Automated)
L1 Auto
Description

This recommendation verifies that agents connect via SSH or secured protocols on the Jenkins CI/CD automation server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.

Rationale

Failure to implement this control may leave the Jenkins CI/CD automation server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.

Audit
# Check agent connection security:
curl -s -u admin:$JENKINS_TOKEN \
  http://localhost:8080/computer/api/json?depth=1 | \
  jq '.computer[] | {displayName, offline, launchType: .launchers[0]._class}'
Remediation
# Configure agents with SSH:
# Manage Jenkins > Nodes > New Node
# Launch method: Launch agents via SSH
# Host: agent.example.com
# Credentials: SSH key
# Host Key Verification Strategy: Known hosts file

# Use Docker agents:
# JCasC:
jenkins:
  clouds:
  - docker:
      dockerApi:
        dockerHost:
          uri: tcp://docker.example.com:2376
          credentialsId: docker-tls

6 — Audit & Compliance

▶

6.1 Logging & Scanning

▶
6.1.1 Ensure audit trail logging is configured (Automated)
L1 Auto
Description

This recommendation verifies that audit trail logging is configured on the Jenkins CI/CD automation server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.

Rationale

Failure to implement this control may leave the Jenkins CI/CD automation server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.

Audit
# Check audit trail plugin:
curl -s -u admin:$JENKINS_TOKEN \
  http://localhost:8080/pluginManager/api/json?depth=1 | \
  jq '.plugins[] | select(.shortName=="audit-trail")'
Remediation
# Install and configure Audit Trail:
# Manage Jenkins > Plugins > Install audit-trail

# JCasC configuration:
unclassified:
  audit-trail:
    logBuildCause: true
    pattern: '.*/(?:configSubmit|doDelete|postBuildResult|enable|disable|cancelQueue|stop|toggleLogKeep|doWipeOutWorkspace|createItem|createView|toggleOffline|cancelQuietDown|quietDown|restart|exit|safeRestart)'
    loggers:
    - syslog:
        syslogHost: syslog.example.com
        facility: LOCAL0
6.1.2 Ensure dependency scanning is integrated in pipelines (Manual)
L1 Manual
Description

This recommendation verifies that dependency scanning is integrated in pipelines on the Jenkins CI/CD automation server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.

Rationale

Failure to implement this control may leave the Jenkins CI/CD automation server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.

Audit
# Check OWASP dependency check:
ls $JENKINS_HOME/plugins/dependency-check* 2>/dev/null

# Check job configurations for security scanning:
grep -r 'dependencyCheck\|sonarqube' $JENKINS_HOME/jobs/*/config.xml
Remediation
# Add OWASP Dependency-Check to pipelines:
# pipeline {
#   stages {
#     stage('Security Scan') {
#       steps {
#         dependencyCheck additionalArguments: '--scan ./ --format HTML',
#           odcInstallation: 'dependency-check'
#         dependencyCheckPublisher pattern: 'dependency-check-report.xml'
#       }
#     }
#   }
# }

7 — Web Security

▶

7.1 HTTPS & Headers

▶
7.1.1 Ensure Jenkins is served over HTTPS (Automated)
L1 Auto
Description

This recommendation verifies that Jenkins is served over HTTPS on the Jenkins CI/CD automation server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.

Rationale

Failure to implement this control may leave the Jenkins CI/CD automation server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.

Audit
# Check Jenkins URL and HTTPS:
curl -s -u admin:$JENKINS_TOKEN \
  http://localhost:8080/configure | grep -o 'jenkinsUrl.*value="[^"]*"'

# Check reverse proxy configuration:
nginx -T 2>/dev/null | grep -A10 'server_name jenkins'
Remediation
# Configure HTTPS via reverse proxy:
# /etc/nginx/sites-available/jenkins:
# server {
#   listen 443 ssl;
#   server_name jenkins.example.com;
#   ssl_certificate /etc/ssl/certs/jenkins.crt;
#   ssl_certificate_key /etc/ssl/private/jenkins.key;
#   location / {
#     proxy_pass http://localhost:8080;
#     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#     proxy_set_header X-Forwarded-Proto https;
#   }
# }
7.1.2 Ensure Content Security Policy headers are configured (Automated)
L1 Auto
Description

This recommendation verifies that Content Security Policy headers are configured on the Jenkins CI/CD automation server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.

Rationale

Failure to implement this control may leave the Jenkins CI/CD automation server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.

Audit
# Check content security policy:
curl -sI -u admin:$JENKINS_TOKEN \
  http://localhost:8080/ | grep -i 'content-security-policy\|x-frame-options\|x-content-type'
Remediation
# Set security headers in Jenkins:
# System Properties (JAVA_OPTS):
-Dhudson.model.DirectoryBrowserSupport.CSP="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'"

# Via JCasC:
unclassified:
  resourceRoot:
    url: https://resources.jenkins.example.com/