Every scan type — regardless of tool — parses into the same Finding model, so triage works the same way everywhere.
Status lifecycle
open → acknowledged / resolved / suppressed
Set one finding at a time from its detail modal, or in bulk using the select button to toggle bulk selection mode, or from the Django admin.

Bulk actions
The Select toggle (top-right of the filter bar on /findings/) adds a checkbox column. Selected rows survive pagination. After selection, pick an action, and hit Apply.
Deduplication
Findings are deduplicated per (agent, dedupe_key):
- A repeat sighting of the same finding bumps
last_seenrather than creating a duplicate row. - A finding that a later authoritative scan no longer reports is auto-resolved.
- If it reappears after that, it’s reopened.
Filtering
/findings/ and GET /api/findings/ support status, severity,
scan_type, agent, and page. Grype findings also support ?kev=1 to show
only CISA Known Exploited Vulnerabilities.
Endpoints
| Route | Purpose |
|---|---|
GET /api/findings/ |
list, with the filters above |
POST /api/findings/<id>/status/ |
{status} — open / acknowledged / resolved / suppressed |
POST /api/findings/bulk-status/ |
{ids: [...], status} — same statuses, applied to many findings at once (cap 1000; unknown ids are skipped) |
See Notifications for how findings turn into alerts, and Scans for what each scan type actually reports.