EMERGENCY STOP

Stop one agent, a whole team, or everything, now

Checked first, before every other control, and honest about refusing new work rather than recalling old.

You stop a misbehaving agent by engaging a kill switch scoped to one agent, one team or the whole estate, and it is the first thing the governance pipeline checks — ahead of lifecycle status, permissions, budgets and every policy — so nothing further down can outrank it. Engaging one is an admin action, requires a stated reason and cannot be done anonymously, because the audit entry is the only account anyone will ever have of why an entire fleet stopped; engagement and release both append to the hash-chained audit log and publish an event. A global switch reaches every governed subject, a team switch matches the subject’s team case-insensitively on the reasoning that a team name is typed by a human under incident pressure, and an agent switch matches the subject id exactly — which also stops a developer seat, since a seat is a governed subject with its own prefixed id. The predicate that answers whether a switch reaches a subject is written once and exported, so the same function the gateway refuses a request with is the filter that decides which switches are compiled into a seat’s signed policy bundle. What a switch is, honestly, is admission control: it refuses new work rather than recalling a request already dispatched upstream.
Scopes
global, team matched case-insensitively, or one agent id exactly
Where it runs
First in the pipeline, before lifecycle, permissions, budget and policy
Who and how
Admin only, with a stated reason; engaging and releasing are both audited
Also reaches
Token counting, the model catalogue, and a seat’s signed policy bundle
It is admission controlIt refuses new work; it cannot recall a dispatched request
On this page
before the fix

Revoking the key, redeploying, and phoning the team that owns it

The first instinct is to revoke the credential, and it works — on the next authentication attempt, for the calls that use that credential, in the systems where you can find it. What it does not do is answer quickly enough when the question is which credential, because an agent that has been running for six months may hold one key at the gateway and a second one directly against a vendor, and revoking the first tells you nothing about the second. Revocation is also indiscriminate in the wrong direction: it stops everything that agent does, which is right in an incident and wrong when what you needed was to stop one tool.

The second is to redeploy with the agent disabled, which is the honest answer in most estates and takes as long as a deploy takes. That is minutes at best, and it depends on the pipeline being healthy at the moment you need it least. It also requires the team that owns the agent to be awake, which is usually the actual bottleneck: the person who can stop the agent and the person who noticed the problem are different people in different time zones.

The third is to suspend the agent in a console and assume that covered it. That is closer, and the gap is specific and was found in this product rather than theorised about: token counting and the model-catalogue routes deliberately skip the trace-opening path, because they execute nothing and opening a trace for a size check would pollute the evidence record — and in skipping it they also skipped the agent-status and kill-switch checks, so a frozen agent could still price prompts and enumerate models. Those checks now run on all three routes. An emergency stop an agent can still work around is not a stop.

The fourth is the one nobody plans for, which is what a stop means for a developer subscription running on a laptop. There is no network path to intercept, the vendor’s credential is not yours, and the enforcement point is the vendor’s own administrator hook deciding locally against a signed bundle. A stop there has to reach the artefact the device already holds, which is why the switch predicate is one exported function rather than two implementations that could differ by one character.

the procedure

How to actually do it

Each step is something you can go and do. Where a step depends on a decision somebody has to make rather than a setting somebody has to change, it says so.

  1. 01

    Decide the blast radius before you engage anything

    Three scopes, and the choice is a judgement about what you know. One agent, when the misbehaviour is attributable and contained. One team, when you do not yet know which agent and the team is a meaningful boundary — a newly registered agent joining that team is stopped without anyone remembering to add it. Everything, when the answer to which agents are affected is not yet known.
  2. 02

    Engage it, with a reason somebody will read at three in the morning

    Engagement is admin-only and the reason is mandatory. Write what you know rather than a ticket number: the refusal returned to every affected caller names the scope, the person who engaged it and the reason they gave, and the audit entry is the only account anyone will have afterwards of why an entire fleet stopped.
  3. 03

    Confirm what it reached and what it did not

    New requests from every subject the scope selects are refused with a 403 at the first check in the pipeline, and the attempt is still recorded. Requests already dispatched upstream are not recalled, and a tool call already executing at an upstream server has already happened. Check for in-flight work rather than assuming the switch covered it.
  4. 04

    Convert a temporary stop into a durable one

    A kill switch is an emergency posture, not a lifecycle state. If the agent should not run again until somebody reviews it, suspend it: suspension flips the status and the evaluator refuses that agent on its lifecycle check, after the kill-switch check and before permissions, budgets or any policy. The transition is audited and published as an event, so paging and ticketing systems learn about it without polling.
  5. 05

    Revoke the credential where a person or a process is holding it

    Revocation is one write and takes effect on the next authentication attempt, so any process still holding the key starts failing. Unknown, revoked and expired keys are logged as three different operational events and the caller receives one identical message for all of them, because telling somebody their key merely expired confirms it was once valid.
  6. 06

    Release deliberately, and read the audit entries afterwards

    Releasing is admin-only too and is audited in the same chain as the engagement, so the window during which the estate was stopped has two ends with named people on both. Read the blocked traces from that window as part of the incident review: every refusal opened a trace, so what the agent tried while it was stopped is evidence rather than a gap.

Three scopes, one predicate, and why the team match is case-insensitive

Scope is deliberately three values rather than four. A global switch reaches every governed subject in the estate, agents and seats alike. A team switch compares team names case-insensitively, on the reasoning that a team name is being typed by a human under incident pressure and a capital letter should not be the difference between a fleet stopping and not. An agent switch matches the subject id exactly, and because a subscription seat is a governed subject with its own prefixed id, the same scope value stops a seat — a fourth scope would have to be threaded through the store, the API and the console to make a distinction the predicate already makes from the id.

That asymmetry is worth knowing before you name things, because policy scope does not share it. Kill switches and policy scope both match on team case-insensitively, and both match on tags case-sensitively: Finance and finance are the same team to a kill switch, while pci and PCI are two different tags to a policy.

The predicate that answers whether a switch reaches a subject is written once and exported, and that is load-bearing rather than tidy. The same function the gateway stops a request with is the filter that decides which switches are compiled into an endpoint seat’s signed policy bundle. A second copy that was stricter by one character would omit an engaged switch from the artefact, and the big red button would be pressed in the console and reach nothing at all on the device.

A released switch reaches nobody, immediately, on the next request. There is no propagation step on the gateway path because the resolver loads the agent, its roles, the switches currently in force and its recent spend window live from the store on every request. The one deliberate exception is the seat bundle, which is a snapshot by design and is bounded by a freshness window rather than read live — a hook that phoned home would convert every outage, slow network and DNS failure into a silent policy bypass, because every vendor fails open when a hook times out.

global
Every governed subject, refused with a 403 naming the scope, the person who engaged it and the reason they gave.
team
Matched against the subject’s team, case-insensitively. Everything else about the subject is ignored, so a newly registered agent joining that team is stopped without anyone having to add it.
agent
One subject id. Pointed at a seat id, it stops that seat’s device-side enforcement at the next bundle it holds.
Never licence-gated
The gateway, permissions, redaction, approvals, budgets, rate limits, the flight recorder, the audit chain and the kill switch are present in every tier and are never gated. A licence problem that degraded a customer’s safety controls is the one failure a governance product cannot have.

What a stop reaches, and the two places it does not

Inside the pipeline, the reach is total by construction: the switch is the first check, ahead of lifecycle status, deny-by-default permissions, budget and rate ceilings and every policy, so nothing configured further down can outrank it. That ordering exists because a kill switch is an operator’s emergency stop and there is no sense evaluating a policy against an agent somebody has already stopped.

It also runs on the routes that execute nothing. Token counting and the model-catalogue routes skip the trace-opening path on purpose, because opening a trace for a pre-flight size check would pollute the evidence record rather than protect anything — and they once skipped the agent-status and kill-switch checks along with it, so a frozen agent could still price prompts and enumerate models. The product’s own known-issues log records that gap and its closure, which is the sort of thing worth asking every vendor for.

The first place it does not reach is a request already dispatched. A switch is admission control: it refuses new work, and a call already on the wire to a provider completes and is billed. On the tool path the equivalent is starker, because a tool that has already run has already had its effect — which is why a policy verdict on a tool result is reported as a plain block rather than as a resumable approval, and why the refusal states explicitly that the tool ran and its output was withheld.

The second is an agent that does not route through Token Observe at all. A switch cannot stop a process talking directly to a vendor API, and it cannot end a vendor subscription: retiring a seat or revoking its credential stops the seat reaching Token Observe and stops bundles being issued, and the vendor’s own administration console is what ends the entitlement. On a managed seat the enforcement is the vendor’s administrator hook, whose non-zero exit blocks a tool call before it executes, deciding locally against a signed bundle — and no bundle, a malformed or unsigned one, a key the device does not trust, another seat’s bundle, one past its expiry or its freshness bound, and the hook’s own time budget all resolve to a deny.

The graded options underneath the big red button

A kill switch is the blunt instrument, and reaching for it when something narrower would do is how an incident becomes an outage. Underneath it sit four controls that stop less and are audited just as well, and knowing which one to reach for is most of the skill in operating this.

The narrowest is a policy. A rule can block one action for one agent rather than stopping the agent, and its suspend_agent action does both — it blocks the request and takes the agent out of service, writing the status change into the audit log. If that status write fails the block still stands, because losing the suspension is serious and is not a reason to let the request through. A policy is also the only one of these you can rehearse: run it in shadow mode and read what it would have stopped before it stops anything.

