Google Cloud Assured Workloads, CJIS control package

ChargeStack's production environment runs inside a Google Cloud Assured Workloads folder configured with the CJIS control package. Google enforces the package as organization policy on everything inside the folder — which regions may hold data, which services may run, and that customer-managed keys encrypt every service that supports them. These are not settings a ChargeStack engineer can quietly loosen; the application is built to the boundary, not the other way round.

US-only data residency

The database, uploaded files, backups, logs, secrets, encryption keys and the AI models that read your documents all live in US regions. Policy blocks a resource from being created anywhere else.

Customer-managed encryption keys

Database, file storage, backups, secrets, logs, build artifacts and queues are encrypted under keys ChargeStack controls in Cloud KMS inside the boundary — with a per-organization key wrapping your content on top (below).

Restricted services

Only services Google covers under its CJIS package can run inside the folder. Anything outside the package — including third-party AI vendors — is refused at the platform level, not by a setting in our code.

AI inside the boundary

Documents are read, transcribed and answered by Google's own models served from US endpoints inside the boundary. Under Google Cloud's enterprise terms your prompts and documents are not used to train models and are not shared with third parties. No third-party AI vendor can be enabled for a criminal-justice organization: the lock is a database constraint.

Production moved inside the boundary on 2026-10-07. This marketing website holds no case data and is hosted outside it; the application at app.chargestack.ai is inside.

1. Runtime gate

Our ops staff literally cannot read your case content. The privacy boundary is a gate in the data-access layer on every query our ops tooling issues, not a code-review checklist.

2. You hold the key

If support needs a deeper look, they request it. You approve in your admin panel — single case, time-boxed, revocable at any time, with revocation taking effect on the very next query.

3. Receipts, every time

Every ops query against your org writes a row visible to you. "Zero access today" is a real signal, not a marketing line.

Identity and sessions

There is no public self-signup — every account is provisioned. Your organization's admin (or ChargeStack) invites a member by email; the member sets a password and enrolls a passkey (Touch ID, Face ID, Windows Hello) or an authenticator app. Two-step verification is enforced by policy on every account, and text-message codes are not permitted. Nobody at your county's IT desk is involved.

Accounts are hosted on Google Cloud Identity inside the boundary, under a ChargeStack-owned sign-in domain. The password and the second step happen on Google's sign-in page; the application itself never handles your password.

  • Sessions end after 8 hours, or after 30 minutes idle. A playing recording counts as activity; a paused one does not.
  • Sensitive actions — deleting documents, exporting a case, approving a legal export — require a sign-in within the last 15 minutes, and prompt for one if it is older.
  • Sign-out and revocation are server-side. A revoked account is refused within a minute, whatever its browser still holds.
  • Accounts idle for 90 days are disabled automatically; repeated failed sign-ins are locked out.

Defense in depth

The privacy boundary below is the layer you'll interact with — but it sits on top of controls that isolate every tenant and harden every entry point.

LayerWhat's enforced
Platform A Google Cloud Assured Workloads folder with the CJIS control package: US-only regions, a restricted service list, and customer-managed keys required on every service that supports them — enforced by Google as organization policy.
Tenant isolation Row-level security is forced at the database — even our own application role is not exempt. If no tenant context is bound, a query returns zero rows. Isolation fails closed, never open.
Per-tenant keys Sensitive columns are envelope-encrypted with data keys wrapped by a key that belongs to your organization alone, on top of the platform's customer-managed keys. One tenant's data cannot be decrypted with another tenant's key.
Identity Hosted accounts on Google Cloud Identity; two-step verification enforced by policy (passkey or authenticator app, no SMS); no public self-signup; 8-hour sessions, 30 minutes idle; fresh sign-in for sensitive actions; server-side revocation.
Edge A regional load balancer with a Cloud Armor web application firewall — OWASP rulesets, rate limiting, and US-only geo restriction — fronts the application; backend services are not directly reachable from the internet.
Ingest Every uploaded file is held until it passes a malware scan. Nothing processes a file the scanner has not cleared; oversize archives and executables are refused rather than waved through.
Backups Daily database backups, encrypted under customer-managed keys and kept inside the boundary, with a written restore runbook that has been exercised end to end.
Our own access No ChargeStack employee holds standing access to production infrastructure. Access is a timed grant made by hand, with a written reason, logged and removed when the work is done — the same "receipts, every time" standard we apply to your data.

