Jenkins Course
Jenkins Security Model
A Jenkins instance with no security configured is an open door to your entire build infrastructure. This lesson covers the security model from the ground up — authentication, authorisation, CSRF protection, and the settings every production Jenkins must have locked down before it touches a real network.
This lesson covers
Security Realm (authentication) → Authorization Strategy → CSRF protection → Agent-to-master security → Script approval → API tokens → The global security configuration checklist
Jenkins security has two distinct layers — who is allowed in (authentication) and what they're allowed to do (authorisation). Most teams configure authentication correctly but leave authorisation too permissive. This lesson covers both layers and the additional protections that sit underneath them.
The Analogy
Jenkins security is like a building's access control system. Authentication is the keycard reader at the front door — it checks who you are. Authorisation is the room-level access control — it decides which rooms you can enter once you're inside. CSRF protection is the security camera — it verifies that actions on the system were initiated by the right person, not by a malicious link someone tricked them into clicking.
Layer 1 — Authentication (Security Realm)
The Security Realm controls how Jenkins verifies who a user is. Jenkins supports several methods — each suited to different team sizes and infrastructure setups.
Jenkins' own database
Most common starting point
Jenkins stores usernames and passwords internally. Simple to set up. Works for small teams. The limitation: no single sign-on, no integration with your company's identity provider. Every Jenkins user account is managed separately.
LDAP / Active Directory
Enterprise standard
Jenkins delegates authentication to your organisation's LDAP server or Active Directory. Engineers log in with their company credentials. When someone leaves the company, deactivating their AD account automatically revokes Jenkins access. This is the right choice for any team with more than 10 people.
GitHub OAuth
Cloud-native teams
Users log in with their GitHub account. Jenkins verifies membership in a specific GitHub organisation or team. Works well for open-source projects and teams already using GitHub as their identity layer. Requires the GitHub Authentication plugin.
SAML / SSO
Enterprise SSO
Integrates with identity providers like Okta, Azure AD, Google Workspace via SAML 2.0. Single sign-on across all company tools. Requires the SAML Plugin. The most secure option for larger organisations.
The Global Security Configuration Screen
All security settings live at Manage Jenkins → Configure Global Security. Here's what the most important sections look like and what each setting does:
Security Realm (Authentication)
Authorization
CSRF Protection
Crumb Issuer: Default Crumb Issuer ▾
Agent → Controller Security
Prevents agent processes from reading or writing files on the controller beyond what's needed for the build.
Layer 2 — Authorisation Strategies Compared
Once a user is authenticated, authorisation determines what they can do. The wrong choice here is one of the most common Jenkins security mistakes teams make.
| Strategy | What it does | Use it? |
|---|---|---|
| Anyone can do anything | No auth required — anyone can do anything including admin actions | Never in production |
| Logged-in users can do anything | Any authenticated user has full admin access — including contractors and interns | Dev/learning only |
| Matrix-based security | Fine-grained per-user and per-group permissions across all of Jenkins | Recommended |
| Project-based Matrix | Matrix-based plus per-job permission overrides — team A can only see team A's jobs | Recommended for large teams |
| Role-Based Strategy | Define named roles (admin, developer, read-only) and assign users to roles — cleaner than per-user matrix for large teams | Recommended for 20+ users |
Configuring Security via the Jenkins CLI
The scenario:
You're a platform engineer at a 60-person fintech company. Jenkins was set up quickly six months ago and is currently running with "Logged-in users can do anything" — meaning every developer has full admin access. You need to audit the current security configuration and tighten it up via the CLI and a Groovy script before auditors review the system next week.
New terms in this code:
- Groovy script console — Jenkins has a built-in Groovy script console at
/script. Admins can run arbitrary Groovy code against the live Jenkins instance. It's extremely powerful and extremely dangerous — only admins should have access. - Jenkins.instance — the root Jenkins object accessible from the script console. It exposes every configuration setting programmatically.
- HudsonPrivateSecurityRealm — the Java class name for Jenkins' internal user database authentication. Using class names lets you configure Jenkins programmatically.
- GlobalMatrixAuthorizationStrategy — the Java class for matrix-based security. You add permissions to it using
add(Permission, username). - groovy-script CLI command — lets you run a Groovy script against Jenkins from the terminal, without opening the browser script console.
# Step 1: Check the current security configuration
# This Groovy script reads the live Jenkins config and prints it
java -jar jenkins-cli.jar \
-s http://jenkins-master-01:8080 \
-auth admin:your-api-token \
groovy = << 'EOF'
import jenkins.model.Jenkins
def j = Jenkins.instance
// Print current authentication method
println "Security Realm: ${j.securityRealm.class.simpleName}"
// Print current authorization strategy
println "Authorization: ${j.authorizationStrategy.class.simpleName}"
// Print whether CSRF protection is enabled
println "CSRF Enabled: ${j.crumbIssuer != null}"
// Print whether agent-to-master security is enabled
println "Agent Security: ${j.injector.getInstance(jenkins.security.s2m.AdminWhitelistRule.class).masterKillSwitch == false}"
EOF
Where to practice: The Groovy script console is at http://localhost:8080/script on your local Jenkins. Paste the script body directly into the console and click Run. You'll see the current security config printed immediately. Never expose the script console to non-admin users — it provides full control over Jenkins. Full security configuration guide at jenkins.io — Access Control.
Security Realm: HudsonPrivateSecurityRealm Authorization: FullControlOnceLoggedInAuthorizationStrategy CSRF Enabled: true Agent Security: true
What just happened?
HudsonPrivateSecurityRealm— Jenkins is using its own internal user database for authentication. This is fine for a small team but not ideal for an organisation — it means user management is separate from your company's identity system.FullControlOnceLoggedInAuthorizationStrategy— this is the "Logged-in users can do anything" setting. Every authenticated user has full admin rights. For a fintech company, this is a serious finding. Any developer who logs in can delete jobs, read credentials, modify security settings, or install plugins — a major risk.CSRF Enabled: true— good. CSRF protection is active. This prevents cross-site request forgery attacks where a malicious page tricks an admin's browser into making unauthorised changes to Jenkins.Agent Security: true— good. Agent-to-master security is enabled. A compromised build agent cannot read files from the Jenkins master filesystem or execute arbitrary code on the master.
Now let's tighten the authorisation strategy from "everyone is admin" to proper matrix-based security:
# Step 2: Switch to matrix-based security via a Groovy script
# This script configures proper role separation:
# - admin gets full control
# - developers get read + build rights
# - anonymous gets nothing (forces login)
java -jar jenkins-cli.jar \
-s http://jenkins-master-01:8080 \
-auth admin:your-api-token \
groovy = << 'EOF'
import jenkins.model.Jenkins
import hudson.security.*
def j = Jenkins.instance
// Switch authorization to Matrix-based security
def strategy = new GlobalMatrixAuthorizationStrategy()
// Grant the admin user full control over everything
strategy.add(Jenkins.ADMINISTER, 'admin')
// Grant authenticated developers read access to Jenkins
strategy.add(Jenkins.READ, 'authenticated')
// Grant developers permission to build and cancel jobs
strategy.add(hudson.model.Item.BUILD, 'authenticated')
strategy.add(hudson.model.Item.CANCEL, 'authenticated')
strategy.add(hudson.model.Item.READ, 'authenticated')
// Grant developers read access to view build logs
strategy.add(hudson.model.Run.UPDATE, 'authenticated')
// Deny anonymous access — anyone must log in to see anything
// (no anonymous permissions added = no anonymous access)
// Apply the new strategy
j.authorizationStrategy = strategy
j.save()
println "Authorization strategy updated to Matrix-based security"
println "Admin: full control"
println "Authenticated users: read + build only"
println "Anonymous: no access"
EOF
Authorization strategy updated to Matrix-based security Admin: full control Authenticated users: read + build only Anonymous: no access
What just happened?
- Authorization strategy replaced programmatically — the Groovy script ran against the live Jenkins instance and swapped the authorisation strategy from "everyone is admin" to matrix-based security. This took effect immediately — no restart required.
authenticatedis a special group — in Jenkins matrix security,authenticatedrepresents all logged-in users. Granting permissions to this group applies to every user who has authenticated, without naming them individually.- Anonymous has no permissions — because we added no permissions for the anonymous user group, anyone who is not logged in sees a login screen. No data is exposed to unauthenticated requests.
j.save()persisted the change — without this call, the change would apply in memory for the current session but revert after a Jenkins restart.save()writes the config toconfig.xmlon disk.- Developers can now build but not administer — they can trigger builds, read logs, and cancel running jobs. They cannot install plugins, modify security settings, manage credentials, or delete jobs. This is the principle of least privilege applied to Jenkins.
API Tokens — The Right Way to Authenticate Automation
Any time a script, CI tool, or another system needs to talk to Jenkins — triggering builds, checking status, fetching artifacts — it should authenticate with an API token, not a username and password. API tokens are:
Advantages of API tokens
- Revocable without changing the user's password
- Can be scoped — create a separate token per integration
- Never expire unless you set them to
- Visible in audit logs as distinct from browser sessions
Never use passwords for automation
- Changing the password breaks all integrations
- If the password leaks, the whole account is compromised
- Can't tell which integration used it in audit logs
- Shared passwords spread across multiple systems
To generate an API token: log in as the user → click the username in the top right → Configure → API Token → Add new Token. Copy the token immediately — Jenkins only shows it once.
Production Security Checklist
Teacher's Note
Run the security audit Groovy script on every Jenkins instance you inherit. "Logged-in users can do anything" is more common than you'd think — and takes two minutes to fix.
Practice Questions
1. What Java class name does Jenkins report when the authorization strategy is set to "Logged-in users can do anything"?
2. In Jenkins matrix-based security, which special group name represents all users who have successfully logged in?
3. What should scripts and automation tools use to authenticate with Jenkins instead of a username and password?
Quiz
1. What does CSRF protection in Jenkins guard against?
2. What does enabling Agent → Controller security protect against?
3. Which authorization strategies are recommended for a production Jenkins with a team of 15 engineers?
Up Next · Lesson 29
Users, Roles and Permissions
The Role-Based Access Control plugin in depth — creating roles, assigning users, and designing a permission model that scales with your team.