Next is the lifecycle state. Suspension flips the status and the evaluator refuses that agent on its lifecycle check, taken at the single decision point rather than at the door, so the attempt is still recorded against the trace opened earlier instead of vanishing. Suspending and retiring both free licensed capacity and neither is ever refused on licence grounds — a limit that blocked its own remedy would be an outage wearing a licence’s clothes.

Then the credential, which is the right tool when the problem is who is holding the key rather than what the agent is doing. And finally the budget, which is the slowest brake and the only one that acts without a person: a per-request, hourly, daily or monthly ceiling refuses the call before egress once the money crosses the line. It is worth having configured before an incident precisely because it does not need somebody to notice.

Refusals are still evidence
A stopped agent’s attempts are recorded. The trace opens before the verdict, so what an agent tried while it was stopped is available afterwards rather than being a gap in the timeline.
The refusal is typed
Callers receive a typed code — ACP_KILL_SWITCH_ENGAGED for the switch, ACP_AGENT_NOT_ACTIVE for a suspended or retired agent — so a client can branch on the reason rather than parsing prose.
Suspension is published, not just logged
A transition into suspended is published as an agent.suspended event as well as audited, because suspension is an operational fact other systems page and ticket on rather than something only an auditor reads later.
the bit that remains

What this still does not solve

Doing everything above leaves a residue. It is smaller than what you started with and it is not nothing, and knowing its shape in advance is the difference between a control you trust correctly and one you trust too much.

  • A kill switch cannot recall a request already dispatched to a provider, and it cannot undo a tool call that has already executed upstream. It is admission control, and the honest sentence about any such switch is that it refuses new work.
  • It cannot stop an agent that does not route through Token Observe. A process holding a vendor credential and calling the API directly is unaffected, which makes the stop only as broad as your coverage — and coverage is a discovery question with its own answer.
  • It cannot revoke a vendor subscription. Retiring a seat or revoking its credential stops that seat reaching Token Observe and stops bundles being issued, and only the vendor’s own administration console ends the entitlement.
  • Nothing engages it automatically. A policy can block a request and suspend the agent that made it, but a team or global stop is a person’s decision with a stated reason, and no threshold in the product pulls that lever on its own.

If one of those residues is the thing that actually worries you, that is the conversation worth having rather than the one about the steps above it.

Talk it through

Does the kill switch stop calls that are already in flight?

No. It is checked at the start of every governed request, so it refuses new work rather than recalling a call already dispatched upstream. What it covers is broader than the model gateway: it runs on token counting and the model-catalogue routes too, which deliberately open no trace because they execute nothing and once skipped the check with them, and it is the same predicate that filters an engaged switch into an endpoint seat’s signed policy bundle. Engaging or releasing one is admin-only, requires a stated reason and is written into the audit chain.

How fast does a stop take effect?

On the agent’s next governed request. There is no propagation step and no redeployment, because the resolver loads the agent, its roles and the switches currently in force live from the store on every request rather than from an exported copy. The one exception is a developer seat, where enforcement happens inside the vendor’s own administrator hook against a signed bundle it already holds, so a stop reaches that device at the next bundle within its freshness window — a hook that phoned home would fail open on every network problem, which is why it does not.

Should we suspend the agent or engage a kill switch?

Engage the switch when you need to stop something now and may want it back shortly, particularly when the scope is a team or the whole estate. Suspend the agent when the decision is that it should not run again until somebody reviews it: suspension is a lifecycle state, it is refused at the evaluator’s lifecycle check after the kill-switch check, it is audited with the previous status beside the new one, and it is published as an event so paging and ticketing systems learn about it. Suspending and retiring both free licensed capacity, and neither is ever refused on licence grounds.

Who can engage it, and what gets recorded?

Admin rank, with a mandatory reason, and it cannot be done anonymously. Engagement and release both append to the hash-chained audit log and publish an event, and the reason travels into the 403 that every affected caller receives, alongside the scope and the person who engaged it. Control-plane access is session-only — there is no admin bearer token — because every control-plane action being attributable to a named person is what makes the audit log evidence rather than a log file.

Can we make it engage automatically on a threshold?

Not the switch itself. What can act without a person is a policy: its suspend_agent action blocks the offending request and takes that agent out of service, writing the status change into the audit log, and if the status write fails the block still stands. Budgets are the other automatic brake, refusing a call before egress once a ceiling would be crossed. A team-wide or global stop stays a human decision with a stated reason, because the audit entry is the only account anyone will have of why an entire fleet stopped, and a threshold cannot write that sentence.

get in touch

Describe the version of this you actually have.

The steps above are the general shape. Which of them matter, and in what order, depends on what your agents do and which of them worries you — say that and you will get a straight answer, including when the answer is that Token Observe is not what you need for it.

no form · no qualification step · no sales desk · the other three ways in