What we mean by "literally cannot read"
Every column in our database is classified into one of three tiers. Ops staff get Tier 0 by default; Tier 1 with a customer-issued grant or by default for non-criminal-justice orgs; Tier 2 only with a customer-issued grant — never as a default, never as an "emergency override."
| Tier | What it covers | Default visibility |
|---|---|---|
| 0 Structural | IDs, timestamps, counts, sizes, status enums, error codes — never derived from your input. | Visible |
| 1 Sensitive metadata | Case names, case numbers, court names, filenames, folder skeletons, org names. | Visible to ops by default; gated for criminal-justice orgs. |
| 2 Content | Case descriptions, document text, AI extractions and analyses, conversation messages, agent artifacts, embeddings, free-text error messages. | Always blocked without an active debug grant. |
When an ops query touches a Tier 2 column, the database session
raises OpsForbiddenColumnError at the engine. Even
hand-written SQL gets the same error. The runtime — not policy —
is what enforces this.
Debug grants
When support needs deeper access — to diagnose a specific case, say — they request a grant from inside the ops console. You see the request in your Privacy & Audit panel: who's asking, what case, what tier, why. You choose the duration (up to your org's configured maximum) and approve. Or reject.
Grants are scoped to a single case by default. They expire automatically on a clock you set. You can revoke at any moment — ops loses access on the next request.
The audit trail
Every /ops_admin/* request — including pure-metadata
ones like "list this org's billing rollup" — writes a row to your
org's audit log. The row records who, when,
which tables they touched, the maximum tier they read, and
the grant ID under which they read (if any). You see this in your
Privacy & Audit panel.
For criminal-justice orgs, your admins additionally receive a daily email digest — even if zero access happened. The "zero access today" email is itself the trust signal.
Criminal-justice mode
Police agencies, prosecutors, public defenders, and government investigative offices are onboarded in CJ mode (flagged automatically based on the org-type they identify with). In this mode:
- Tier 1 cannot be globally unblocked. Even names and filenames require per-case debug grants.
- The org's display name in our ops console is the UUID, not the chosen name — so the org name itself doesn't reveal patterns.
- Daily access-digest email regardless of activity.
- The privacy posture cannot be relaxed without an explicit owner action by ChargeStack — usually only after a written request.
Legal compulsion
If we receive a subpoena, search warrant, or court order, we follow a separate code path with its own audit trail. Two ChargeStack signers must approve before any data is exported, and the second signer must re-authenticate to do so. You receive notification within 24 hours unless we are served a gag order alongside.
Each quarter we publish a transparency report — counts by category (subpoena, search warrant, court order, NSL). Goal: always zero, but if not, you know.
Verifying our claims
This page is the customer-facing summary. An implementation reference for engineers, auditors, and security reviewers — mapping each guarantee on this page to specific code, the SQLAlchemy event hook, and the unit tests that verify the gate — is available on request to security@chargestack.ai.
Get in touch
Procurement, security review, or audit liaison: security@chargestack.ai. We respond within one business day.
Last updated: 2026-05-10.