Live triage package
What this page is
The forensic snapshot the sensor takes on operator command. A
single JSON document collected from /proc, /sys, and
the filesystem in four phases, streamed back over the existing
Collector channel.
Why it exists this way
Architecture Section 7.3 names live triage as the second response action after host isolation. The package answers the "what's running, what's it talking to, how is it pinned, and what changed recently" question without forcing an analyst to ssh in.
The package is read-only: triage::collect_triage_package
never deletes, modifies, or kills anything on the host. The
collected JSON is the only side effect, and it is uploaded
through the Collector path, not written to a place where an
attacker could read it.
How it works
The implementation lives in edr_linux::triage and runs four
phases:
| Phase | Source | Output type |
|---|---|---|
| Process tree | /proc/[pid]/{stat,cmdline,status,exe,cwd} | Vec<ProcessNode> |
| Network connections | /proc/net/{tcp,tcp6,udp,udp6} + per-pid socket inodes | Vec<NetworkConnection> |
| Persistence locations | cron, systemd, autostart, rc.local, profile.d, init.d, per-user shell rc files | Vec<PersistenceItem> |
| Recent file modifications | find over forensic-relevant directories (fallback: manual recursive scan) | Vec<FileModification> |
Each phase is bounded by the constants at the top of the module
(MAX_PROCESS_ENTRIES, MAX_CONNECTION_ENTRIES, etc.) so
a host with millions of files cannot exhaust sensor memory.
Each phase fails independently. A failure in connection
enumeration does not stop process-tree collection; partial
results carry per-phase Option<TriageError> fields in the
TriagePackage envelope so the analyst sees what worked and
what did not.
Network connection rows are cross-referenced with each
process's socket inodes under /proc/[pid]/fd, so the
process_pid and process_comm fields are populated when
the kernel exposes the mapping.
What goes wrong
TriageError::ProcessTree,/procis missing or permission-denied. The phase returns an error but the rest of the package proceeds.findnot on the host, the recent-files phase falls back to a manual recursive scan. The scan respects the same depth cap so the fallback's worst case matches the primary path.- The package exceeds the gRPC message size limit, split is not yet implemented. The single-package size is bounded by the four phase caps so the worst-case payload (4096 process nodes + 2048 connections + 512 persistence items + 1024 recent files) sits comfortably under the default 4 MiB gRPC frame.