Security & Trust
Controls you can verify.
If your purchase goes through a security review, this page is written for your reviewer. Every control below names the file, migration or published policy that implements it — so it can be checked rather than taken on trust.
a 15-minute call — no checkout, nothing to buy online
Before the conversation: Start the assessment
Every claim carries its source. Under NDA we will walk any of them line by line.
5
Invariants enforced on every push
A violation blocks the merge. The guard prints what it checked, so a reviewer can run it themselves.
scripts/check-security-invariants.mjs
19
Principal-only routes carrying a fail-closed delegate check
A chief of staff or EA can be given access without inheriting the leader’s private material.
PRINCIPAL_ONLY_ROUTES, same guard
13
Controls we can show you the code for
Each one names the file, migration or published policy that implements it, so your reviewer can check it rather than take it.
Listed in full below
Controls a reviewer can verify today
Secret-shaped public env vars
Blocked on every push
Service-role DB client in client code
Blocked on every push
Row-level security on new tables
Required to merge
Personal-side SMS sender guard
Fail-closed
Principal-only route delegate check
Fail-closed, 19 routes
Inbound text never an instruction
CI invariant
Published DPA, privacy policy, terms
Readable without asking
Tokens encrypted at rest
AES-256-GCM
Append-only audit log
No update or delete policy
A green cell is a control, not a certification. Each one is something you can go and check in our codebase. Nothing appears here that we cannot evidence, and nothing absent from this grid is being claimed elsewhere on the page.
Every cell restates a control described in prose on this page, and each one is checkable by running our own guard. No uptime, incident, customer-count or response-time figure appears anywhere on this page, because no such measurement exists for us to publish.
01 · The controls
What is actually in place.
Each row names the file, migration or published policy that implements it, so your reviewer can check the claim rather than take it. Under NDA we will walk any of them line by line.
Security checks in CI
Five security invariants are enforced on every push and block the merge if violated: no secret-shaped public environment variables, the service-role database client may never be imported into client code, new tables must ship with row-level security enabled, personal-side SMS must route through a fail-closed sender guard, and nineteen principal-only routes must carry a fail-closed delegate check. The guard's own documentation is explicit that it is a fast static audit and does not replace a penetration test.
scripts/check-security-invariants.mjs
Tenant data isolation
Isolation is enforced primarily in the application layer, which scopes every query by account. Row-level security is enabled and FORCEd on tenant tables as a default-deny backstop that blocks anonymous and authenticated keys outright. We describe it in that order deliberately: the database policies are a blanket backstop rather than per-tenant predicates, because the user identifier and the auth identifier are different types with no in-database bridge — a limitation recorded in the migration itself.
supabase/migrations/20260703180000_security_rls_lockdown.sql · 20260513003000_p0_rls_zero_policy_tables.sql
Tokens encrypted at rest
OAuth tokens are encrypted with AES-256-GCM before they are stored, using a dedicated 32-byte key held outside the database. There is no plaintext fallback: if the key is absent in production the encrypt path throws rather than writing the token in the clear, so a misconfiguration fails closed instead of silently degrading.
lib/crypto.ts
Deletion you can audit
A daily job hard-deletes data for accounts cancelled more than thirty days earlier, walking foreign keys in a defined order and then anonymising the account record. One lifecycle-log row is written per account regardless of outcome, which is the evidence surface if a regulator asks us to prove a deletion happened.
app/api/cron/retention-cleanup/route.ts · lib/account-data-pipelines.ts
Deletion coverage is test-enforced
A test in CI fails if a new table is added without being wired into the erasure walk, so the right-to-be-forgotten path cannot silently fall out of date as the schema grows.
test/gdpr-delete-order-completeness.test.ts
Data subject requests
Export, deletion and data-subject-request intake are live endpoints rather than a manual process, and requests are recorded for follow-up.
app/api/billing/data-export/route.ts · app/api/billing/data-delete/route.ts · app/api/sophia/gdpr-request/route.ts
Audit trail
Every mutating administrative action writes one row to an append-only audit log. Append-only is enforced by the absence of any update or delete policy on the table, not by convention. The log is exportable.
supabase/migrations/20260512180000_audit_log.sql · app/api/admin/audit-log/export/route.ts
Authentication
Magic-link tokens are 32 random bytes and are SHA-256 hashed before storage, so a database read does not yield usable tokens. WebAuthn passkeys are supported, with single-use challenges on a five-minute expiry. Enterprise SSO is available through WorkOS.
lib/owner-auth.ts · lib/passkeys.ts · lib/sso.ts
Fail-closed as a design rule
Where a check can fail, it is written to deny rather than allow: a missing per-principal sending number stops the message instead of falling back to a shared line, an unreadable delegate session is treated as not-the-principal, and an unrecognised agent-to-agent decision resolves to escalation rather than being passed through. Two of these are enforced by the CI guard above.
scripts/check-security-invariants.mjs invariants 4–5 · lib/a2a/represent.ts
Model provider
Anthropic is the sole model provider. Under our agreement with them, customer data is not used to train their models.
lib/anthropic-client.ts · /privacy
Incident response
A written runbook defines P1/P2/P3 severities with encoded trigger conditions, a named on-call owner and communications owner, throttling to prevent alert storms, and a 48-hour post-mortem requirement. Severity classification is implemented in code rather than left to judgement in the moment.
docs/for-internal-team/2026-05-24-incident-response-runbook.md · lib/alerts-classifier.ts
Call recording and consent
Recording consent is announced on the first turn of a call, with all-party-consent states named explicitly in the published privacy policy. Third parties who were never JOOLT customers can stop recording, opt a number out permanently, and request deletion.
/privacy
Data processing agreement
A DPA is published and available to sign. It commits to encryption in transit and at rest, 72-hour breach notification, twelve-month minimum audit-log retention, a customer audit right, a thirty-day post-termination export window, and thirty days' notice of subprocessor changes.
/legal/dpa
02 · Documents
What you can read today.
Data Processing Agreement
Our processor commitments, breach notification window, audit rights and deletion terms.
Read the DPAPrivacy Policy
What we collect, how long we keep it, call-recording consent, and the rights of third parties who never signed up with us.
Read the privacy policy03 · What comes next
Where SOC 2 sits.
We do not hold a SOC 2 report. It is on the roadmap ahead of enterprise procurement, and we will say so in exactly these words until that changes.
What an audit examines — access control, encryption at rest, tenant isolation, an append-only audit trail, change control enforced in CI rather than by policy document — overlaps heavily with the controls above. Overlap is not an audit, and we will not present it as one.
So: if a report in hand is a hard gate for your process, tell us on the first call and you will get a straight answer about where we are rather than a timeline that slips past you. If it is not, the DPA, the controls above and a walkthrough under NDA are all available now.
Where this page is silent, nothing is being claimed. Security questionnaires are welcome before a commercial conversation rather than after — including the questions whose answer today is “not yet”.
Security & Trust
We would rather lose on an honest answer.
a 15-minute call — no checkout, nothing to buy online
Before the conversation: Start the assessment