Entry 020Guides6 min readBy Mandare Labs

AI agent kill switch: what it has to revoke

A kill switch for an AI agent is revocation, not a process stop. It has to refuse the agent's next request, kill the keys, tokens and cards the agent already holds, and keep a record of the refusal. Stopping the process does none of that for a credential that was copied or issued elsewhere.

Stopping the process does not revoke anything

kill -9 on an agent process, or a stopped container, ends that process. It does not touch the credentials the agent was given. An API key copied from its environment still works. A virtual card still authorizes. A token already handed to a sub-agent still passes the check at the other end.

A kill switch that deserves the name does four things:

  1. Refuses the next request. The checkpoint that accepts the agent's credentials looks at revocation state on every request, not once at login.
  2. Kills what the agent already holds. Keys, tokens and cards are revoked at the place that honors them, not only at the place that handed them out.
  3. Works when the network does not. If the kill needs a call to a third party to take effect, whoever can jam that call can keep the agent running.
  4. Leaves a record. The refusal after the kill is evidence that the kill landed, and when.

Each credential type has its own revoke call, and each has a delay or a limit. The sections below take them in turn, using the providers' own documentation. The four layers that stop a runaway loop are a different question: that entry is about limits that trip by themselves, this one is about the human pressing the button.

Provider API keys can be switched off, for everyone who holds them

Anthropic's Admin API documents an update call for API keys (read 3 November 2026):

POST /v1/organizations/api_keys/{api_key_id}
# body: {"status": "active" | "inactive" | "archived"}

The page lists active, archived and inactive as the settable values, and expired as a fourth status a key can report. The page does not say whether an inactive key can be switched back, so a runbook should not assume it either way.

The limit is structural. A provider key is shared by whatever holds it. If three agents run on one key, switching the key off stops all three. Per-agent keys make the switch narrower, at the cost of managing more keys, and the key still sits in the agent's environment until it is revoked. A key that never leaves a vault is a different design, covered in what proof of possession fixes after a key theft.

OAuth revocation leaves self-contained tokens to the deployment

RFC 7009, OAuth 2.0 Token Revocation (August 2013), defines a revocation endpoint. The client posts the token and an optional token_type_hint. The requirement is asymmetric between the two token types:

Implementations MUST support the revocation of refresh tokens and SHOULD support the revocation of access tokens

Section 3 then describes why access tokens are harder: they "may be self-contained so that a resource server needs no further interaction with an authorization server". For that case the RFC says some "(currently non-standardized) backend interaction between the authorization server and the resource server may be used when immediate access token revocation is desired."

In practice a self-contained access token stays valid until it expires, unless the resource server asks someone whether it is still good. Two consequences follow for agents:

Cards: inactive is a pause, canceled is permanent

Stripe's Issuing API takes a status on the card update call. From the page, read 3 November 2026:

StatusWhat Stripe documents
active"The card can approve authorizations."
inactive"The card will decline authorizations with the card_inactive reason."
canceled"The card will decline authorizations with the card_canceled reason. This status is permanent."

The call is the same POST https://api.stripe.com/v1/issuing/cards/{CARD_ID} shown on the page, with -d status=canceled. Stripe also accepts a cancellation_reason of lost or stolen.

Two decisions sit inside this table. First, whether a kill should pause or end: a permanent cancel cannot be reversed, so a pause is the safer default for an agent you may want back. Second, who holds the Stripe secret key. If the agent's environment can call this endpoint, the agent can also change its own card. The same reasoning is in virtual card limits for an AI agent: the control belongs where the agent cannot edit it.

A published status list is only as fresh as its cache

When many parties need to check one agent's status, a revocation list is the usual answer. The IETF Token Status List draft (version 21, 21 June 2026, submitted to the IESG, not yet an RFC) packs one status per token into a compressed bit array. Section 7.1 defines the status values, including these three (it also reserves application-specific ones):

