Skip to main content

Implementing Security Best Practices

1. Enabling Script Security

Example: Enabling Script Security via Jenkins UI

Manage Jenkins > Configure Security > Script Approval
Setting Description Default Status
scriptApproval Controls approval of unsafe scripts Disabled NEW
sandbox Enables sandboxed script execution Disabled NEW
Note: Script approval is required for Groovy scripts that use unsafe methods or classes.
Warning: Disabling script security can lead to arbitrary code execution.

Script Security Configuration Summary

  • Enable script approval for all Groovy scripts
  • Use sandboxed execution where possible
  • Review and approve scripts before deployment

2. Using Credential Masking

Property Description Example
credentials.masked Indicates whether the credential value is masked in logs and UI true
credentials.type Specifies the type of credential (e.g., username/password, API token) usernamePassword

Example: Masking Credentials in Jenkins Pipeline

pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                withCredentials([usernamePassword(credentialsId: 'my-credentials', variable: 'CREDENTIALS')]) {
                    sh 'echo "Username: $CREDENTIALS_USR" && echo "Password masked in logs"'
                }
            }
        }
    }
}
Note: Jenkins automatically masks sensitive values in logs when using withCredentials block.
Warning: Never hardcode credentials in Jenkinsfiles or scripts. Always use Jenkins Credentials Store.

3. Configuring Script Approval

Jenkins provides a security feature to control which Groovy scripts can be executed in the system. This is particularly important for pipelines that use script blocks or dynamic script execution.

Configuration Option Description Default Value
scriptApproval Controls whether scripts must be manually approved before execution. false

Example: Approving a Script via UI

To approve a script:

  1. Navigate to Manage Jenkins > Script Approval.
  2. Find the script that needs approval.
  3. Click Approve next to the script.

Example: Approving a Script via Configuration as Code (JCasC)

unclassified:
  scriptApproval:
    approvedScripts:
      - checksum: "abc123"
        script: "println 'Hello World'"
Note: Script approval is enforced for scripts that are not part of the org.jenkinsci.plugins.workflow.cps.CpsScmFlow or org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition classes.
Warning: Approving scripts without understanding their implications can lead to security vulnerabilities. Always review scripts before approval.

4. Using Sandbox Execution

Note: Jenkins sandbox execution restricts plugin and script execution to prevent unauthorized access or malicious code execution.
Feature Description Configuration
Script Security Plugin Enforces sandboxing for Groovy scripts in Jenkins pipelines and script console. Enabled by default in modern Jenkins versions.
Pipeline Script Approval Requires manual approval of new pipeline scripts before they can run. Configurable via Jenkins UI or API.
Groovy Sandbox Restricts access to sensitive Java APIs and system resources. Enabled via scriptApproval.xml or Jenkins UI.

Example: Enabling Script Security

// Example pipeline script with sandboxed execution
pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                sh 'echo "Building..."'
            }
        }
    }
}

Workflow: Setting Up Script Security

  1. Navigate to Manage Jenkins > Script Approval
  2. Review pending scripts and approve them individually or globally
  3. Ensure Script Security Plugin is installed and enabled
  4. Configure scriptApproval.xml for automated approvals (advanced)

Key Benefits of Sandboxing

  • Prevents unauthorized access to system resources
  • Reduces risk of malicious code execution in pipelines
  • Enables safe use of plugins with unknown origins

5. Implementing Least Privilege Access

Principle Description Implementation
User Permissions Grant users only the minimum permissions required to perform their tasks. Use Jenkins Role-Based Access Control (RBAC) to define roles and assign permissions.
Job Permissions Restrict access to jobs based on user roles or groups. Configure job-level permissions using the "Role-based Authorization Strategy" plugin.
System Permissions Limit access to system configuration and administration functions. Assign administrative roles to only trusted users or groups.

Example: Configuring Role-Based Access Control

// Define roles and their associated permissions
def roles = [
    'admin': ['hudson.model.Hudson.Administer', 'hudson.model.Item.Build'],
    'developer': ['hudson.model.Item.Build', 'hudson.model.Item.Read'],
    'viewer': ['hudson.model.Item.Read']
]

// Assign roles to users
def userRoles = [
    'alice': ['admin'],
    'bob': ['developer'],
    'charlie': ['viewer']
]
Note: Jenkins RBAC requires the Role-based Authorization Strategy plugin to be installed and configured.
Warning: Never grant full admin access to users who do not require it. This can lead to unauthorized changes or security breaches.

6. Securing Webhooks with Tokens

Property Value Description
webhook.token secret-token-12345 Token used to secure webhook endpoints
webhook.url https://jenkins.example.com/webhook Endpoint URL that receives webhook events

Example: Configuring Webhook Token in Jenkins

