Zero-Knowledge Telemetry & Control Plane
This defines what is allowed to cross the boundary from workstation to control plane.
Event model
Every enforcement decision produces a security event: schema version, a random event
ID, organization/workstation/agent identity, the policy snapshot ID and fingerprint that
produced the decision, severity (defaulting to medium if unspecified), the decision
itself, a reason code, and the surface it occurred on. This is the same event schema
whether the event is destined only for the local queue or eventually for the control
plane.
Redaction happens at construction. When a detector reports a finding,
the event carries the finding's kind, detector name, and placeholder — the matched
value itself is replaced with the literal string "redacted" before the event object
exists in memory, including in the local on-disk log. This is a meaningfully stronger
property than "we redact before sending" — there is no in-memory or on-disk moment where
a constructed event carries the actual matched secret.
What "sanitize for sync" actually strips
A distinct, additional sanitization pass runs specifically before an event is queued for transmission to the control plane:
| Field | Sync-safe replacement |
|---|---|
command |
command_hash (SHA-256) + command_length |
| Working directory | Hashed + counted |
| Arguments | Hashed + counted |
resource_path, executable_path, parent_chain |
Hashed + counted |
| Clipboard content | Dropped entirely — not even hashed |
A sanitized event self-declares evidence_redacted: true, so a consumer can tell the
difference between "this event has no evidence because none was relevant" and "this
event's evidence was deliberately stripped."
Local queue mechanics
Events queue locally as JSONL, in a directory with mode 0700 and files at mode 0600. A malformed line is skipped. Acknowledgement of successfully-synced events happens by sequence number, via a sidecar watermark file, so a double-acknowledgement is idempotent and concurrent appends during a sync are safe. Oversized or undecodable records are skipped-and-counted. The queue itself is bounded; once full, the oldest records are dropped, the loss is counted, and a security event is emitted specifically to make that loss visible. Heartbeats report queue depth, cumulative dropped/skipped counts, and last-sync time — and a heartbeat that happens to omit queue health leaves the previous reported value in place.
Defense in depth at every boundary
Sanitization is deliberately re-applied independently at every boundary crossing — on the agent before send, again at control-plane ingest, and again at every export path (event API views, SIEM push, audit export).
%%{init: {"theme": "base", "themeVariables": {"fontFamily": "-apple-system, Segoe UI, Helvetica, Arial, sans-serif", "primaryColor": "#eef2f7", "primaryTextColor": "#0b0b0b", "primaryBorderColor": "#5b6b7c", "lineColor": "#5b6b7c", "secondaryColor": "#eef4ff", "tertiaryColor": "#f4f3f0", "clusterBkg": "#f9f9f7", "clusterBorder": "#c3c2b7", "edgeLabelBackground": "#fcfcfb", "actorBkg": "#eef2f7", "actorBorder": "#5b6b7c", "actorTextColor": "#0b0b0b", "actorLineColor": "#5b6b7c", "signalColor": "#52514e", "signalTextColor": "#0b0b0b", "labelBoxBkgColor": "#eef4ff", "labelBoxBorderColor": "#5b6b7c", "labelTextColor": "#0b0b0b", "loopTextColor": "#0b0b0b", "noteBkgColor": "#fdf3d9", "noteBorderColor": "#c98500", "noteTextColor": "#3d2f00", "activationBorderColor": "#5b6b7c", "activationBkgColor": "#eef4ff", "sequenceNumberColor": "#ffffff"}}}%%
flowchart LR
Event["Event constructed\n(already redacted findings)"] --> Sync["Sanitize-for-sync\n(hash + drop forbidden fields)"]
Sync --> Queue["Local JSONL queue\n(0700 dir / 0600 files)"]
Queue --> Send["Send to control plane"]
Send --> Ingest["Control-plane ingest:\nre-sanitize any forbidden\nfield present anyway"]
Ingest --> Store[("Audit storage")]
Store --> Export["Every export path\n(API, SIEM, audit export):\nre-sanitize again"]
This design was a deliberate choice over two alternatives:
| Alternative | Why rejected |
|---|---|
| Reject any event carrying a forbidden field | Loses telemetry from a misbehaving or outdated agent version entirely, worsening incident reconstruction exactly when something has already gone wrong |
| Store raw, sanitize only on export | Violates the zero-knowledge boundary at the point that matters most — raw evidence would sit in the database and in backups, reachable by anyone with DB or backup access, not just by the intended export path |
The accepted model: accept, sanitize on the way in, and never store what was
stripped — the control plane rewrites forbidden fields at ingest, increments a
sanitized counter in its response so producers can detect their own
non-compliance, and genuinely malformed (non-JSON) events are still rejected and counted
as rejected.
SIEM export
Audit entries, events, and detector-quality metrics push directly via HTTP to Grafana Loki — no intermediary shipper or collector process. Export re-applies the same sanitization pass (never raw command lines, arguments, working directories, or resource/executable paths), uses deterministic ordering and stable labels, supports a multi-tenant header, queues durably with retry/backoff on failure, and supports a dry-run mode that returns the constructed payload without actually sending it.
Continue to Identity, Access & Fleet Operations.