All lessons › Function E — The Agentic SOC › Respond — From a Conclusion to the Actor Stopped
E4.5

The fleet kill switch

E4
▶
Lightboard recording

Not recorded yet. The lesson below is complete and runnable today — the video is added later without touching this page.

Video placeholderpublishes automatically from recordings/E4.5.mp4
Risk

Terminating agents while their tokens stay valid leaves the persistence in place. In the incident, third-party access ended when the third party revoked keys — not when the agents stopped.

Control

A tested kill path independent of the agent execution path, snapshot before terminate, revocation in the same action, a measured activation target and named authority to pull it (C8.3).

The lab

Kill a fleet, then check what the revoked-credential step changes about what an attacker still holds afterwards.

◉Use case relevance

The third party's exposure ended when the third party revoked its keys, not when the agents were stopped. Terminating a fleet whose credentials stay valid moves the incident rather than ending it.

At CyberTravels. Imports D1.9's coverage() rather than recomputing it, so the red team and the SOC cannot disagree about the number mid-incident. What this adds is the ordering: snapshot before terminate, and revoke in the same action. A plan that terminates without revoking leaves the tokens valid, and the first version of this check called such a plan correct — the comment in the file says why.

◴What this lesson is — Day 0, Day 1, Day 2

A kill path independent of the agent's own execution path, in the order that matters — snapshot before terminate, revoke in the same action rather than after it, because terminating agents whose tokens stay valid leaves the persistence in place.

Day 0 — why

Terminating agents while their credentials stay valid leaves the persistence exactly where it was.

Day 1 — how

One selector, one action, and revocation rather than termination.

Day 2 — measure

What the credentials can still do after the processes stop. That is the number that says whether containment ended the incident.

Measure this

what to measuredenominator or target
what the credentials can still do after the processes stopcount of actions still authorised

▦The framework, and how it works

   one selector, one action, in this order

      snapshot state + transcripts     <- or the incident is unreconstructable
              |
           terminate
              |
        revoke credentials             <- or the tokens outlive the agents

   the path must not run through the fleet
      via orchestrator API      NO   depends on the thing being stopped
      via the agent sidecar     NO   workload credentials
      out-of-band control plane YES  separate creds, separate network

   tested quarterly, under partial failure, target under 5 minutes

E4.3 contained one agent. This is the control for the case where the unit of containment is the fleet.

The source incident makes the requirement concrete in one detail: third-party access ended when the third party revoked its keys — not when the agents stopped. Terminating agents while their credentials stay valid leaves the persistence exactly where it was, and moves the incident rather than ending it.

So the kill switch is one action with four properties:

One selector. Experiment, model, time window, or everything. Not a runbook of forty steps executed under pressure.

Independent of the agent execution path. Separate credentials, separate network path, so a compromised fleet cannot interfere with the thing that stops it.

Evidence-preserving. Snapshot state and transcripts before terminating. An incident you cannot reconstruct afterwards has been survived, not handled.

Revocation in the same action. Terminate and revoke together, or the attacker keeps what the agents were holding.

Plus the operational half: a tested activation path with a measured target under five minutes, quarterly tests including partial-failure conditions, and a documented authority to activate that does not require consensus. A kill switch nobody has pulled is a hypothesis.

Anchor → E1.0. Contain, when the unit is the fleet — and the detail that decides whether the interval ended at all. Terminating agents whose credentials stay valid leaves the persistence in place and moves the incident rather than ending it.

2 · Kill the fleet, and count what is left

3 · Preserve first, then terminate

4 · Where it breaks — the path that runs through the fleet

activation pathruns through the fleet?credentialsusable if the fleet is compromised
via the orchestrator APIyessharedno
via the agent's own sidecaryesthe workload'sno
out-of-band control planenoseparateyes
The first two are the ones teams actually build, and both run through the thing they are trying to stop. The switch has to be independent in credentials AND in network path, or it is a request.

5 · Verify — a switch nobody has pulled is a hypothesis

6 · The procedure, as a skill

Terminating eight agents without revoking leaves eight tokens valid for up to 72 hours. The skill tests both paths, checks that killing preserves the evidence for the incident that triggered it, and measures the whole thing against a target.

▶Real time execution as skill

The skill — skills/response/fleet-kill-switch-test/SKILL.md

name: fleet-kill-switch-test
description: >-
  Test a fleet-wide stop for what it leaves behind — valid tokens, destroyed
  evidence, and the runs that should have been preserved — and measure how long
  the whole thing takes. Use before relying on a kill switch, and after
  designing one.
allowed-tools: Read, Grep, Glob

Terminating the agents leaves every token valid

A fleet kill switch usually terminates workloads. Termination does not revoke credentials, so every token the fleet held stays valid until it expires — up to seventy-two hours of an attacker being able to act as agents that no longer exist. And a kill that does not preserve first destroys the evidence for the incident that triggered it.

When to use this

Before a kill switch is relied on, after it is built, and once a year as a rehearsal.

Procedure

1 — Terminate only, and count what stays valid. Tokens, sessions, outstanding delegated grants. This is the baseline failure and it is invisible in a design review.

2 — Terminate and revoke together, and re-count. Zero is the target. If revocation is a separate runbook step performed by a different team, it will not happen at speed.

3 — Check evidence preservation. Kill with and without preservation, then attempt the reconstruction. A kill switch that destroys the run records is a containment that ends the investigation.

4 — Test selectivity. Stop one agent, one class, the whole fleet. A switch with only the last setting will not be used until it is far too late, which is the same as not having one.

