Chapter 29Lesson 05~225 minutes

Checkpoint Lab — Security Hardening, CSRF, Agent-to-Controller Controls, Script Security, CSP, TLS, and Reverse Proxies

Harden an intentionally weak but local-only Jenkins lab, prove each control with safe tests, preserve before/after evidence, and document rollback boundaries without ever disabling CSRF, authorization, Script Security, TLS verification, or agent-to-controller protection.

Checkpoint labBefore/afterVerificationRollbackEvidence packetProduction bridge

Learning objectives

  • Predict security-state changes before hardening the lab.
  • Move execution off the controller and prove queue behavior.
  • Verify CSRF, script, CSP, proxy/TLS and agent boundaries independently.
  • Capture a complete before/after evidence packet without secret material.
  • Document rollback so hardening is repeatable rather than a one-off UI exercise.

1. Mission: harden a weak but local-only controller

Your lab starts with Jenkins 2.568.3 LTS/Java 21 on loopback or an isolated container network. CSRF and authorization are already enabled. Weaknesses are deliberately limited to conditions that do not require disabling security: the built-in node has one executor, security evidence has not been documented, the general UI CSP is not enforced, and the reverse-proxy/TLS design exists only as an unverified local configuration. A disposable trusted-lab agent is available.

Finish with a controller that does not execute builds, current Script Security, tested CSRF behavior, staged/enforced CSP in the disposable clone, a correct TLS/proxy model, documented agent isolation and a reproducible evidence packet.

2. Assumptions and preflight

Component Checkpoint assumption
Jenkins 2.568.3 LTS
Java 21 (25 also supported by this LTS)
Script Security 1422.v06869826dd9b_ or newer; do not continue on 1415 or earlier
Agent Disposable trusted-lab, separate process/identity, no JENKINS_HOME access
Credentials Fake lab user/API token only; never archive or print it
TLS/proxy Local Nginx/Caddy simulation or reviewed config; no public DNS required

3. Predict before changing anything

Write at least these predictions:

  1. After built-in executors become zero, a job constrained to trusted-lab will wait rather than run on the controller when that agent is offline.
  2. After correct proxy headers are introduced, public HTTPS requests will no longer produce HTTP absolute redirects, and WebSocket upgrade evidence will be available for inbound agents.
  3. After CSP enforcement is enabled in the clone, compatible Jenkins UI pages will carry the enforced policy while violations identify any incompatible plugin UI.

Also predict which states should not change: source SHA, prior build records, archived artifacts and credentials values.

4. Capture the before packet

evidence/security-ch29/
├── assumptions.md
├── controller-version.txt
├── plugins-security.txt
├── listeners-before.txt
├── node-executors-before.txt
├── approvals-before.txt
├── headers-before.txt
└── proxy-config-before.conf

Use screenshots for UI-only settings if needed. Redact Authorization/Cookie headers and never store a private key or API token in this directory.

5. Apply bounded hardening changes

A. Controller execution

Set built-in executors from 1 to 0. Run the synthetic job on trusted-lab; record build number, node name and workspace. Mark the agent temporarily offline and trigger again; record the queue reason, then reconnect the agent and let the same queued item proceed.

B. CSRF behavior

Using the disposable identity, perform one harmless authenticated read. Then trigger the exact synthetic job with an API token and record the returned status/queue location. Separately document the password/session crumb flow from Lesson 2 without storing credentials. CSRF remains enabled throughout.

C. Script boundary

Confirm Script Security 1422.v06869826dd9b_ or later and export the list/count of pending and approved entries. Do not create a dangerous approval merely to have evidence; “none pending” is valid evidence.

D. CSP

Review violation data and core plugin screens, then enable general UI CSP in the disposable clone. Record the response header and any violation that occurs. If a plugin breaks, revert the CSP change in the clone and record the incompatibility rather than weakening the rule globally.

E. TLS/reverse proxy

Validate the local configuration contains host/scheme forwarding and WebSocket upgrade support; confirm the Jenkins context path matches. If you run it locally with a self-signed certificate, curl -k is allowed only for this isolated test. In production, install a trusted chain instead.

F. Agent boundary

Record agent process identity, Java/Remoting context, labels and workspace root. Prove the worker does not mount/read JENKINS_HOME. Do not attempt to disable agent→controller access control—it is always enabled in current Jenkins.

6. Independent verification checklist

  • Built-in node shows 0 executors.
  • A queued lab build does not fall back to the controller when the agent is offline.
  • CSRF protection is still enabled; API-token behavior and session/crumb behavior are documented correctly.
  • Script Security is 1422+ and approval inventory is captured.
  • General UI CSP state is recorded with header/violation evidence; user-content isolation plan is documented.
  • Proxy config preserves Host and X-Forwarded-Proto, supports WebSocket upgrade and does not expose the backend as an unintended public entry point.
  • Agent identity/workspace is separate from controller home.
  • No evidence file contains credentials, tokens, session cookies or TLS private keys.

7. Evidence packet

Add these files or equivalent records:

evidence/security-ch29/
├── build-and-queue-ids.txt
├── node-executors-after.txt
├── csrf-test-redacted.txt
├── approvals-after.txt
├── csp-headers-after.txt
├── proxy-config-after.conf
├── agent-identity.txt
├── listeners-after.txt
├── rollback.md
└── findings.md

findings.md should distinguish configuration truth from test outcome: “header present” is not the same as “every plugin UI is compatible,” and “agent connected” is not the same as “agent is trustworthy.”

8. Cleanup and rollback

Rollback is not “turn security off.” If the local proxy test is no longer needed, stop/remove only the disposable proxy and delete the lab certificate/key securely. If CSP exposes a plugin incompatibility, return the clone to its prior CSP state while preserving the violation evidence and opening a remediation item. Keep built-in executors at zero if an eligible agent exists. Remove the fake lab token/user and synthetic jobs after exporting non-secret evidence.

Production rule. Any rollback that broadens privilege—such as re-enabling controller builds or removing TLS/CSRF—is a separate security exception requiring explicit risk ownership, not a routine lab rollback.

9. What this chapter adds to the production operating model

You now have a layered security model that links HTTP/TLS, identity, CSRF, controller execution, script/plugin trust, agent Remoting and browser content to independent evidence. That is the prerequisite for Chapter 30: external identity and access governance. SSO/LDAP/OIDC/SAML can improve identity lifecycle, but they do not replace these controller, script, agent and transport boundaries.

Next chapter

Chapter 30 — SSO, LDAP, OIDC/SAML Plugins, External Identity, RBAC Patterns, and Enterprise Access Governance

Carry the verified evidence and operating discipline from this chapter into the next chapter.

Knowledge check

Answer before revealing the explanation.

1. The agent is offline and the build remains queued after hardening. Is that a failure?

2. A plugin UI breaks after CSP enforcement. What should the checkpoint record?

3. Why is an API-token POST without a crumb not evidence that CSRF is disabled?

4. What is the correct response if the lab reports Script Security 1415?

5. Which Chapter 30 topic naturally follows this hardening work?

Official references and version notes

Verified baseline — 17 September 2026. Labs target Jenkins 2.568.3 LTS with Java 21 (Jenkins 2.568.3 is tested with Java 21 and 25) and Script Security 1422.v06869826dd9b_. Script Security 1415.v9a_f9b_3a_c253d and earlier are affected by multiple sandbox vulnerabilities disclosed 16 September 2026. General Jenkins UI CSP is a core feature in Jenkins 2.539+ but is disabled by default because plugin compatibility varies; introduce it using report evidence and testing. Re-check Jenkins core/plugin advisories before applying these patterns to a long-lived controller.

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this address.