The draft's own words on freshness matter more than the format. The ttl claim "MUST specify the maximum amount of time, in seconds, that the Status List Token can be cached by a consumer" (section 5.1). Section 8.4 says a list "only conveys information about the state of Referenced Tokens at the time the Status List Token was issued". So the time from a kill to the last relying party seeing it is bounded by the longest ttl any consumer honors. A list with a one-hour ttl is a kill switch with a one-hour tail for every consumer that caches it.

This is the central trade-off. A shared list scales to many checkers and tolerates their downtime, and it is eventually consistent. A check against the revoker's local state on every request is immediate, and it only covers the checkpoints that can see that state. Pick per checkpoint, and state the delay.

Where Mandare fits

Mandare's kill switch is the second kind: local state, read on every request. The commands are in the CLI reference:

mandare kill <agent-did> [--reason <text>]
mandare kill --mandate <id>     # the permission slip dies; the agent survives
mandare kill --all              # halt the whole door
mandare reinstate <agent-did>

As of v0.1.0 (checked against the public repository at commit 327442e, 3 October 2026), the CLI documentation says the kill is "local, offline, fail-closed": it writes the revocation entry and flips the revocation projection in one transaction, revokes the actor's vault tokens, and revokes bound virtual cards. The gateway reads the revocation state before spend work on every request. The repository's captured demo (docs/demos/S3-dead-paper-demo.txt, cuts marked) shows the sequence, including the refusal landing in the ledger:

pnpm demo:dead-paperlive capture
$ mandare kill did:mandare:dev-agent
  KILLED did:mandare:dev-agent
    subject:      agent:did:mandare:dev-agent
    ledger entry: a9f8582dd52c1821f4018b8439e6e86975c4550731404e66dcef46ab9d47d4b1 (seq 3)
…
    vault:        1 live token(s) revoked
…
    status:       written to the LOCAL ledger — the gateway fails closed on its next request (offline, un-jammable)

[agent]  valid signed call AFTER the kill  → 403 AGENT_REVOKED
         the refusal is ledger entry fc84d99646ba90a5…
…
subjects:
  REVOKED    agent:did:mandare:dev-agent  (index 0, @ 2026-09-27T05:32:01.506Z, entry a9f8582dd52c…)
…

The concepts page adds that a dead witness never blocks a kill, and that the same revocation records render into one Token Status List bitstring. Limits, stated next to the claims they limit:

The threat model lists the wider residuals, and there is no external security audit yet. For the design choice behind a kill that refuses when it cannot check, see fail closed or fail open.

Questions

What is the difference between stopping an AI agent and revoking its access?

Stopping ends one process. Revoking ends what the credentials can do, wherever they are used. A stolen or copied key keeps working after the process stops, so a kill switch has to act on the credentials and on the checkpoint that accepts them.

How fast does a revocation take effect?

It depends on who checks and how often. A check against local state on every request takes effect on the next request. A check against a cached status list takes effect when the cache expires: the Token Status List draft makes the publisher state a maximum cache time, in seconds.

Should a kill switch pause an agent or end it permanently?

Both are useful, and some systems separate them. Stripe has an inactive card status and a canceled one, and calls canceled permanent. The Token Status List draft has SUSPENDED and INVALID. Decide in advance which one a kill uses, because a permanent revoke cannot be undone.

Can the agent be allowed to trigger its own kill switch?

Only if you accept that whatever can kill can usually also reinstate. In Mandare's current release the kill signs a ledger entry with the door's key, so an environment that can kill holds operator-level authority. The safer layout keeps the kill with a human or a supervising process.

Sources

  1. Update API Key (Claude Developer Platform) · Anthropic
  2. RFC 7009: OAuth 2.0 Token Revocation · IETF · 2013-08
  3. Update a card (Stripe API reference, Issuing) · Stripe
  4. draft-ietf-oauth-status-list-21: Token Status List (TSL) · IETF OAuth Working Group · 2026-06-21

Run it yourself: 3 commands, no API keys.

github.com/mandarelabs/mandare →
← All journal entries