Kill switch and revocations
Stop an agent, session, user or token across the installation within about a second with maqpna kill, make the revocation durable with an AgentRevocation, and lift it after the incident.
flowchart LR A[Incident:<br/>runaway loop, leaked token,<br/>suspected injection] --> B[maqpna kill<br/>scope + reason] B --> C[Gateway revocation list<br/>break-glass entry] B -. --emit-yaml .-> D[AgentRevocation<br/>durable, every replica] C --> E[Next tool or model call<br/>-32001 reason revoked] D --> E D --> F[Operator suspends or<br/>terminates sessions] E --> G[Investigate:<br/>audit, taint, timeline] G --> H[maqpna revocations delete<br/>or the TTL expires]
Goal#
Stop what an agent is doing now, without waiting for a policy change. You will revoke one session, see its next call denied, list the revocation, and lift it. Then you will see how to make a revocation durable in a cluster and which scope to use for which incident.
A revocation is one kill-switch entry: what is revoked, by whom, why and until when. The MAQPNA gateway checks every tool and model call against the revocation list.
Prerequisites#
- A local MAQPNA:
maqpna dev up(see Your first governed agent). - In a cluster: the
killswitchoradminrole (HelmadminAuth.roles), andkubectlaccess for--emit-yaml.
Choose the scope#
| Situation | Flags |
|---|---|
| One session misbehaves | --session S (with -n NS) |
| Every session of one agent | --agent A (with -n NS) |
| A user's sessions, for example after an account takeover | --user U |
| A leaked session token | --jti J (the token ID; maqpna token inspect shows it) |
| Everything in a namespace | -n NS --all |
| Everything in the installation | --all without -n |
--agent, --session, --user and --jti take globs and can be repeated; all given fields must match.
| Action | Flag | Effect |
|---|---|---|
| block | (default) | Calls of the matching sessions are denied at the gateway. Sessions keep running. |
| suspend | --suspend |
Also suspends the matching sessions (the operator scales their sandboxes down). |
| terminate | --terminate |
Also ends the sessions: sandbox and token deleted, and the user's connected accounts revoked for user revocations. |
--reason is required and is written to the audit ledger and the agent's error. --ttl makes the
revocation expire on its own (0, the default, keeps it until removed).
Steps#
1. Revoke a session#
Load the local admin token, run a session, then revoke it:
eval "$(maqpna dev env)"
maqpna dev run --agent payments-agent --session pay-91c2 -- \
maqpna call --server echo --tool echo --arg text="reconcile batch 7" >/dev/null
maqpna kill -n dev --session pay-91c2 --reason "INC-2041: agent retrying payments" --ttl 4h --yes
revoked (block, namespace dev): breakglass/636e2e0cd4106122
On a terminal, maqpna kill says what it will revoke and asks for confirmation. --yes skips the
question; without a terminal, --yes is required and the command exits 2 without it.
2. See the next call denied#
maqpna dev run --agent payments-agent --session pay-91c2 -- \
maqpna call --server echo --tool echo --arg text="retry batch 7"
Expected output (exit status 3):
error -32001: revoked: calls of this token are blocked by revocation/breakglass/636e2e0cd4106122 (INC-2041: agent retrying payments)
data: {"domain":"maqpna.com","policy":"revocation/breakglass/636e2e0cd4106122","reason":"revoked","rule":""}
The SDKs raise PolicyDenied with reason revoked. Running tool calls are cut off; the gateway enforces
a new revocation within about a second.
3. List revocations#
maqpna revocations list
ID SOURCE ACTION NAMESPACE EXPIRES REASON
breakglass/636e2e0cd4106122 breakglass block dev 2026-10-03T08:01:58.19245Z INC-2041: agent retrying payments
SOURCE is breakglass for entries made through the gateway API (maqpna kill) and file for
AgentRevocation objects, which the operator renders into the gateway's revocation list.
4. Lift it#
maqpna revocations delete breakglass/636e2e0cd4106122 --yes
deleted breakglass/636e2e0cd4106122
The next call from pay-91c2 is allowed again. Lifting a revocation lets what it revoked call tools and
models again, so the command asks for confirmation as kill does.
5. Make it durable in a cluster#
maqpna kill --gateway URL writes a break-glass entry to the gateway that answers. It survives gateway
restarts (a journal next to the ledger), and with state.backend: postgres every replica shares it. To
make the revocation reach every replica on any state backend, survive a database restore, and let the
operator suspend or terminate sessions, also apply it as an AgentRevocation:
maqpna kill -n ai-lab --agent coder --reason "INC-2041" --suspend --emit-yaml | kubectl apply -f -
--emit-yaml prints the manifest:
apiVersion: maqpna.com/v1alpha1
kind: AgentRevocation
metadata:
name: kill-20261003-035310
namespace: ai-lab
spec:
match:
agents: ["coder"]
action: suspend
reason: "INC-2041"
An AgentRevocation created in the gateway namespace (maqpna-system) applies to every namespace;
match.all: true there is the installation-wide kill switch. Set spec.expiresAt for a time limit. Its
short name is arev:
kubectl get arev -A
The chart mirrors break-glass revocations to AgentRevocation objects by default (Helm
gateway.revocationMirror.enabled, which needs gateway.activity.enabled). When the gateway does not
mirror them, as on a local MAQPNA, maqpna kill --suspend or --terminate warns that the operator cannot act on
the sessions, and tells you to apply the manifest as well.
After the kill: investigate#
Follow the runbook for a compromised agent:
maqpna audit verify --gateway "$GW" # the ledger is intact
maqpna audit tail --gateway "$GW" --agent coder --since 1h # what it did
maqpna audit export --gateway "$GW" --agent coder --since 2026-10-01T00:00:00Z --out evidence.json
maqpna -n team-a taint list --gateway "$GW" # which sessions read untrusted input
maqpna mcp tools team-a/github --drift-only # tool definitions that changed
maqpna replay --ledger ledger.jsonl --policy fixed.yaml # what the fixed policy would deny
Rotate what could have leaked (an identity signing key with maqpna keys rotate identity; connected
accounts with maqpna accounts revoke USER PROVIDER), fix the policy or pins, test them, then lift the
revocation.
Verify#
maqpna revocations listshows the entry, with its expiry.- The audit ledger has a
revocation.createrecord with the reason and who created it, a denied call per attempt with reasonrevoked, and arevocation.deleterecord when it is lifted. - The console's kill-switch page lists the same entries:

Troubleshooting#
| Symptom | Cause | Fix |
|---|---|---|
confirmation required and exit 2 |
No terminal and no --yes |
Add --yes; the error prints the full command |
--gateway (or env MAQPNA_GATEWAY_URL) is required unless --emit-yaml is set |
No gateway configured | Pass --gateway, set a context, or use --emit-yaml |
HTTP 403 |
Your token has no killswitch or admin role |
maqpna whoami; map your group to killswitch in adminAuth.roles |
| Calls still allowed on another replica | File state backend: break-glass entries are per replica | Apply the --emit-yaml manifest, or use state.backend: postgres |
Every call is denied with revocation_list_unavailable |
The gateway's revocations file is missing or invalid, and it fails closed | Check the maqpna-revocations ConfigMap and the operator; see Troubleshooting |
--suspend and --terminate are mutually exclusive |
Both given | Pick one |
Next steps#
- Find out what the session read before it went wrong: Taint and prompt-injection containment.
- Preserve and verify the evidence: Audit ledger.
- Inspect and delete sessions: Sessions.
- Alerts for revocation lag and an unavailable list: Monitoring and alerts.
- Command reference:
maqpna kill,maqpna revocations list,maqpna revocations delete.