Repository navigation
Description
Part of #51. Every runtime gets its own in-process probe, but they all talk to the same sensor (#67) the same way. This issue defines that contract once, along with a test kit, so a probe for a new runtime can be built and checked without reading another probe's code.
Activation: a probe is inert unless SECFOO_SENSOR=1 is set: no hooks, no threads, no connections. This applies to every runtime (rule 0 in #51), and the conformance kit checks it.
Transport: one env var, SECFOO_SENSOR_ADDR, picks it:
| Value | Use it for |
|---|---|
unix:///var/run/secfoo/sensor.sock (default on Linux/macOS) |
host daemon, or a sidecar sharing a volume |
tcp://127.0.0.1:7461 |
sidecars that share a network namespace but not a filesystem: K8s pod, ECS/Fargate task, Cloud Run, Azure Container Apps, Nomad group |
npipe:////./pipe/secfoo-sensor (default on Windows) |
Windows hosts and Windows containers |
https://secfoo.internal |
direct mode, when no second process can run (serverless, single-process PaaS). The probe batches and POSTs to #66 itself, using the same Secfoo API key (SECFOO_API_KEY_FILE / SECFOO_API_KEY). |
file:///path/events.ndjson |
offline. Read later with secfoo runtime ingest. |
The sensor listens on loopback or local IPC only, never on a routable address. For TCP mode, add an optional shared key (SECFOO_SENSOR_KEY), since other containers in the same pod share loopback.
Messages: the #53 NDJSON lines, newline-framed, plus:
hello(probe → sensor): protocol version, runtime and version, probe version, pid, host or pod.welcome(sensor → probe): accepted protocol version, watchlist version and path, and the flush interval.- Backpressure: the sensor may answer
slowand the probe then samples more coarsely. If the sensor is gone, the probe drops events and counts the drops, and never blocks or retries on the request path. - Direct mode flushes at the end of each invocation (serverless) or on the interval, with a hard time cap (default 200 ms) so a cold start or shutdown never waits on the network.
Conformance kit: secfoo sensor conformance -- <command that starts the sample app>. It starts a fake sensor, drives a standard scenario against the sample app (call the watched function, don't call it, request on a templated route, request with an auth header, kill the sensor mid-run), and checks that:
- every line is valid against the schema;
- no forbidden data appears (argument values, concrete URL paths, query strings, header values, user IDs);
- the app keeps serving when the sensor dies (fail-open);
- with
SECFOO_SENSORunset, the probe does nothing at all; - overhead stays inside the budget from Tracking: Runtime reachability for SCA (in-app probe + live sensor) #51.
Each runtime probe issue is done only when it passes this kit.
Done when: the spec is written in docs/RUNTIME_PROTOCOL.md, a JSON Schema is in src/secfoo/runtime/, the sensor (#67) implements all transports, and the kit runs in CI against the Python probe (#55) as the reference.
Activity
karthickmk2001 commentedon Nov 12, 2026
I'd like to take this. It builds on the #53 event format now on main. PR to follow.
Merge pull request #100 from secfoo-com/feat/73-probe-protocol