sbx: document audit logging as a governance feature#25239
Conversation
Add a governance page describing how sandboxd records a structured audit event for every policy decision, where the JSONL records land on disk, how to collect them with a SIEM, and how to override the storage location. Link it from the governance index and add Filebeat to the Vale vocabulary. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
✅ Deploy Preview for docsdocker ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
- Remove bold from concept names in the record-categories list - Replace semicolons with separate sentences - Correct the Linux and Windows default audit paths to match the storagekit platform namespaces (verified against the implementation) and generalize the storage-root override description - Use the correct CrowdStrike brand casing; update the Vale vocabulary and existing networking doc to match Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add the paid-subscription note used across the governance section so the audit logging page states that the feature requires Docker AI Governance. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
SANDBOXES_STORAGE_ROOT and DOCKER_SANDBOXES_APP_NAME are undocumented internals and out of scope for the audit logging page. Remove the override section; it can be documented separately in a follow-up if needed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Drop the unattributed-records caveat. In the licensed, signed-in flow, every record is attributed to the signed-in Docker user; empty attribution is an abnormal state, not expected behavior. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Verified the field table and example against real records from a running daemon. Bump schema_version to 1.82.0, include the port in resource_id (host:port), and match the field order of actual output. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
This page was just updated because the bot is zealous and wanted to avoid vale lint errors on the term "Crowdstrike" / nothing related to audit logs.
| | OS | Default path | | ||
| | ------- | ----------------------------------------------------------------- | | ||
| | macOS | `~/Library/Logs/com.docker.sandboxes/sandboxes/auditkit/` | | ||
| | Linux | `${XDG_STATE_HOME:-~/.local/state}/sandboxes/sandboxes/auditkit/` | |
There was a problem hiding this comment.
[MEDIUM] Linux audit log path may contain a duplicated sandboxes/sandboxes/ segment
The Linux path in the OS table is:
${XDG_STATE_HOME:-~/.local/state}/sandboxes/sandboxes/auditkit/
On macOS the app namespace (com.docker.sandboxes) is distinct from the content subdir (sandboxes), so com.docker.sandboxes/sandboxes/auditkit/ is unambiguous. On Windows the namespace (DockerSandboxes) is similarly distinct from the content subdir (sandboxes). On Linux, however, the app namespace is bare sandboxes; if the content subdir is also sandboxes, the resulting path has two consecutive identical segments with no differentiating prefix. This looks like a copy-paste error — the correct Linux path may be ${XDG_STATE_HOME:-~/.local/state}/sandboxes/auditkit/. Users directed to the wrong directory won't find their audit records.
There was a problem hiding this comment.
this is correct I think
There was a problem hiding this comment.
Thanks for confirming! I misinterpreted the path structure — I assumed the double sandboxes/sandboxes/ was unintentional since macOS and Windows use distinct namespace prefixes (com.docker.sandboxes and DockerSandboxes respectively) before the content subdir. On Linux, the lack of a prefix like org.docker. made the repeated segment look like a mistake, but if this is the correct path, that's what matters.
Sorry for the noise!
| tools can collect them. The records stay on the machine that produced them. | ||
| Docker doesn't collect or ingest audit data. | ||
|
|
||
| > [!NOTE] |
There was a problem hiding this comment.
Nit - this is correct. But we should make it explicit in the documentation that audit logs are only written when a Centralized Governance policy is enforced. If there's no centralized policy for the user coming from the org - even if they technically have a governance license - there will be no audit log.
I don't want customers to be confused looking for audit logs on machines that haven't set up a centralized policy to test it with.
Address PM feedback: make explicit that audit logs are written only while an organization enforces a centralized governance policy. A subscription alone produces no records. Add an sbx policy ls check so testers can confirm governance is active instead of hunting for absent log files. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
| Evaluation records share the run's `audit_session_id`, so you can correlate | ||
| every decision back to a single daemon session. | ||
|
|
||
| A network evaluation record looks like this: |
There was a problem hiding this comment.
This seems to be missing several of the fields mentioned here: https://docker.slack.com/archives/C0A8EAKVABG/p1780415157471639?thread_ts=1780396473.646129&cid=C0A8EAKVABG
For example: agent, org_id, org_name
There was a problem hiding this comment.
This is the actual schema for these records, FYI:
https://github.com/docker/data-contracts/blob/main/proto/docker/marlin/audit/event/v1/audit_record_prototype.proto
There was a problem hiding this comment.
I didn't actually see org_id, org_name, or agent in records in my testing.
There was a problem hiding this comment.
@skykelsey the records you shared in that thread look a lot like results from integration testing, not actual audit logs from sbx. I think the current docs are correct.
| - [Audit logs](audit.md): capture a durable, structured record of every | ||
| policy decision for SIEM ingestion and compliance |
There was a problem hiding this comment.
They also capture other important executions, such as sessions starting or ending, policy changes, etc.
| tools can collect them. The records stay on the machine that produced them. | ||
| Docker doesn't collect or ingest audit data. |
There was a problem hiding this comment.
This is in flux and will be based on a remote config in the near future -- just a heads up.
| Evaluation records share the run's `audit_session_id`, so you can correlate | ||
| every decision back to a single daemon session. | ||
|
|
||
| A network evaluation record looks like this: |
There was a problem hiding this comment.
This is the actual schema for these records, FYI:
https://github.com/docker/data-contracts/blob/main/proto/docker/marlin/audit/event/v1/audit_record_prototype.proto
| | `schema_version` | Version of the record schema. Pin your SIEM field mappings to it, as the format is a stable contract. | | ||
| | `category` | `AUDIT_CATEGORY_EVALUATION` for policy decisions, `AUDIT_CATEGORY_MANAGEMENT` for session lifecycle records. | | ||
| | `audit_session_id` | Identifies the daemon run that produced the record. | | ||
| | `username` | The signed-in Docker user's account UUID. | |
There was a problem hiding this comment.
We are changing this soon to be the actual username, and adding a real userID field, FYI.
https://github.com/docker/sandboxes/pull/3281/changes#diff-a324fb193e945b426ed5fc8fb898d430127cf8f636e008f535c2a29884f7ccd2R194
Summary
Documents sbx audit logging, which records a structured audit event for every policy decision sandboxd makes. The new governance page covers what gets recorded, where the JSONL records land per-OS, how to collect them with a SIEM, and how to override the storage location.
https://deploy-preview-25239--docsdocker.netlify.app/ai/sandboxes/governance/audit/