Web app
Findings
A finding is a problem that needs a person: a detector catch, a refused tool call, an unregistered agent, a red-team probe that got through. This is the queue you work them from.
In the web app Findings
When to use this
- Daily triage: open findings, most severe first.
- After promoting a policy, to see what it now stops.
- To record that something was fixed, or that it is accepted and why.
The queue
/app/findings loads GET /api/findings?status=…&severity=…&agent=…&limit=200. The filters are in the URL, so a filtered view can be bookmarked or linked:
- status:
open(the default),resolved,suppressed - severity:
critical,high,medium,low, with clear severity × - agent: a drop-down and filter, with clear agent ×
Each row shows severity, agent (or "unattributed"), type, title with a one-line explanation of the type, the controls it maps to, and when it was raised. The caret expands the evidence in place, without leaving the list; the title opens the full finding. A finding that keeps recurring is one row (its occurrences are counted against the same fingerprint), so the length of the list is the number of distinct problems.
Severity
critical means someone should look today; high, this week. medium and low are worth a look when the first two are clear. Severity comes from the rule or check that raised the finding, not from a setting on this page.
Types
The type column uses plain labels. The ones you will see most:
| Label | Type | What happened |
|---|---|---|
| Guardrail catch | guardrail_detection | A detector matched something in a request, response, retrieved text or tool payload. |
| Contained action | containment | A tool call was stopped or held by a permission, provenance or blast-radius rule, not by a content detector. |
| Security test | redteam | Red-team probes got through without being blocked. |
| Over-blocking | redteam_over_block | Benign control probes were refused. |
| Unregistered agent | shadow_agent | Traffic from an agent nobody registered. |
| No owner | unowned_agent | No one is accountable for the agent. |
| Missed hand-off / Hand-off overdue | missed_escalation, handoff_sla_breach | A conversation should have gone to a person and did not, or did and nobody picked it up. |
| Answered outside its boundary | boundary_breach | The agent answered beyond its declared knowledge boundary. |
| Tool contract changed | mcp_schema_drift | An MCP tool's schema changed after approval. |
The full list is in Detectors and findings.
Detection and containment; contained and would-have-been
A detection finding asks "was the detector right?". A containment finding asks "why did the agent try that?", and is named for what refused it, in one sentence: who tried to do what, with which data, and what happened. The end of the title says whether it took effect:
- (contained) or (held for approval): the rule was enforcing and the call was stopped or sent to Approvals.
- (would have been contained), (would have been held for approval), or a detection titled Would have been blocked on …: the rule is in observe mode. The call went through; the finding records what promoting the rule would change.
…ecxt83e6 high containment support-triage tried to redteam.sim.issue_refund outside
the limits of its permission (contained)
…ded9jv95 high guardrail_detection Would have been blocked on output: PII.CREDIT_CARD,
PII.EMAIL, PII.US_SSN
…4qk46y70 high 3x containment payments-ops tried to payments.transfer, which needs a
person's sign-off first (would have been held for
approval)The finding page
In the web app Findings → a finding
/app/findings/<id> loads GET /api/findings/{id}. The header gives the title, severity, type with its explanation, and when it was raised; below it, the status, the agent (linked), and the controls it maps to, each linking to the control on Compliance.
What we found: the evidence panel
The evidence is drawn according to the type:
- Guardrail catch: the surface, the verdict, and a table of every match with entity, score, a masked excerpt and the OWASP and MITRE ATLAS references. Excerpts are masked when the detector runs; the underlying value is never stored. A link opens the trace with full detector activity.
- Security test and Over-blocking: the probes this finding is about first, each with the literal payload tried and the verdict; then the campaign it came from (probes run, attacks blocked, attacks that got through, legitimate requests blocked), and collapsed tables of results by category and every prompt tried.
- Everything else: the recorded evidence as labelled fields. For a containment finding that includes the tool, the rule, and where the arguments came from. To see the call itself, open the trace from the agent page or the Traces list.
surface output verdict block
entity score masked excerpt reference
PII.EMAIL 0.90 jane**************** LLM02 AML.T0057
PII.CREDIT_CARD 0.95 4111*************** LLM02 AML.T0057
PII.US_SSN 0.95 123-******* LLM02 AML.T0057Resolve or suppress
An open finding has two actions, each with its own required text:
- Mark resolved — "The underlying problem is actually fixed." Needs a note on what you did. The gateway refuses a resolve without one.
- Suppress — "Not acting on it right now." Needs the reason you are accepting it. The finding stays visible under
status=suppressedas a known, accepted issue rather than looking fixed.
Both post the form to the web app, which sends PATCH /api/findings/{id} with status and note or suppression_reason. Afterwards the page shows who resolved or suppressed it and the text they gave. If the finding's own evidence still shows the problem (a posture score below 100%, or attacks that got through), the page warns you before you mark it resolved, and suggests Suppress instead.
Over HTTP, with a token from API tokens:
curl -s -X PATCH http://127.0.0.1:8080/api/findings/fnd_01m4699rz7ecxt83e6 \
-H "Authorization: Bearer $AGENTFOX_API_TOKEN" -H 'Content-Type: application/json' \
-d '{"status":"resolved"}'{"detail":"resolving requires a note describing what was fixed"}Common tasks
| You want to | Run |
|---|---|
| The same queue in a terminal, worst first | agentfox findings |
| Only critical | agentfox findings --severity critical |
| Full records for a script | agentfox findings --json |
| Open a finding by id | ⌘K, paste fnd_… |
| Turn the would-have-been findings into real blocks | agentfox policy enforce baseline |
What can go wrong
- "No findings match." Either nothing has tripped, or no traffic has been recorded; Start here says which.
- A resolved finding comes back. The same problem recurred and raised a new finding. Resolving records a fix; it does not silence the check.
- The type explanation says "it changed the outcome" on a would-have-been detection. Read the title: "Would have been" means observe mode, and the verdict shown in the evidence is the one the policy asked for.
Limits
- There is no bulk resolve or suppress, and no assignee field.
- There is no CLI command to resolve or suppress; use the page or
PATCH /api/findings/{id}. - Findings only exist for what passed through AgentFox.