Device Agent Personas and Visibility
Status: PRIVATE PREVIEW
This page is for the security or compliance reviewer and the enterprise administrator who need one answer, per persona, per class of data: what can this person actually see, and what is stopping them from seeing more? For every cell we say whether the boundary is access control (a role check, a tenant predicate, or a human gate) or cryptography (the data is sealed and the key is simply not available to that persona), because that distinction is what changes a procurement decision.
It covers the device agent (cz-agent, service cz-agentd) and the
Control Zero platform data it touches. Related pages provide more detail:
- Custody Tiers of Customer Data — where each data class physically lives and how it is deleted.
- Access Ledger — the audit sinks and the "who
looked" trails (
audit_unmask_log,audit_view_log,audit_purge_log). - Device Agent Privacy and Consent — the agent's wire types and the structural privacy boundary.
- Support Access and the Air-Gap Support Bundle — how vendor support reaches a self-managed or air-gapped install.
The four personas
| Persona | Who they are | Relevant access |
|---|---|---|
| Org admin | An organization membership seat at rank admin or owner | Admin and owner role checks. |
| Security / compliance reviewer | Usually a read-only seat (analyst or viewer), or an admin asked to produce evidence | Org-scoped read access described in Access Ledger. |
| End user | The person whose machine is governed; not necessarily an org member at all | device agent's machine identity, not an interactive role |
| Vendor support | Control Zero's own staff; has no in-product role in your org | Support Access and the Air-Gap Support Bundle |
The org role ladder is owner (100) > admin (80) >
billing_admin (60) > developer (40) > analyst (25) > viewer (20) >
readonly (10) — and handlers gate on a minimum role of admin, or on an
exact owner match.
The four data classes
| Class | What it is | Sibling page with the detail |
|---|---|---|
| Endpoint spool | Durable, encrypted, append-only spool on the governed machine. For SDKs it is ~/.controlzero/spool/, used when CONTROLZERO_SPOOL enables it. For the agent it is spool/ in its state dir. The agent seals each record's content to the org's retention-unit public key, which arrives on the map stream, and writes nothing until the org has such a key. This release has no control-plane path that issues one, so the agent spool holds no records today | Custody Tiers |
| Platform operational data | Postgres rows for orgs, users, projects, policies, entitlements, and the secrets vault | Custody Tiers |
| Audit store | audit_logs decision metadata plus opt-in captured I/O and the unmask/view/purge trails | Access Ledger |
| Archived data | public-key-encrypted WAL to object storage (hosted platform); the dormant audit cold tier (Parquet) | Custody Tiers |
The visibility matrix
Each cell states what the persona can see and what withholds the rest, labelled access control or cryptographic (or both). "Access control" means a role check, an org-scope predicate, or a human gate; "cryptographic" means the bytes are sealed and the key is not held where that persona can reach it.
| Persona | Endpoint spool | Platform operational data | Audit store | Archived data |
|---|---|---|---|---|
| Org admin | Can set the SDK spool's retention, cap and location (CONTROLZERO_SPOOL_RETENTION / CONTROLZERO_SPOOL_MAX_BYTES / CONTROLZERO_SPOOL_DIR) on machines they administer (the agent spool has no such setting), but cannot remotely read or decrypt a machine's spool — the DEK stays on the endpoint and is never sent to the platform (cryptographic) | Can read and manage their own org's operational rows through the app-layer org predicate and RLS; cannot read plaintext vault secrets — those are sealed under the master key / per-org DEK (access control + cryptographic) | Can read decision metadata scoped to their org; can unmask args (admin+) and reveal captured I/O, both behind reason + attestation; I/O purge is owner-only (access control) | No tenant path — archive read/delete is an operator function, and the WAL is public-key-encrypted to a recipient key the admin does not hold (cryptographic + no access path) |
| Security / compliance reviewer | Same as org admin: config visible, plaintext not reachable remotely (cryptographic) | Read-only org-scoped rows; no plaintext secrets (access control + cryptographic) | Read metadata; reveal of captured I/O requires reason + attestation and is itself recorded in audit_view_log (access control) | Same as org admin: no tenant read path; objects are opaque BLOBs to a raw reader (cryptographic + no access path) |
| End user | Owner of the machine, so the spool is reachable by root / same-UID code on that machine; it is encrypted against other local users. Where the DEK is in the OS keystore, a copied spool directory or a lost disk is also protected. Where the DEK is the 0600 file beside the spool (always the case for the agent), it is not. It is never protected against root or the user themselves (cryptographic, with a documented floor) | No org view by virtue of being governed. The agent authenticates as a machine identity (X-CZ-Machine-ID + signature), not an interactive org seat; end users see platform data only if separately granted a seat (access control) | Their device's decisions appear in the org ledger only to people with a seat, and only when an SDK, gateway or browser path reports them; the agent itself sends only enrolment and heartbeat metadata (inventory upload is not yet active). It never uploads decision records or captured I/O. The on-device spool refuses to record decisions until the device holds a retention-unit key, and production does not yet issue one, so the agent keeps no local decision history today (access control + cryptographic) | None (no access path) |
| Vendor support | Cannot reach the machine at all — no inbound channel. Support receives only a customer-generated, customer-reviewed support bundle whose environment file is fail-safe redacted (no access path + redaction) | No support-login or impersonation route into your org, and Control Zero staff hold no standing account in it. On the hosted platform, Control Zero platform administrators (an allow-listed operator role, not an org role) have an operator API that reads and manages organization records, the platform user list, usage, tier and entitlement grants, and platform-wide governance and tamper alerts. None of its routes return your policies, vault secrets or audit decision rows. On a self-managed install, that operator role belongs to your own staff. An org owner can still invite any email address, a Control Zero employee's included, as an ordinary member with the role the owner assigns (access control) | None through a vendor route. Support has no session of its own; a Control Zero employee your owner invites as a member sees what that member's role allows (no access path) | None, unless the customer chooses to include an operator export in the reviewed bundle (no access path) |
What actually enforces each boundary
Access-control boundaries
- Tenant scoping is app-layer first. Every query carries the org
predicate derived from the authenticated credential; Postgres Row Level
Security is defence-in-depth, not the primary boundary. The
controlzero_approle connects withBYPASSRLS, so RLS constrains operators on non-app roles, not the application itself. - Role checks are in-handler. Org API-key minting requires
adminor higher;unattended_publishis refused unless the role is exactlyowner. Audit retention change and captured-I/O purge are owner-gated. - Reveal paths carry a human gate. Args unmask and captured-I/O
reveal require a non-empty
reasonand an explicitacknowledgedattestation, and the paired audit row is written before plaintext leaves the server (Access Ledger).
Cryptographic boundaries
- Endpoint spool is encrypted at rest under a per-device DEK. The SDK spool
keeps its DEK in the OS keystore when one is available and otherwise in a
0600file. The device agent always keeps its DEK in a0600custody file inside its spool directory. The server never receives the DEK (Custody Tiers). - Platform secrets are sealed by the application under the master key
before they reach Postgres, and Postgres performs no crypto. A per-org-DEK
envelope (v2) is built but switched off: new secrets are written in the
single-master-key envelope unless
CZ_SECRETS_ENVELOPE_VERSION=2is set, and neither the hosted nor the on-prem deployment sets it (Custody Tiers). - Captured I/O payloads are sealed under a fresh per-record DEK wrapped by the org KEK; deletion is crypto-shred by nulling the wrapped key, leaving the row's metadata intact (Access Ledger; Custody Tiers).
- Archived WAL (hosted platform) is public-key-encrypted to a recipient whose private key is not held on the archiver (Custody Tiers).
- The device identity is held by the account that runs the daemon. Packaged
installs (Linux systemd unit, macOS LaunchDaemon) run the daemon as root, and
the identity file holding the signing key is set to owner-only (
0600) permissions immediately after it is written, in root's state directory, so a non-administrator cannot read or replace it. If a user runscz-agent upunder their own account, the identity file is theirs. Removing it and enrolling again registers a new device rather than impersonating the old one.
Unimplemented rules — named gaps
These are stated as gaps, not as shipped features:
- No single disclosure-boundary table. There is no unified
customer-facing endpoint that lists the full
audit_unmask_log/audit_view_log/audit_purge_loghistory. The only customer-visible surface today isio_last_viewed_by/io_last_viewed_at/io_last_viewed_reasonon a decision row that has captured I/O (Access Ledger). - The RBAC PEP is shadow by default. With
RBAC_ENFORCE_ALLunset, the middleware PEP logs a would-deny and allows; the in-handler role checks are what actually block today. - RLS is not the primary boundary. It is enforced as defence-in-depth; the application-layer org predicate is the real boundary, and the app role bypasses RLS by design.
- The audit cold tier is dormant by default. It is armed only by explicit configuration (Access Ledger).
- No consent state machine on the device. There is no per-user opt-out, consent dialog, or telemetry toggle; the privacy property is not a runtime setting — the detectors are written to emit metadata only, and the process and traffic detectors' tests fail any row they emit that carries a forbidden key (Device Agent Privacy and Consent).
- No S3 Object Lock on the archive path. Append-only-ness is a database trigger, WAL relies on object-store versioning, and the cold tier relies on dual-cloud verification — none of these is an object lock (Custody Tiers).