pipeline {
    agent any
    stages {
        stage('Trigger Build') {
            triggers {
                upstream 'Build-Project'
            }
        }
    }
    post {
        success {
            sh 'curl -H "X-Webhook-Token: secret-token-12345" https://jenkins.example.com/webhook'
        }
    }
}
Note: The webhook token must be securely stored and not exposed in logs or public repositories.
Warning: If the token is compromised, all webhook-based triggers are at risk of unauthorized access.

7. Using Agent Security Settings

Setting Description Default Value Notes
agent.jvm.options JVM options for the agent process -Xmx512m Adjust based on available memory
agent.workspace.dir Workspace directory for the agent /tmp/jenkins-agent Must be writable by the agent user
agent.executors Number of executors for the agent 1 Set to match available CPU cores

Example: Configure Agent Security Settings

agent {
    label 'linux-agent'
    jvmOptions '-Xmx1024m -XX:+UseG1GC'
    workspaceDir '/var/lib/jenkins/agent-workspace'
    executors 4
}
Note: Ensure the agent user has appropriate permissions to access the workspace directory and execute JVM options.
Warning: Setting agent.executors too high can lead to resource contention and build failures.

8. Implementing Build Isolation

Aspect Description Implementation
Isolated Build Environment Ensures builds run in a clean, isolated environment to prevent interference from previous builds or system changes. Use Jenkins Pipeline with agent { docker { image 'node:18' } } to run builds in a Docker container.
Resource Constraints Limits CPU and memory usage to prevent one build from consuming all system resources. Configure Docker agent with resource limits using docker { image 'node:18'; args '--memory=2g --cpus=1.5' }.
Network Isolation Restricts network access to prevent builds from accessing external systems or services. Use Docker networks with docker { image 'node:18'; network 'jenkins-build-net' } to isolate build environments.
Build Artifacts Isolation Ensures that artifacts from one build do not interfere with another. Use Jenkins Pipeline's archiveArtifacts to store artifacts in a structured and isolated manner.

Example: Docker Agent with Resource Limits

pipeline {
    agent {
        docker {
            image 'node:18'
            args '--memory=2g --cpus=1.5'
            network 'jenkins-build-net'
        }
    }
    stages {
        stage('Build') {
            steps {
                sh 'npm install'
                sh 'npm run build'
            }
        }
    }
}
Note: Isolation ensures reproducibility and security by preventing cross-contamination between builds.

9. Auditing Security Events

Event Type Description Log Fields Notes
Security Audit Records security-relevant actions in Jenkins timestamp, user, action, details Enabled via SecurityRealm and AuthorizationStrategy
Login Failure Tracks failed login attempts timestamp, user, ipAddress, reason Useful for detecting brute-force attacks
Permission Change Logs changes to user or group permissions timestamp, user, affectedUser, permission Can be used to detect unauthorized access grants
Plugin Installation Tracks plugin installations and updates timestamp, user, pluginName, version Helps identify potentially malicious plugins

Example: Configuring Security Audit Logging

// In Jenkins Script Console or Pipeline
import jenkins.model.Jenkins
import hudson.security.AuthorizationStrategy
import hudson.security.SecurityRealm

def jenkins = Jenkins.instance
def securityRealm = jenkins.getSecurityRealm()
def authStrategy = jenkins.getAuthorizationStrategy()

// Enable audit logging
jenkins.setAuditLogEnabled(true)
jenkins.save()
Note: Audit logs can be configured to write to external systems (e.g., SIEM tools) for centralized monitoring.
Warning: Ensure audit logs are protected from tampering and regularly backed up to prevent data loss.

Key Audit Events

  • Login attempts (successful and failed)
  • Permission modifications
  • Plugin installations or updates
  • Configuration changes to security settings

10. Using Security Scanning Tools

Tool Description Integration Notes
OWASP ZAP Open-source web application security scanner Can be integrated via Jenkins plugins or CLI Supports automated scanning of web apps for vulnerabilities
SonarQube Platform for continuous inspection of code quality and security Jenkins plugin available; integrates with build pipelines Provides static analysis for security issues in code
Nessus Network vulnerability scanner Can be run as a Jenkins job or via API integration Used for scanning infrastructure and network security
Bandit Security linter for Python code Jenkins plugin or command-line integration Identifies security issues in Python codebases

Example: Integrating OWASP ZAP in Jenkins Pipeline

pipeline {
    agent any
    stages {
        stage('Scan with ZAP') {
            steps {
                sh 'zap.sh -cmd -addoninstall zap'
                sh 'zap.sh -cmd -quickurl http://localhost:8080'
            }
        }
    }
}
Note: Ensure that security scanning tools are run in a secure environment to avoid exposing sensitive data.
Warning: Scanning tools must be configured with appropriate permissions to avoid false positives or missed vulnerabilities.

Was this article helpful?