Add incident grouping (roadmap v0.8: incident list/show/export)
Collapse related alerts into one incident, process-lineage first with a time-window fallback. Each alert batch's flagged PIDs are walked up the /proc PPid chain into a lineage set (excluding pid 0/1 so everything doesn't correlate through init); batches whose lineage sets intersect — sharing a process or a common ancestor like the web server or SSH session — join the same incident. PID-less batches (FIM drift, package tamper, hidden modules) fall back to the most recently active open incident within incident_window. snapshot.capture now computes lineage and records each snapshot into a JSON incident index (incidents.json), writing incident_id into both the report JSON (report level, so the per-alert schema is untouched) and the text header. New commands: incident list incidents newest-first, with signatures incident show <id> summary + time-ordered snapshot timeline incident export <id> JSON bundle: record + inlined snapshots The lineage/assign cores are pure functions; record() serializes the index under a lock (capture runs from sweep + eBPF threads) and is best-effort so an index problem never loses a snapshot. 17 new tests (lineage, assign, record, and an end-to-end capture→group→CLI path). Config: incident_tracking / incident_window / incident_lineage_depth. Docs + sample config updated; closes the last v0.8 roadmap item. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
4015ec872b
commit
a56d72edd6
9 changed files with 545 additions and 13 deletions
|
|
@ -155,6 +155,34 @@ Exit code:
|
|||
- `0`: sampled files match and signature policy is not downgraded.
|
||||
- `1`: a signed-package mismatch or insecure signature setting was found.
|
||||
|
||||
### `incident`
|
||||
|
||||
```bash
|
||||
enodia-sentinel incident list [--json]
|
||||
enodia-sentinel incident show <incident-id> [--json]
|
||||
enodia-sentinel incident export <incident-id>
|
||||
```
|
||||
|
||||
Groups related alerts into incidents so one intrusion reads as one story instead
|
||||
of several disconnected alerts. Grouping is **process-lineage first** (alerts
|
||||
sharing a PID or a common ancestor — the web server or SSH session they descend
|
||||
from), with a **time-window fallback** for alerts that carry no live PID (FIM
|
||||
drift, package tamper, hidden modules). Each captured snapshot records an
|
||||
`incident_id`; the index lives in `incidents.json` under `log_dir`.
|
||||
|
||||
- `list` — incidents newest-first: id, last seen, severity, alert count, and the
|
||||
signatures involved.
|
||||
- `show <id>` — incident summary plus a time-ordered timeline of its member
|
||||
snapshots (time, severity, signatures, PIDs, and the snapshot file to open).
|
||||
- `export <id>` — a single JSON bundle of the incident record with every member
|
||||
snapshot report inlined, suitable for handoff or offline analysis.
|
||||
|
||||
Tuning lives in config: `incident_window` (how long an incident stays open for
|
||||
new alerts) and `incident_lineage_depth` (ancestors walked when correlating).
|
||||
|
||||
Exit code: `0` on success; `1` if the incident id is unknown; `2` if `show`/
|
||||
`export` is called without an id.
|
||||
|
||||
### `posture check`
|
||||
|
||||
```bash
|
||||
|
|
@ -255,9 +283,6 @@ does not require pip or a virtualenv.
|
|||
The roadmap reserves these command shapes:
|
||||
|
||||
```bash
|
||||
enodia-sentinel incident list
|
||||
enodia-sentinel incident show <incident-id>
|
||||
enodia-sentinel incident export <incident-id>
|
||||
enodia-sentinel respond plan <incident-id>
|
||||
enodia-sentinel respond apply <plan-id>
|
||||
```
|
||||
|
|
|
|||
|
|
@ -20,12 +20,13 @@ promised here; the sequence matters more than calendar precision.
|
|||
Purpose: make the current agent easier to operate and create the data model for
|
||||
work that is bigger than single alerts.
|
||||
|
||||
- Add `incident_id` grouping around related alerts while preserving existing
|
||||
alert JSON.
|
||||
- Add an incident timeline generator:
|
||||
alert time, process ancestry, sockets, persistence writes, FIM diffs, package
|
||||
transactions, and rootcheck findings.
|
||||
- Add `enodia-sentinel incident list/show/export`.
|
||||
- ✅ Add `incident_id` grouping around related alerts (process-lineage first,
|
||||
time-window fallback) while preserving the existing alert JSON — `incident_id`
|
||||
is added at snapshot-report level.
|
||||
- ✅ Add an incident timeline generator: `incident show` builds a time-ordered
|
||||
view across an incident's member snapshots (time, severity, signatures, PIDs).
|
||||
Richer sources (package transactions, dedicated FIM-diff lines) can follow.
|
||||
- ✅ Add `enodia-sentinel incident list/show/export`.
|
||||
- ✅ Add host posture checks (`enodia-sentinel posture check`):
|
||||
SSH root/password/empty-password login, passwordless and writable sudoers,
|
||||
world-writable PATH components, loose sensitive-file permissions, and disabled
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ When a fresh alert survives cooldown, Sentinel writes:
|
|||
|
||||
| Interface | Role |
|
||||
|---|---|
|
||||
| CLI | Run daemon, one-shot checks, baseline management, FIM checks, package DB checks, rootcheck, posture audit, triage, watchdog. |
|
||||
| CLI | Run daemon, one-shot checks, baseline management, FIM checks, package DB checks, rootcheck, posture audit, incident review, triage, watchdog. |
|
||||
| Logs | Durable local evidence under `/var/log/enodia-sentinel`. |
|
||||
| Dashboard | Read-only web view for status, alert browsing, and snapshot inspection. |
|
||||
| Push | ntfy, Pushover, and generic webhook notifications. |
|
||||
|
|
@ -164,8 +164,11 @@ The current `Alert` object is the public detection unit:
|
|||
| `detail` | Human-readable explanation. |
|
||||
| `pids` | Process IDs for snapshot deep dives. |
|
||||
|
||||
Future incident grouping should add an `incident_id` around one or more alerts,
|
||||
without breaking the alert JSON schema.
|
||||
Incident grouping adds an `incident_id` at the snapshot-report level (not inside
|
||||
each `Alert`), so it groups one or more alerts without changing the alert JSON
|
||||
schema. Grouping is process-lineage first, with a time-window fallback for
|
||||
PID-less alerts; see the [command reference](COMMAND_REFERENCE.md) and
|
||||
[roadmap](ROADMAP.md).
|
||||
|
||||
## Configuration Model
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue