Security

Architecture, isolation and recovery

What protects one workspace from another, what happens when something is deleted by mistake, and where the limits are.

Tenant isolation

Every tenant table is protected by Postgres row-level security. The application connects as a role that RLS confines, and each request runs inside a transaction scoped to one tenant. A query that forgets its scope returns nothing. It does not return somebody else's rows.

That is audited rather than asserted: a standalone SQL audit is run against the live database as part of every deploy, and the deploy is not considered done until it passes.

Access and roles

Roles are enforced on the server. Every write is checked against the role carried by your signed-in session token; an unrecognised role resolves to the least privilege, not the most. Request headers cannot escalate a role. The token is the authority.

The enforced role comes from your identity provider, not from the user list inside a workspace. That list labels people for attribution and reporting.

In transit

The site and application are served over HTTPS only. The origin server accepts traffic on ports 80 and 443 only from Cloudflare's published address ranges, enforced at the network layer and verified unreachable directly from an external host. Cloudflare handles layer 7; the origin firewall handles layer 3 and 4. They are not duplicates of one another.

The database connection is TLS-encrypted.

Backups, and what a backup is worth

A nightly logical export runs at 03:15 UTC, carrying the current workspace for every tenant.

The restore path is rehearsed. An automated test drives the restore command as a real process and asserts its exit code, because a backup nobody has restored is a hope rather than a control. The export job exits non-zero if any tenant fails, so a partial run cannot report success.

Recovery, stated with its number

Point-in-time recovery covers six hours. The two recovery paths do not meet, and the gap matters more than the phrase:

  • A destructive change noticed within six hours can be rewound to the second.
  • Noticed later than six hours, point-in-time recovery cannot reach it at all. The fallback is the nightly export. Up to a day old, carrying the current workspace per tenant and not the revision history or billing records.

In practice: a bad change made at 10:00 and found at 18:00 loses a working day of edits. Under a six-hour window that is the expected outcome for anything not caught the same afternoon, not a corner case. The window will be raised before the first customer, because retention is not retroactive.

Change history

Each accepted save stores a full revision of the workspace document. Revisions are kept for 12 months. The newest revision for a tenant is never pruned, whatever its age. A dormant workspace with an empty trail is indistinguishable from one that was wiped, and those are different facts.

What is not here

No penetration test has been performed. No SOC 2 or ISO 27001 certification is held or in progress. There is no uptime SLA. See Trust.


Security & compliance: Trust · Security · GDPR · Sub-processors · DPA · Privacy · Terms · Cookies

Questions a page here does not answer: get in touch.