The audit record
What is recorded about a run's network: its policy, the policy's identity, and each connection decision — and how far each can be read back today.
On every run
Each run's record carries its egress posture.
| field | what it says |
|---|---|
| policy source | which policy judged the run: baseline:<name>, baseline:<name>+workload:<name>…, named:<path>, or open:<reason>, <actor>. Empty for a run with nothing to judge (proc) |
| policy digest | the identity of the exact policy the door loaded — the digest of its compiled form |
| enforcement note | the posture the run actually got, for example egress: WALLED, and for a sealed run whether model egress was sealed and, if not, why |
These fields answer the first questions an auditor asks: was this run governed, by what, and if it
was opened, by whom and why? An opened run cannot be mistaken for a governed one — its source
starts with open: and names the actor.
saphan run prints the enforcement note as the enforce line of its report. The policy source and
digest are stored on the run record; this release has no command or console page that displays
them — read them from the installation's database (egress_policy_source, egress_policy_digest).
On every connection
For a run whose door runs on the dispatching machine, each connection decision is written as one row:
| field | content |
|---|---|
| run | the run it belongs to |
| host, port | the destination. Host and port only — never a URL path or any content |
| verdict | permitted or refused |
| reason | the refusal class, for a refused connection |
| time | when the decision was taken (UTC) |
| policy digest | the policy that took it |
A permitted row is written only after the connection succeeded, and once per run, host and port.
Every refusal taken by the door is written. If a permitted decision cannot be written, the
connection is refused rather than allowed unrecorded.
⚠ On the Linux network wall and the container bridge, some refusals never reach the door: a name the policy does not list fails at name resolution inside the run, and a port the policy does not name is reset by the kernel. Neither is recorded.
In the event log
Every connection decision that lands in the record is also written to the installation's event log, one event per decision, and you can list them:
An event carries metadata only: the run or session, host and port, the verdict, the refusal class
and the policy digest — never a request body, a URL path or a credential. The same log carries the
tool permissions decided in a console conversation (tool.allowed, tool.refused).
⚠ Delivery into the event log is at most once. If writing the event fails, the decision still stands in the record and the process logs that it could not be mirrored; nothing retries it. For completeness, read the record, not the event log.
What you can read back today
⚠ Be precise about the current state when you rely on this record:
| state | |
|---|---|
| policy source, digest and enforcement note on the run record | written for every run. The enforcement note is printed by saphan run; the source and digest are only in the database |
| per-connection rows, local runs | written, and listed by saphan bus events (above) |
| per-connection rows, runs on a machine reached over ssh | written on the far machine and brought into the record when the run's result is collected (saphan return); listed by saphan bus events from then on. A run whose result is never collected leaves its rows on the far machine |
per-connection rows, interactive sessions opened with saphan cli | written when the session runs inside its network wall, and listed the same way |