Privacy and data handling
This page describes what the Control Zero SDK collects, what it does not collect, and how to control telemetry. It is not a legal document. For the formal policy, see controlzero.ai/privacy.
What the SDK collects per governed call
When you call cz.guard(...) or any equivalent, the SDK records a single audit row containing:
- Action name. The string you pass in (for example,
database:read,email:send). - Argument fingerprint (
args_hash). A stable, canonical hash of the arguments. Same arguments produce the same hash on every SDK and every machine. The hash is one-way; raw argument values cannot be recovered from it. - Decision.
allow,deny, orawait-approval, plus the matched rule identifier and reason code. - Agent identity. The API key fingerprint, the SDK version, and any identity headers your application attached (for example,
X-CZ-Requestor-Emailfor an approvals flow). - Timestamp and request identifier. Used to correlate the audit row with your application's own logs.
That audit row is the only thing that leaves your process for a governed call. It is stored in the immutable audit trail with the rest of your org's history.
What the SDK does not collect
- Raw argument values. The SQL statement, the email body, the file contents: none of these are transmitted. Only the
args_hash. - Secret values. Vault-managed secrets resolved at runtime are never logged in plaintext, ever. They are referenced by name and identity, not by value.
- Response bodies. The SDK guards the call before it executes. It does not inspect or buffer the response.
- Source code. The SDK does not read your application source.
- Environment variables. Beyond a small allowlist of Control Zero configuration variables (
CONTROLZERO_API_KEY,CONTROLZERO_ENV, and similar), no env vars are read or transmitted.
Telemetry
The SDK can optionally send anonymous usage telemetry to help us prioritise reliability work. Telemetry is opt-in, defaults to off, and never includes argument values, decision context, or any identifier we could resolve to a person.
What anonymous telemetry includes when enabled:
- SDK language and version
- Operating system family
- A randomly generated install identifier
- Aggregate call counts and error counts
What anonymous telemetry never includes:
- API keys, account identifiers, or email addresses
- Action names or
args_hashvalues - Network destinations, file paths, or hostnames from your application
To enable, disable, or inspect telemetry, run:
controlzero migrate --telemetry status
controlzero migrate --telemetry on
controlzero migrate --telemetry off
The command is idempotent and prints the current state.
Dashboard analytics (PostHog)
The web dashboard uses PostHog for product analytics. Identifiers sent to PostHog are limited to:
- The user's identity provider unique identifier (a non-reversible string).
- Org identifier.
- Event names (for example,
dashboard_view_audit,policy_publish_clicked).
Personally identifying fields, including email addresses, are not sent to PostHog. If you previously saw email-shaped identifiers in PostHog logs from your org, that was a regression fixed in the May 2026 dashboard release; no further action is needed on your side.
Data residency and retention
- SaaS: the immutable audit trail is retained according to your plan. Cloud region is documented in your account settings.
- Self-managed: the audit trail lives entirely in your infrastructure. Control Zero never sees it.
Subject access and deletion
For SaaS customers, account owners can:
- Export the audit trail for any time window via the dashboard.
- Request account deletion (which removes org records and irreversibly deletes the audit trail) by emailing
privacy@controlzero.ai.
For self-managed customers, all of the above is your call: the data is in your store.