Controller-Agent Trust

Controller-Agent Trust and the Controller's Attack Surface

The controller holds everything worth stealing: every stored credential, the keys that decrypt them, and the power to run code on every agent. A build on the built-in node breaks that boundary, because its shell runs as the same jenkins user as the controller. This job, run while the built-in node still had its default two executors, reads the controller's secrets (console trimmed to the shell's output):

built-in-peek: any job on the built-in node can read JENKINS_HOMEGroovy
node('built-in') {
  sh 'id -un; ls /var/jenkins_home/secrets | head -2; wc -c < /var/jenkins_home/secrets/master.key'
}
Output
jenkins
hudson.console.ConsoleNote.MAC
hudson.model.Job.serverCookie
256

master.key unlocks the key that encrypts every stored credential, so anyone who can edit a Jenkinsfile could take them all. Jenkins 8,793 warns about the configuration on its Manage Jenkins page:

The warning shown while the built-in node has executors
The warning shown while the built-in node has executors

The fix is zero executors on the built-in node, as in Executors and the Build Queue; the same job then waits for ever. In the other direction, agent-to-controller access control stops a compromised agent from running callables on the controller or touching its files outside a narrow allow-list; since Jenkins 2.326 it is always on.

What remains is the controller's own surface: the web interface and REST API, the CLI, the Script Console (Groovy with full JVM access; CVE-2026-84645, fixed in 2.568.3 on 2 September 2026, let crafted serialized objects reach it) and every plugin. Securing Jenkins hardens each.