What stops one customer’s data reaching another customer’s account?
Postgres, before our code runs. Every table holding tenant data carries a row-level security policy keyed to the tenant bound to the current transaction, and the API connects as a role those policies bind: it owns no table, holds no bypass, and has data privileges and nothing else. A query that reaches those tables with no tenant bound raises rather than returning rows, so the failure mode of a bug on our side is an error on our side. A test reads the database catalog on every build and fails if a table carrying a tenant id has no policy on it.
What happens if you deploy it wrong?
The API refuses to serve. At startup it interrogates the database role it just connected as and stops if row-level security is off, if the role owns the table, if it holds a bypass, or if it reaches anything it should not. The same check runs on every readiness probe, so a task that drifts after startup is pulled out of rotation instead of left answering requests. Failing at boot is the behavior you want from an isolation boundary, because the alternative is a deployment that looks healthy and is not.
Where do the carrier credentials we connect actually live?
Sealed with AES-256-GCM in a store whose database half holds bytes and no key, and whose key-holding half never opens a database connection. An import rule fails the build if either half imports the other, so the separation survives the next refactor rather than depending on somebody remembering it. The credential is never returned by an endpoint, an export, a log line, or an error body, and a support view of your account carries the address of the record rather than anything inside it.
Can someone on your team read our contacts?
The staff console reads through a database role that owns no table and whose only write grant in the whole schema is an insert into the audit log, and the API refuses to start if that role and the runtime role are ever the same principal. Staff hold no customer API key: support access mints a credential of its own class, returned once and stored only as a hash. A session that can change anything requires a live approval from a different staff member, enforced as a constraint on the approvals table, and every action carries the operator’s own stated reason, written in the same transaction as the change it describes.
Can any plan, flag, or support ticket switch the compliance controls off?
No, and not because a policy forbids it. A tenant’s compliance mode can only name checks drawn from a waivable set, and the four floor controls are not members of it; the unwaivable stages are derived by set difference rather than listed, so they cannot be omitted by an edit. Waiving the disclosure opener is not a state anyone can construct, express in JSON, or store, and two tests fail the build if that stops being true. They are also never metered: the local stages are excluded from billable lookups by construction, so there is no configuration in which the floor is charged for or switched off to save money.
What does leaving look like?
An export, on your own schedule. The Twilio account, the numbers, the registrations and the caller-ID reputation were always in your name, so nothing has to be migrated off ours. CSV jobs cover supported record types: contacts, contact attempts, calls, survey responses, shift confirmations, appointments, internal do-not-call entries, scrub results, usage events, and caller requests. Available recordings and transcripts are fetched through authenticated /v1 call reads. Product resources use /v1, while signup, onboarding, and first-key setup remain browser flows, so a team that integrated on day one is already holding its own records.
We have a security questionnaire. What do we get back?
Written answers about the controls themselves, from the people who built them, at support@capstralabs.com. The control descriptions are published rather than held back for a questionnaire, which is what this page is: most of what a reviewer asks is already answered above, and the rest is a reply rather than a process.