Encryption, stated precisely

Data in transit is protected by TLS. Data at rest is encrypted by Google Cloud under customer-managed keys, using Google's FIPS 140-validated cryptographic modules. Our application-layer envelope encryption (AES-256-GCM with per-organization KMS-wrapped keys) adds a second layer on the most sensitive columns; that layer runs in a standard cryptography library and is not separately FIPS-validated. We say so because a reviewer will ask.

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 visibility is governed by your organization's privacy posture; Tier 2 only with a customer-issued grant — never as a default, never as an "emergency override."

TierWhat it coversDefault 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, with every read audited. For criminal-justice orgs this is true today as well — runtime gating of Tier 1 is in development. See Criminal-justice mode below for the plain statement of where that stands.
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 selects a Tier 2 column, our data-access layer refuses to execute it and raises OpsForbiddenColumnError before the query ever reaches the database. The check runs on every query the ops session issues — including queries the ORM generates implicitly, not just the ones we wrote by hand — and it is pinned by unit tests, so it cannot be removed quietly.

A fair question at this point: what about access that bypasses the application entirely? That path is closed a different way. No ChargeStack employee holds standing access to the production database — reaching it directly requires a timed grant that is written down and audited. And the most sensitive content columns are envelope-encrypted with your organization's key, so a raw read returns ciphertext, not case content. The gate, the access model, and the encryption are three separate layers; a reviewer should evaluate them together.

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 — revocation takes effect on the very next query.

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. Audit logs are retained for 30 months.

For criminal-justice orgs, your Privacy & Audit panel additionally shows a daily access digest — even when zero access happened. The "zero access today" entry is itself the trust signal.

Criminal-justice mode

Police agencies, prosecutors, public defenders, and government investigative offices are onboarded in CJ mode. The designation is set when we provision the organization — and since there is no self-serve signup, there is no path onto the platform that skips it. In this mode:

  • The privacy posture is locked at maximum at provisioning. No support or admin staff can change it; relaxing it requires an explicit action by a ChargeStack owner — in practice only after a written request from your agency — and that change itself writes an audit row with a recorded reason.
  • No AI or transcription provider outside the Assured Workloads boundary can be switched on for the organization. The database refuses the combination, so there is no setting to get wrong.
  • 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.
  • To be plain about where Tier 1 stands today: sensitive metadata — case names, case numbers, court names, filenames — is currently visible to our ops staff for CJ orgs, with every read written to your audit log and surfaced in your daily digest. Runtime per-case gating of Tier 1 is in development as the next hardening phase; until it ships, the audit trail is the control, and we would rather tell you that than imply otherwise.

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.

We commit to publishing a quarterly transparency report — counts by category (subpoena, search warrant, court order, NSL). The goal is that every count stays zero; if it doesn't, you'll know.

CJIS alignment

The platform runs on Google Cloud Assured Workloads with the CJIS control package, and ChargeStack's own controls are mapped to the FBI CJIS Security Policy v6.0 — access control, auditing, encryption, identification & authentication, and incident response — with every intentional deviation documented alongside its compensating control. We do not claim CJIS certification: no vendor can self-certify, and accountability always rests with the agency and its state CJIS Systems Agency. What we provide is a platform Google attests to under its CJIS agreement, controls you can verify, and the paperwork an agency review needs. A plain-language compliance summary is available on request to security@chargestack.ai.

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. So is our full control matrix, which covers the topics a procurement review asks about next: encryption in transit and at rest, backups and disaster recovery, vulnerability management, personnel screening, subprocessors, data retention and deletion at offboarding, and breach notification.

Procurement, security review, or audit liaison: security@chargestack.ai. We respond within one business day.

Last updated: 2026-10-15. Production moved inside the Assured Workloads boundary on 2026-10-07.

← Back to home