After a runner begins executing a job, it streams captured eBPF events back to the orchestrator in real time through a single long-lived HTTP POST. Events are grouped intoDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/irchaosclub/FANGS/llms.txt
Use this file to discover all available pages before exploring further.
EventBatch objects and written as newline-delimited JSON (NDJSON) — one batch per line — in the request body. The runner flushes every 250 milliseconds or after accumulating 64 events, whichever comes first. Once the job completes, the runner posts a ScanResult to finalize the run record with terminal status and drop counts. The orchestrator uses both endpoints together to build a complete picture of what the package did during its sandbox execution.
POST /v1/runs//events
Streams captured eBPF events from a runner to the orchestrator. The body is NDJSON — a sequence ofEventBatch JSON objects, each terminated by a newline (\n), all in a single HTTP request body. The connection stays open until the runner closes it after the sandbox exits.
Path parameter
Hex-encoded run identifier returned by
POST /v1/scans. Must match an existing row in the runs table.EventBatch received, the orchestrator:
- Persists one
EventRowper event to theeventstable withts_ns = time.Now().UnixNano(). - Increments per-type metrics counters (one counter per
EventTypestring). - Resets a 2-second debounce timer for this
run_id. When the timer fires, the Differ runs once on the complete event set. This prevents the Differ from executing once per batch during a high-volume stream.
- Transitions the run state to
"done"in therunstable. - Fires the debounced Differ if not already scheduled.
EventBatch JSON object:
16-byte binary run identifier. Must match the
run_id path parameter.Monotonically increasing batch sequence number, per run. The orchestrator logs this for debugging but does not currently enforce ordering.
Array of
EventEnvelope objects. Each envelope wraps one eBPF event.| Numeric | String | Payload struct | Description |
|---|---|---|---|
1 | file_access | OpenatEvent | An openat() syscall matched a watched path prefix |
2 | exec | ExecEvent | A process was executed inside the cgroup |
3 | net_connect | NetConnectEvent | An outbound TCP connection was initiated |
4 | dns_query | DnsQueryEvent | A DNS query was sent from the cgroup |
5 | tls_sni | TLSSniEvent | A TLS SNI hostname was observed |
Total number of
EventBatch objects decoded from the NDJSON stream.Total number of individual events across all batches.
Number of events successfully written to the
events table. Equal to received_events unless storage is not configured or individual rows failed to marshal.POST /v1/runs/{run_id}/result body.
POST /v1/runs//result
Finalizes a run. The runner posts this after the sandbox container exits and the sensor has been detached, reporting terminal status, drop counts, and total scan duration. The orchestrator transitions the run to"done" or "failed" and stamps finished_at, events_emitted, events_dropped, and duration_ns on the runs row.
Path parameter
Hex-encoded run identifier. Must match an existing row in
runs.16-byte binary run ID. Informational — the path parameter is authoritative.
Terminal status of the run. Must be one of:
| Value | Meaning |
|---|---|
"ok" | Sandbox exited normally within the observation window |
"failed" | Sandbox or sensor encountered an unrecoverable error |
"timeout" | Observation window elapsed before the sandbox exited |
Human-readable failure description. Present when
status is "failed" or "timeout". Stored in runs.failure_reason.Total events the sensor emitted during the run. Stored in
runs.events_emitted.Events dropped due to ring-buffer overflow or queue saturation. Stored in
runs.events_dropped. A non-zero value here means the recorded event set is incomplete and some behaviors may have been missed.Actual wall-clock scan duration in nanoseconds. Stored in
runs.duration_ns.true when the result was written to storage. false when the orchestrator has no storage backend configured (the result is still logged).| Status | Condition |
|---|---|
| 400 | Missing or empty run_id path parameter |
| 400 | status is not one of ok, failed, or timeout |
| 404 | No run exists with the given run_id |
| 500 | Database write failed |
The
events_dropped metric is also forwarded to the Prometheus metrics sink when non-zero. Monitor the fangs_events_dropped_total counter to detect ring-buffer saturation — a sustained non-zero value indicates the sandbox is generating events faster than the runner can drain them, and scan accuracy may be degraded.