Chapter 18Lesson 02~180 minutes

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.

Hands-onInbound agentReconnectSecret rotationWindows modelCleanup

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.

Never copy the real inbound secret into this lesson, a Jenkinsfile, terminal transcript, screenshot, Git repository or evidence ZIP. Use a protected environment variable or secret file only on the disposable worker.

2. Create the inbound node first

  1. Manage Jenkins → Nodes → New Node → Permanent Agent.
  2. Name: ch18-ws-a.
  3. Remote root: /home/jenkins/agent or another disposable path.
  4. Labels: ch18-remote linux webSocket.
  5. Executors: 1.
  6. 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:

  1. Stop its agent process.
  2. Preserve reviewed node/log evidence.
  3. Create ch18-ws-b with the same capability label but a fresh remote root.
  4. Use the new node’s generated secret; never reuse the old secret.
  5. Connect ch18-ws-b and run the evidence Pipeline.
  6. Retire/delete ch18-ws-a only 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.

Do not select a “no verification” host-key strategy. If the host key changed unexpectedly, preserve the old/new fingerprints and determine whether the worker was legitimately rebuilt before updating trust.

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.txt still 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.

Next lesson

Configuration, Design Choices, and Tradeoffs

Compare SSH, inbound TCP and WebSocket by network direction and trust; then choose service vs. interactive and static vs. ephemeral worker lifecycle.

Knowledge check

Answer before revealing the explanation.

1. Why does the lab first prove the agent works before forcing a disconnect?

2. What is the safest compatibility source for a manually launched inbound agent JAR?

3. How should a compromised inbound secret be rotated in this disposable lab?

4. What makes the Windows path “faithful” even if the learner is on Linux?

5. Why is SSH host-key verification part of agent identity?

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.jar from 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 using latest.
  • 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.
Assumption timestamp: 2026-09-17. Recheck Jenkins LTS/Java support, Remoting/inbound-agent versions, SSH Build Agents advisories, reverse-proxy WebSocket behavior, and Windows service guidance before repeating the lab later.

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.