---
title: Incidents
description: Record an investigation, link the evidence, and let policy react to an open incident automatically.
---

An incident is a recorded investigation with a severity, affected agents, a
timeline, and links to the actions and audit events that constitute the
evidence.

The reason to use it rather than a ticket in your usual tracker: **policy can
see an open incident**.

## Open one

```bash
curl -X POST $CP/v1/incidents \
  -H "Authorization: Bearer $KEY" \
  -H 'content-type: application/json' \
  -d '{
    "title": "finance-agent refund volume 8× baseline",
    "severity": "HIGH",
    "description": "Refund volume rose sharply at 02:14 UTC with no corresponding claim volume.",
    "affected_agent_ids": ["agt_01JAV…"]
  }'
```

Requires `incident:manage`, held by `SECURITY_ADMIN`, `ADMIN` and `OWNER`.
`incident:read` is broader.

## Policy reacts to it

```json
{
  "id": "rule-incident-requires-approval",
  "name": "Agents under investigation need a human",
  "priority": 890,
  "enabled": true,
  "when": {
    "kind": "condition",
    "id": "c-active-incidents",
    "field": "trust.active_incidents",
    "operator": "gt",
    "value": 0
  },
  "then": {
    "decision": "REQUIRE_APPROVAL",
    "reason": "This agent is subject to an open incident; every action requires a human decision.",
    "approval": { "routingMode": "SINGLE", "requiredApprovals": 1, "requireStepUp": true }
  }
}
```

:::security This is the rule worth having before you need it
Opening an incident then automatically puts the agent behind human approval for
everything, with no further action and no policy edit under pressure.

It is strictly better than remembering to pause the agent, because it degrades
gracefully: the agent keeps working on things a human is willing to approve
rather than stopping entirely. And it is reversible by closing the incident.
:::

A stricter variant, for when you want a hard stop:

```json
{
  "when": {
    "kind": "group",
    "id": "g-incident-dangerous",
    "operator": "and",
    "children": [
      {
        "kind": "condition",
        "id": "c-incidents",
        "field": "trust.active_incidents",
        "operator": "gt",
        "value": 0
      },
      { "kind": "condition", "id": "c-dangerous", "field": "tool.dangerous", "operator": "is_true" }
    ]
  },
  "then": {
    "decision": "BLOCK",
    "reason": "Dangerous tools are refused while an incident is open on this agent."
  }
}
```

Human approval for ordinary work, a hard refusal for anything destructive.

## Risk sees it too

Open incidents feed the risk assessment independently of any policy rule, so an
agent under investigation scores higher even where no rule tests
`trust.active_incidents`.

Two independent effects from one action, which is the intended defence in depth.

## Link the evidence

Attach the actions and audit events that matter as you find them. The value is
not during the incident — it is six months later when someone asks what
happened and the answer is a link rather than a reconstruction.

```bash
veefore logs --decision BLOCK --limit 100
veefore audit list --severity CRITICAL --from 2026-10-03T00:00:00Z
```

## Close it

Closing drops `trust.active_incidents` and lifts whatever rules depended on it.

Write what you found. An incident closed with no note is an incident that
teaches nothing, and the same thing will happen again with nobody recognising
it.

## Severity

| | Use for |
| --- | --- |
| `LOW` | Noted, no containment needed |
| `MEDIUM` | Investigating, agent still operating |
| `HIGH` | Containment in place — paused, suspended, or behind approval |
| `CRITICAL` | Confirmed compromise, or active harm |

Severity should reflect what you have **done**, not how worried you feel.
`HIGH` meaning "contained" makes the list readable at a glance; `HIGH` meaning
"concerning" makes it noise.

## Integrate it

Subscribe a webhook to `incident.created` and open a ticket in your usual
tracker.

```bash
curl -X POST $CP/v1/webhooks \
  -H "Authorization: Bearer $KEY" -H 'content-type: application/json' \
  -d '{
    "name": "incidents-to-tracker",
    "url": "https://hooks.internal.example.com/veefore-incidents",
    "event_types": ["incident.created"]
  }'
```

Keep the Veefore incident as the thing policy reads and the evidence hangs off.
Use your tracker for the human workflow. Trying to make one system do both ends
with policy unable to see the state that matters.

## Related

:::cards

:::card Compromised agent | /operate/runbook-compromised-agent
The runbook that opens an incident.
:::

:::card Trust evidence | /concepts/trust
Where `trust.active_incidents` comes from.
:::

:::card Emergency controls | /operate/emergency-controls
Containment, with blast radius previews.
:::

:::card Security API | /reference/api/security
Incidents and emergency controls.
:::

:::
