A Jenkins controller holds the keys to production; it is a top target and a frequent bottleneck.
Builds never run on the controller. Set the built-in node's executors to 0. A build on the controller can read JENKINS_HOME, including encrypted credentials and the key that decrypts them.
Authentication and authorization: connect to SSO (LDAP, SAML, OIDC plugins) and use Matrix or Role-based authorization so users only see and run what they need. Anonymous read access and "logged-in users can do anything" are common mistakes.
Credentials and scripts: scope credentials to folders, keep the Groovy sandbox enabled, approve scripts sparingly, and restrict who can configure jobs: anyone who can change a Jenkinsfile on a built branch can run code with that job's credentials.
Plugins are the largest attack surface. Install few, update promptly and watch the security advisories shown in Manage Jenkins.
Scaling: one controller handles many agents, but its CPU, heap and disk are shared by everyone. Use ephemeral agents from the Kubernetes or EC2 cloud plugins: a fresh pod or VM per build gives isolation and elasticity. Watch the build queue, executor usage and controller GC pauses; split very large installations into several controllers by team rather than growing one forever.
Example
# casc/jenkins.yaml (excerpt)
jenkins:
numExecutors: 0 # no builds on the controller
authorizationStrategy:
globalMatrix:
entries:
- group:
name: authenticated
permissions: ["Overall/Read", "Job/Read", "Job/Build"]
- user:
name: admin
permissions: ["Overall/Administer"]
clouds:
- kubernetes:
name: k8s
namespace: ci
containerCap: 50
templates:
- name: maven
label: maven
containers: # fresh pod per build, deleted afterwards
- name: maven
image: maven:3.9-eclipse-temurin-21
command: sleep
args: infinityRemember
- Zero executors on the controller; builds run on agents
- Use SSO plus matrix or role-based authorization
- Ephemeral Kubernetes or cloud agents give isolation and elasticity
Watch out for
- Leaving executors on the built-in node, letting any job read controller secrets.