Skip to main content

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, or await-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-Email for 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 an ordinary cz.guard() call. When the coding-agent hook is active, the SDK additionally transmits input_payload (the tool input rendered as text -- the Bash command, the SQL, the file path and content) and output_payload (the tool response / stdout), DLP-redacted locally before egress. This applies regardless of whether your organization has opted into I/O capture storage. Whether Control Zero persists that payload on the server side is separately gated by a per-org toggle (off by default); transmission still occurs.

The audit row is stored in the append-only audit trail with the rest of your org's history.

What the SDK does not collect

  • Raw argument values (ordinary guard calls). For a standard cz.guard() call, only the args_hash is transmitted; the SQL statement, the email body, and the file contents are not sent. However, when the coding-agent hook is active, input_payload and output_payload are transmitted (DLP-redacted locally before egress). This is the default behavior; capture_resolved defaults to True and the CLI does not override it.
  • 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 (ordinary guard calls). The SDK guards the call before it executes and does not inspect or buffer the response. However, when the coding-agent hook is active, output_payload (tool response / stdout) is captured and transmitted (DLP-redacted locally before egress).
  • Source code. The SDK does not open or read your application source files itself. However, when the coding-agent hook is active and the agent reads or edits a file, that file's path and content arrive in the host's hook payload and are transmitted as input_payload / output_payload, DLP-redacted locally before egress.
  • Environment variables. Beyond a small allowlist of Control Zero configuration variables (CONTROLZERO_API_KEY, CONTROLZERO_API_URL, 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_hash values
  • Network destinations, file paths, or hostnames from your application

To enable, disable, or inspect telemetry, run:

controlzero telemetry # print the current mode (full / anonymous / off)
controlzero telemetry full # opt in to full anonymous telemetry
controlzero telemetry anonymous # counter-only telemetry, no device ID
controlzero telemetry off # disable telemetry entirely

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 append-only 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.