5 — Measure the time. Decision to last agent stopped and last token revoked. Set a target and report against it; an untimed rehearsal is a demonstration.

Example

Input — the fixture committed at the top of scripts/fleet_kill_switch_test.py. Edit it and re-run: the buckets, counts and verdicts below are derived from it, not hard-coded.

Output — the opening lines of a real run:

terminate only        : 8 agents stopped, 8 tokens still valid for up to 72h
terminate and revoke  : 8 agents stopped, 0 tokens still valid

In the source incident, third-party access ended when the third party
revoked its keys - not when the agents stopped. Stopping the process is
the visible half of containment and the smaller one.
terminate first   terminate -> revoke credentials                           reconstructable=False
preserve first    snapshot state and transcripts -> terminate -> revoke credentialsreconstructable=True

The run continues past this. test_skills.py executes the script on every build, with no model configured — so what CI proves is that it runs and refuses legibly, not that it prints these lines. The output above is a recorded run against a real model, and nothing re-diffs it: a model's answer is not reproducible, and this repository does not claim otherwise anywhere it can be checked.

Output contract

{
  "fleet": {"agents": 0, "tokens": 0},
  "terminate_only": {"tokens_valid_after": 0, "max_validity_hours": 0},
  "terminate_and_revoke": {"tokens_valid_after": 0},
  "preservation": {"preserved": true, "reconstructable": true},
  "selectivity": [{"scope": "one|class|fleet", "supported": true}],
  "timing": {"target_minutes": 0.0, "measured_minutes": 0.0}
}

Failure modes

  • Terminating without revoking. The credentials outlive the workloads.
  • Killing before preserving. The incident becomes unreconstructable.
  • A fleet-only switch. Nobody uses it until the whole estate is on fire.

Three ways to do this lesson. Pick one. They run the same procedure against the same code — what changes is who drives it, and how much you see.

1In your AI agent — you are taught

The agent reads the lesson, explains the idea, fetches the code, runs the check and answers your questions as you go. This is the one to take if you are here to learn.

Install it, once. From the folder you cloned. --all does every agent it finds on your machine:

python3 scripts/install_skills.py --all --lessons E4.5

Then restart your agent and open it in that folder. On Windows, if python3 says Python was not found, use python instead.

Then pick e4-5-the-fleet-kill-switch:

agentinstall just for this agentstart it
Claude Codepython3 scripts/install_skills.py --tool claude --lessons E4.5type /e4-5-the-fleet-kill-switch
GitHub Copilot (VS Code)python3 scripts/install_skills.py --tool copilot --lessons E4.5type /e4-5-the-fleet-kill-switch in Chat
Cursorpython3 scripts/install_skills.py --tool cursor --lessons E4.5type / in Agent chat and search for it
Codexpython3 scripts/install_skills.py --tool agents --lessons E4.5type $e4-5-the-fleet-kill-switch, or run /skills

2As one Python command — you just run it

No agent, no conversation. The same lesson executes and prints the same readback. Take this one if you have no assistant, if you are reviewing rather than learning, or if you want the result without the teaching around it.

python3 scripts/lesson.py E4.5

3Read the code, and the difference — nothing runs

Neither of the above, and no model needed. The first command writes CyberTravels exactly as it stood at the end of this lesson; the second prints the diff — the lines this lesson added or changed, and nothing from any later one.

python3 scripts/checkpoint.py --at E4.5 --out work/cybertravels
python3 scripts/checkpoint.py --at E4.5 --diff

On Windows, type python wherever these say python3 — and use \ instead of / in the paths. Everything else is identical. A0.0 step 2 explains why.

Ways 1 and 2 need a model; way 3 does not. A signed-in Claude Code CLI needs no API key, and any OpenAI-compatible endpoint works too. With neither, the audit exits 2 and says so rather than inventing an answer. A0.0 sets this up.

Ways 1 and 2 both end with the same readback: What I did, What changed, The number and Read this next. A step that was skipped or refused is reported as exactly that, never as a pass.

If you did the last lesson’s challenge, expect this to stop. Most challenges ask you to edit the code, and ways 1 and 2 will not overwrite your edits: you get stopped, not a failure, with two options — --out for a fresh folder that keeps your work, or --force to discard it and start this lesson clean.

✓What you just proved

Terminating eight agents without revoking leaves all eight tokens valid for up to 72 hours; terminating and revoking together leaves none. Preserving before terminating keeps the incident reconstructable and terminating first does not. Only one of three plausible activation paths survives the fleet being compromised, and of four quarterly tests one was never run and one ran 6.8 minutes against a five-minute target, with the revocation step the part that slowed.

✎Your turn

Ask who in your organisation is allowed to stop every agent at once, without asking anyone. If the answer is a committee, you do not have a kill switch — you have an escalation path, and they take different amounts of time.

→Where this leaves you

What you can do now. You can fix the contain interval before the incident — actions classified on reversibility and radius, tiers derived from that rather than from their author, containment timed against a measured breakout, and a fleet stop that revokes as well as terminates.

What you still cannot do. The incident is contained and nothing has been learned. No control has been named, no measurement re-read, and the policy that permitted it is exactly as it was — so the next occurrence starts every interval again from the top.

Chapter E5 is the last interval, recover: the root cause record, the layer the fix belongs in, the re-measurement that decides whether it worked, and the policy change with the incident attached.

Tools used

VaultKubernetes

Skill source: skills/response/fleet-kill-switch-test

← PreviousE4.4 · Stop authority — who halts a fleet, and how long it takes