Skip to content

Disabled agents ​

Use this runbook to stop an agent from gaining or using authority: a misbehaving agent, a report of abuse, or a sponsor who has left. It covers both a single tenant admin acting on one agent and a security team containing an incident across the organisation.

What "disabled" means ​

An agent has one of three statuses: active, suspended or retired.

  • Suspended: every access token for the agent is revoked at once. New token requests fail with 403 forbidden (reason_code: agent_suspended), status reads and resumes fail, and any approved action fails its fresh authority check at resume and moves to revoked (agent_suspended). Suspension is reversible with a recorded reason.
  • Retired: the same effect, but permanent. A retired agent cannot change status again; register a new agent instead.

Work the gateway already dispatched is not recalled: actions in executing or outcome_unknown continue to their recorded outcome and reconciliation. Suspension is recorded separately from that in-flight work.

Option A: suspend one agent (tenant administrator) ​

  1. Console: Customer tenants → your tenant → Agents → the agent (/app/tenants/:tid/agents/:aid). Check the owner, sponsor, operator and credentials.

  2. Choose Suspend and enter a reason. The API call is:

    sh
    axiom_post /v1/agents/agt_01…/status '{"status":"suspended","reason":"Unexpected refund volume; INC-2291"}'

    Requires agent.write on the agent's tenant (tenant admin, org admin or security admin).

  3. Confirm on the agent detail page that status is suspended and status_reason is recorded. The audit stream carries agent.suspended.

  4. Look for open work: Console: Project → Actions, filtered by agent (GET /v1/projects/:pid/actions?agent=agt_…). Pending or approved actions will be refused at resume. Actions already executing or outcome_unknown need tracking, not cancelling (see Missing receipts).

Option B: contain through an incident (Control) ​

Use an incident when the agent belongs to your organisation's estate and you want emergency denies published to every gateway, acknowledgements tracked and an exportable bundle.

  1. Search for the agent (see Runbooks) and note its grants, descendants and in-flight actions.

  2. Console: Incidents → New incident (/control/orgs/:oid/incidents). Choose targets and options:

    sh
    axiom_post /v1/orgs/$ORG/incidents '{
      "title": "Billing agent issuing unexpected refunds",
      "severity": "high",
      "targets": [{ "type": "agent", "id": "agt_01…" }],
      "suspend_agents": true,
      "revoke_grants": false
    }'

    Target types are agent, credential, grant, tenant, service and project.

  3. What happens immediately:

    • An emergency deny is published per target. Agent and tenant targets also deny each of their grants, so delegates holding descendant grants are blocked too. Every submit and resume checks emergency denies first, so the deny takes effect in Axiom-hosted enforcement at once.
    • With suspend_agents: true, agents your organisation owns are suspended and their tokens revoked. An agent owned by another organisation is never suspended; it is contained by denying its grants on your services and listed as not_suspendable / scoped_via_grants.
    • Tokens bound to a targeted credential are revoked even if the agent stays active.
    • With revoke_grants: true, targeted grant trees are revoked, descendants included. Revocation is permanent; prefer denies when you may want to restore access.
  4. Console: Incident detail (/control/orgs/:oid/incidents/:iid), or GET /v1/incidents/:id. Read:

    FieldMeaning
    emergency_denies[]Each published deny and its target.
    gateways[]Per gateway: when it acknowledged the denies (acked_at) and its freshness.
    local_blockactive, denies, effective_at, hosted_enforced, acknowledged_gateways of total_gateways.
    downstream_revocation[]Agent suspensions, grants, credentials and the count of revoked tokens, each with its current status.
    offline_gateways[]Gateways that have not acknowledged and are not fresh, with cached_bundle_valid_until.
    in_flight_actions[]Pending or approved actions; they are blocked at resume while the deny or suspension is in force.
    dispatched_work[]Work dispatched before the incident opened, with outcome_state and whether the target confirmed it.
  5. The incident status moves from open to contained once every affected gateway has acknowledged every deny. Customer-hosted gateways acknowledge on their next heartbeat; see Unreachable gateways if one does not.

  6. Export the bundle for the record: Incident detail → Export bundle, or

    sh
    axiom_get /v1/incidents/inc_01…/bundle > inc_01….json

    The bundle (axiom.incident.bundle.v1) contains the incident, denies, gateway acknowledgements, local block, downstream revocation, offline gateways, dispatched work, affected action IDs with digests and receipt IDs, and the audit timeline. It omits request fields (params, summary, intent, resource_id, approver comments) and is signed with Axiom's event key (signature, typ: axiom-incident-bundle+jws over the digest of the content). Requires evidence.export.

What the agent's user sees ​

The agent receives 403 forbidden with reason_code: agent_suspended (or emergency_deny on submit while a deny is in force). Approved actions it later tries to resume end in revoked. Nothing it already dispatched is retried.

Next ​

Bringing the agent back is a separate, recorded decision: see Safe release after containment.

Developer preview. Contract version 2026-11-14.