SSH, Inbound, WebSocket, Windows, and Ephemeral Agents: Connectivity, Remoting, and Agent Lifecycle: Guided Hands-On Workflow and Core Operations
Bring up a disposable inbound/WebSocket agent, inspect its Java and Remoting evidence, exercise safe disconnect/reconnect behavior, model SSH and Windows launch patterns, rotate disposable connection material, and prove ephemeral teardown.
Learning objectives
- Connect one disposable agent over WebSocket with pinned Java/Remoting assumptions.
- Capture connection, process, node and workspace evidence without exposing the inbound secret.
- Force a bounded disconnect, observe queue/build effects and reconnect safely.
- Model SSH and Windows agent launch with explicit identity and host/process permissions.
- Rotate a disposable agent identity and prove ephemeral workspace teardown.
1. Lab topology and preflight
Use a disposable Jenkins 2.568.3 LTS controller with
Java 21, built-in node executors set to 0, and a node
named ch18-ws-a with label
ch18-remote linux webSocket, one executor and a
disposable remote root.
The mandatory path uses a local/container inbound agent over WebSocket. SSH is demonstrated as a free local option if you already have an isolated SSH container/VM. Windows is represented faithfully with the same inbound command/service identity model; if you have Windows containers or a disposable Windows VM you may run it directly.
2. Create the inbound node first
- Manage Jenkins → Nodes → New Node → Permanent Agent.
- Name:
ch18-ws-a. -
Remote root:
/home/jenkins/agentor another disposable path. - Labels:
ch18-remote linux webSocket. - Executors:
1. - Launch method: inbound/agent connects to controller.
Save the node and record the command shape shown by Jenkins. Store the secret privately. The configured node is controller state; no agent process exists yet.
3. Use the controller’s agent.jar or a pinned official image
Direct Java path:
install -d -m 700 "$HOME/ch18-agent"
cd "$HOME/ch18-agent"
curl -fsSLo agent.jar "$JENKINS_URL/jnlpJars/agent.jar"
java -version
java -jar agent.jar -help >/tmp/ch18-agent-help.txt
Container path: the reviewed image baseline is
jenkins/inbound-agent:3391.va_37fa_a_305d6d-2-jdk21.
Record the repository tag and the digest returned for your
architecture before use. Do not substitute latest in
the evidence packet.
4. Connect over WebSocket without echoing the secret
One safe shape uses a secret file mounted/read only by the agent account:
umask 077
printf '%s' "$CH18_AGENT_SECRET" > "$HOME/ch18-agent/secret"
unset CH18_AGENT_SECRET
java -jar "$HOME/ch18-agent/agent.jar" \
-url "$JENKINS_URL" \
-secret @"$HOME/ch18-agent/secret" \
-name 'ch18-ws-a' \
-webSocket \
-workDir "$HOME/ch18-agent/work"
Expected startup evidence includes the Remoting version, work directory, WebSocket connection and connected status. Save only redacted log excerpts.
5. Prove execution identity with a bounded Pipeline
pipeline {
agent { label 'ch18-remote && webSocket' }
options { timeout(time: 3, unit: 'MINUTES') }
stages {
stage('Evidence') {
steps {
sh '''
set -eu
mkdir -p out
{
echo "build=$BUILD_NUMBER"
echo "node=$NODE_NAME"
echo "labels=$NODE_LABELS"
echo "workspace=$WORKSPACE"
id
java -version 2>&1 | head -n 3
} | tee out/agent-context.txt
'''
archiveArtifacts artifacts: 'out/agent-context.txt', fingerprint: true
}
}
}
}
Record build number/URL/source SHA, node name, workspace and archived digest. This baseline proves that later disconnect behavior is not an initial routing defect.
6. Force one controlled disconnect
Start a second Pipeline that records context, then performs a safe
90-second sleep. While it is waiting, stop the
disposable agent process/container. Preserve:
- build number and current stage/step;
- agent connection log before/after termination;
- node offline status/cause;
-
queue state for one additional bounded build requesting
ch18-remote.
Do not immediately loop restarts. First capture the original disconnect and the Jenkins-visible effect.
7. Recover the same worker once
Restart the same agent process/container using the same configured node identity and protected secret. Observe whether the running build resumes, fails or completes according to its actual step state; never claim a generic outcome. Record the result.
Then run a new short evidence build and compare
NODE_NAME, WORKSPACE, Java/Remoting
evidence and archived output with the baseline.
8. Rotate disposable connection material by replacing the node identity
For the rotation drill, treat ch18-ws-a as compromised:
- Stop its agent process.
- Preserve reviewed node/log evidence.
-
Create
ch18-ws-bwith the same capability label but a fresh remote root. - Use the new node’s generated secret; never reuse the old secret.
-
Connect
ch18-ws-band run the evidence Pipeline. -
Retire/delete
ch18-ws-aonly after evidence is captured.
This demonstrates actual identity rotation. Merely restarting an old agent process does not rotate a stable node secret.
9. SSH path: controller-pushed launch with verified server identity
If you have an isolated local SSH host/container, install SSH Build
Agents 3.1097.v868116049892. Use a disposable SSH key
credential scoped to this lab and configure a verified host-key
strategy based on an independently obtained key/fingerprint. The
controller should connect as a least-privilege account whose remote
root is writable but which cannot read JENKINS_HOME.
10. Windows-faithful inbound pattern
The same concepts apply on Windows. A faithful command shape is:
$Work = 'C:\JenkinsAgent'
New-Item -ItemType Directory -Force -Path $Work | Out-Null
# Download agent.jar from the controller and store the secret in a protected file.
java.exe -jar "$Work\agent.jar" `
-url $env:JENKINS_URL `
-secret "@$Work\secret.txt" `
-name 'ch18-win-a' `
-webSocket `
-workDir $Work
For persistent operation, use a dedicated service account or scheduled task with least privilege and defined startup/restart policy. Do not assume a service can or should interact with a user desktop.
11. Prove ephemeral teardown
After the replacement agent has produced retained evidence, terminate it and remove its disposable work directory. Verify that:
- the node is offline/retired;
- its workspace no longer exists;
-
the Jenkins build record and archived
agent-context.txtstill exist; - no secret file was archived;
- the old node identity cannot be used for the replacement.
12. Challenge: choose the failing layer
A new build sits in the queue saying no matching online node is
available. The configured label is correct, the replacement agent
process is running, and java -version is supported, but
the agent log shows an HTTP 400 during the WebSocket handshake.
Which layer should you repair first?
Answer direction: transport/proxy WebSocket handling—not labels, executor count, Jenkinsfile syntax, or controller-local execution.
Knowledge check
Answer before revealing the explanation.
1. Why does the lab first prove the agent works before forcing a disconnect?
It creates a known-good baseline for node identity, Java/Remoting versions, workspace path and build attribution. Without a baseline, reconnect failures can be confused with initial configuration defects.
2. What is the safest compatibility source for a manually launched inbound agent JAR?
Download agent.jar from the target Jenkins
controller at /jnlpJars/agent.jar. That aligns
the Remoting binary with the controller rather than relying on
an arbitrary local copy.
3. How should a compromised inbound secret be rotated in this disposable lab?
Stop the old process, preserve evidence, remove or retire the old node, create a new node name so Jenkins generates new connection material, then connect the replacement. Do not keep reusing the compromised node identity.
4. What makes the Windows path “faithful” even if the learner is on Linux?
The lesson models the same inbound command, supported Java requirement, fixed work directory, non-interactive service/scheduled-task identity, restart behavior and filesystem permissions without requiring a proprietary Windows host.
5. Why is SSH host-key verification part of agent identity?
The Jenkins controller must know it is connecting to the intended SSH server. A valid username/key presented to an unverified host can still be intercepted by a man-in-the-middle.
Official references and version notes
-
Jenkins LTS changelog
and
Java support policy
— lab baseline
Jenkins 2.568.3 LTS; Jenkins system components, including agents, require Java 21 or 25 on this baseline. - Using Jenkins agents and Managing Nodes — distributed execution, node configuration, Windows agent examples, and lifecycle concepts.
-
Jenkins Remoting
and
Launching inbound agents
— obtain
agent.jarfrom the controller; inbound command,-webSocket, work directory, and direct TCP guidance. -
SSH Build Agents plugin
— baseline
3.1097.v868116049892; SSH launch requires verified server identity and least-privilege agent credentials. -
Official Jenkins inbound-agent images
— reviewed lab image line
jenkins/inbound-agent:3391.va_37fa_a_305d6d-2-jdk21. Pin a reviewed tag/digest for repeatable labs rather than usinglatest. - Controller Isolation — keep the built-in node at zero executors and do not use controller-local builds as a connectivity workaround.
- Installing Jenkins — standalone Jenkins uses the supported Jetty/Winstone stack; WebSocket-agent support depends on a compatible servlet/proxy path.
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.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this
address.