DOCS REFERENCE

The signed audit trail: exports, retention and erasure

An auditor wants evidence, your data-protection officer wants a retention answer, and someone has asked to be erased from a log that is meant to be append-only.

This page holds the detail behind the trust page’s promises about the audit trail: what is signed, what you can hand an auditor, and what happens to personal data.

Audit events and their keys

Every audit event is signed with ECDSA P-256 before it is stored, and is never rewritten. The platform signs its own events with a key your instance holds. Each endpoint agent from 0.240.0 on signs its own events with a key it made itself: in the TPM where the machine has a usable one, and otherwise in the Windows software key store, from which a local administrator can extract it. Either key is usable only by LocalSystem. The endpoint’s page shows which kind the agent reports. The platform checks agent events against the agent’s bound key at ingest and again at export.

An agent older than 0.240.0, or a newer one that could not create a key, signs with a throwaway development key that no verifier trusts. The export refuses a window that holds such an event.

If an endpoint is compromised, an admin can mark its keys compromised from the endpoint’s page, from a moment they choose, behind a typed confirmation. The instance signs a revocation statement: events that key signed after that moment are refused at ingest and left out of exports, and the export’s signed manifest lists each one it left out. Events from before the moment still verify. The control has shipped since platform 0.240.0 but has not yet been exercised on a live install.

Audit search reads the signed events themselves. When the ingest self-check fails, the search page says the log may be missing events, rather than showing a clean result.

The audit export

One action exports a window you choose. The export pages through the audit store, re-verifies every event’s signature, writes the events as canonical JSON (the exact bytes that were hashed), and seals a SHA-256 manifest over the set. Each agent’s events travel with that agent’s key and a platform-signed statement binding the key. An auditor can therefore check the whole audit bundle offline by pinning one platform fingerprint, which the export panel shows:

wep-bundle-verify bundle.tar.zst --expected-fingerprint <sha256>

A window holding an event signed with a development key is refused, and the console says so before you confirm. The manifest says how the signing key was held: a file on the host in Community Edition, a Key Vault on a dedicated instance. With no signer configured, the export refuses outright.

Catalog evidence and fleet inventory

Two more exports are signed with the deployment’s catalog-attest key and checked by the same tool:

wep-bundle-verify catalog-bundle <file>.tar.zst --expected-fingerprint <sha256>
  • Export evidence, from the catalog, writes a catalog evidence bundle. It packages each selected version with the signed statement and SBOM of the run it exports, or the reason one is absent, under one signed statement for the bundle.
  • Export inventory, from the fleet page, writes an inventory export: what your endpoints report (endpoint, package, version, scope, last seen), as JSON and CSV under a signed in-toto statement. User names stay out unless the exporter holds the per-user export permission, asks for them, states a purpose, and the tenant allows it. The signature says the platform exported those rows unchanged. It does not make an agent’s report true.

Both formats are specified on the trust page.

Chain of custody, per version

Each version’s page has a Chain of custody tab (since platform 0.245.0): the steps the version went through, oldest first. It runs from the upstream source listing it, through being read into the catalog, each sandbox run and its verdict, the signed statement, decisions about its rings, and any halt or withholding. Each step names who or what took it and links to its proof where one exists: the manifest, the sandbox run, the signed statement, the halt. A step whose actor nobody recorded says “not recorded” rather than guessing.

It is a view, not a second log. It reads the signed audit events and the catalog’s own rows; the catalog rows behind some steps are not signed themselves, and the tab says so under its timeline. The evidence you hand an auditor is still the signed export above.

How long the trail is kept

As long as you say. The default is unbounded: nothing is pruned unless you ask. An admin sets the retention window in whole months from the console. Pruning itself is a deployment switch that ships off, so a saved window removes nothing until that switch is on. Community Edition’s setup suggests 12 months and never applies it on its own.

When a prune runs, it drops whole monthly partitions in two phases, a grace period apart. Each phase writes a signed record before anything is removed, so removing history is itself evidence. Without a signing key, the prune refuses.

Erasure: the people on your endpoints

Agent events name a Windows user by a random identity ref, not in a SID or account-name field. Free-text diagnostics are scrubbed of SIDs and profile paths best-effort; a DOMAIN\user name or an email address written into free text is not caught. The mapping from SID to ref lives in your own database and in each agent’s local store.

Erasing a user deletes their per-user inventory rows and the mapping on the server. The agent drops its own copy of the mapping on its next check-in, and the erasure reads as pending until it does. The log keeps its signed events, without rewriting or re-signing them. It stops naming the person once no copy of the mapping remains: in your database, on the endpoint, or in your backups. That is pseudonymisation, not anonymisation.

Erasure: your operators

Operators are recorded differently, on purpose. An audit trail exists to show which administrator did what, so operator actions carry the account id or the user name at the time, and are not erased one person at a time. They leave the log when their month passes the retention window and pruning is on. On a self-hosted deployment you are the controller: the window, and the answer to each request, are yours.

Inventory, not usage

The agent reports point-in-time presence: what is installed, which version, in which scope. Run frequency, foreground or dwell time, and per-app usage duration are neither collected nor derived; this is a written product constraint. The one duration-shaped input is how long each user is signed in interactively. The agent counts it in memory, and the server ranks it during the check-in to pick the endpoint’s primary user, the target of per-user installs. It is never stored and never shown per user.