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.

results matching ""

    No results matching ""