MAQPNADocs

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 killswitch or admin role (Helm adminAuth.roles), and kubectl access 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.

Revoke a session with the kill switch, then lift the revocation.cast

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 list shows the entry, with its expiry.
  • The audit ledger has a revocation.create record with the reason and who created it, a denied call per attempt with reason revoked, and a revocation.delete record when it is lifted.
  • The console's kill-switch page lists the same entries:

The console kill-switch page

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#