Security model

The reach of each credential in the system, and the limits placed on it.

On this page
  1. The two planes
  2. Kafka ACLs
  3. Credentials at rest
  4. Fleet hub authentication
    1. API surface separation
  5. Package integrity
  6. Transport encryption
  7. Telemetry isolation
  8. Residual risks

The two planes

The data plane and the management plane share the monitored host and nothing else.

  Data plane Management plane
Carries Provenance events Fleet control
Transport Kafka (TLS + SASL/SCRAM-SHA-256) SignalR / HTTPS
Direction One-way, agent → backend Bidirectional
Host component Collection Agent Updater
Backend EventProcessor, Writer, PostgreSQL FleetServer, AgentDashboard
Can read collected provenance Yes No
Can instruct a host to install software No Yes

An operator with dashboard access cannot read collected provenance, and a compromised collection path cannot issue installer instructions. Downstream collection components cannot reach back into monitored hosts: the data path is a Kafka topic that an agent can only write to.

%% ProvCollector — the management plane. Editable Mermaid source; see the notes
%% at the top of architecture.mmd. Colours come from the active colour scheme.

flowchart LR

  subgraph host ["Monitored host"]
    agent["<b>ProvCollector.Agent</b><br/>Collects provenance.<br/>Knows nothing about the fleet."]
    updater["<b>ProvCollector.Updater</b><br/>Heartbeat, config delivery,<br/>verified package install."]
  end

  raw(["RawEvents → the data plane"])

  fleet["<b>FleetServer</b><br/>Agent hub + operator API<br/><i>X-Api-Key checked before registration</i>"]

  dashboard["<b>AgentDashboard</b><br/>Blazor operator UI<br/><i>no state of its own</i>"]

  packages[("<b>Packages</b><br/>SHA-256 digest per package,<br/>verified before install")]

  agent --> raw
  updater <-- "SignalR · heartbeat, commands, logs" --> fleet
  fleet <-- "HTTP · operator API" --> dashboard
  fleet --- packages

  class raw topic
  class packages store
  class agent dataplane
  class updater,fleet,dashboard management
  • Data plane
  • Durable store
  • Management plane
Figure 2. The updater runs beside the agent and shares nothing with it but the host. Fleet control never touches RawEvents, the processed stream or the database, so an operator with dashboard access cannot read collected provenance — and the collection path, which holds a write-only Kafka credential, cannot issue installer instructions.

Kafka ACLs

Each service operates under a dedicated SASL principal restricted to minimum required privileges:

Principal Grants
agent Write/describe/create on RawEvents; idempotent-write on cluster
eventprocessor Read on RawEvents; write on ProcessedEvents; read/write on IdentityChangelog; consumer group access
database Read/describe on ProcessedEvents; consumer group access
throughputmon Read/describe on RawEvents and ProcessedEvents; consumer group access
admin Superuser administration and schema registry access

An agent credential compromised on a monitored host permits event injection into RawEvents. It does not permit reading the event stream, reading ProcessedEvents, or accessing identity changelogs. Injection remains a host compromise risk, but exfiltration of the fleet’s collected provenance through a single compromised agent is prevented.

Credentials at rest

Agent Kafka credentials are stored encrypted in local configuration files and decrypted in memory at service startup using platform-native protection (DPAPI on Windows, OS credential stores on Linux). Plaintext credentials can be used in local development environments.

Fleet hub authentication

Agents connecting to the management plane authenticate using API keys. Key digests are compared using constant-time verification to prevent timing side-channels. Connections presenting invalid or missing credentials are immediately rejected prior to registration.

If no API key hashes are configured on the fleet server, all agent connections are rejected by default.

API surface separation

The fleet server isolates endpoints into three distinct URL paths with independent authorization policies:

Prefix Consumer Stability
/api/v1/agent Updaters (SignalR hub) Frozen — deployed agents depend on it
/api/v1/updates CI pipelines and package tools Published contract
/api/v1/fleet AgentDashboard UI Internal administration

All error responses adhere to the RFC 9457 Problem Details standard with structured machine-readable error codes.

Package integrity

Software packages distributed by the management plane are verified against published SHA-256 digests prior to execution. Packages failing validation are deleted immediately. Download and extraction routines enforce strict boundary checks to prevent path traversal attacks.

Disabling TLS certificate validation (AllowInvalidCertificates) should only ever be used in isolated development setups. Disabling validation on channels carrying installer instructions creates an unauthenticated remote execution vector under LocalSystem.

Transport encryption

All inter-component communication is encrypted in transit:

  • Kafka: TLS encryption with SASL/SCRAM-SHA-256 authentication.
  • PostgreSQL: SSL encryption with CA certificate validation.
  • Fleet Management: HTTPS and WSS with TLS certificate validation.

Telemetry isolation

Collection agents filter out their own process and network activity to prevent recursive feedback loops in the provenance stream. Monitored host agents run with elevated privileges (LocalSystem on Windows, root on Linux) to access kernel event providers, security event logs, and kernel drivers.

Residual risks

  • Event injection: A compromised endpoint holds valid credentials to write into RawEvents. Downstream stages cannot distinguish fabricated telemetry from genuine OS events.
  • Induced collection gaps: Under heavy host resource exhaustion or deliberate flooding, the agent’s bounded buffer drops events to protect kernel stability. While drops are counted, an attacker can exploit this to create blind spots.
  • Traversal resource consumption: Deep traversals across dense subgraphs can demand substantial memory. Time-bounded filters and node limits are required to bound query cost.

Back to top

ProvCollector — system-provenance collection, storage and analysis. Documentation built with Jekyll and Just the Docs.