Security posture, in plain language.
LAST REVIEWED — JUNE 2026
You are trusting us with a database credential. That deserves specifics, not badges. Here is exactly how OffsiteDB handles your data, what we ask for, and where the limits are.
What we ask you to give us
A Postgres connection string — ideally for a read-only role, which is all a backup needs. Create one in 30 seconds:
CREATE ROLE offsitedb_reader LOGIN PASSWORD '...'; GRANT CONNECT ON DATABASE postgres TO offsitedb_reader; GRANT USAGE ON SCHEMA public TO offsitedb_reader; GRANT SELECT ON ALL TABLES IN SCHEMA public TO offsitedb_reader; GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO offsitedb_reader; ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO offsitedb_reader; ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON SEQUENCES TO offsitedb_reader;
We test the connection before saving and never need write access to your database for backups.
What gets backed up
A backup captures every schema the connecting role can read — tables, sequences, views, constraints, functions, and extensions. The snippet above grants the public schema, which holds your application data and is all most people need.
If your data also lives in other schemas, grant the role access to them too. For example, to include a second app schema, add USAGE and SELECT on it the same way:
GRANT USAGE ON SCHEMA app TO offsitedb_reader; GRANT SELECT ON ALL TABLES IN SCHEMA app TO offsitedb_reader; GRANT SELECT ON ALL SEQUENCES IN SCHEMA app TO offsitedb_reader;
Supabase note: the public schema is your app data. The managed auth and storage schemas are owned by Supabase and aren't readable by a normal role — if you need them in your off-site backup, connect with your full postgres connection string instead of a restricted role, and the backup will include everything that role can see. OffsiteDB never holds write access either way.
Per-customer keys (envelope encryption)
- Every customer gets their own random data key. Your credentials and your backup artifacts are encrypted with your key — not a single shared one.
- Each data key is itself wrapped (encrypted) by a master key that lives only in the application environment, never in the database. The master key never directly encrypts your data; it only unwraps data keys in memory.
- This is what makes the wind-down promise real: we can hand you your data key — which decrypts only your data — without touching anyone else's.
Credentials at rest
- Connection strings and storage credentials are encrypted with AES-256-GCM under your data key before they touch the database.
- Passwords are hashed with scrypt and a per-user salt. We cannot read them.
- API keys are stored only as a SHA-256 hash — shown to you once at creation, never again, never in plaintext in our database.
- Credentials are decrypted only in memory, at the moment a backup runs.
Backup artifacts
- Dumps are encrypted before they leave the worker: streamed through gzip and AES-256-GCM (under your per-customer data key) in one pass, then uploaded. Plaintext never lands in your bucket or our storage.
- Each artifact carries a SHA-256 integrity hash, and every snapshot is verified by restoring it — first pg_restore --list against the decrypted archive, then a full restore drill into a scratch Postgres cluster with row counts checked.
- With your own S3/R2 destination, we hold credentials (sealed as above) but never the only copy of your data.
In transit
- All dashboard and API traffic is TLS-only, fronted by Cloudflare with HTTPS enforced end-to-end to the origin.
- Database connections use the Postgres wire protocol with TLS where your provider supports it (Supabase, Neon, RDS all do).
Access model
- Sessions are 32-byte random tokens in httpOnly, secure cookies. Sessions are invalidated on password reset.
- API keys (for the checkpoint API) are scoped to your account and rotatable from Settings at any time.
- Authentication endpoints are rate-limited against credential stuffing.
- Operationally, one engineer (the operator) has infrastructure access. There is no support staff with database reach.
What we are not
OffsiteDB is not SOC 2 certified — certifications cost more than a young product can honestly carry, and we would rather tell you that than imply otherwise. What we give you instead is the artifact your auditor actually wants: a monthly Restore Drill Report with tested restore times, retention proof, and per-snapshot drill evidence for your own SOC 2 / due-diligence answers.
Want to see the proof path?
Open the live demo or start a free trial and run a restore-tested snapshot against your own Postgres.
Reporting a vulnerability
Email [email protected] with “SECURITY” in the subject. You will get a human response within 48 hours, a fix timeline, and credit if you want it. Please don't test against other customers' data — spin up a free trial and break that instead.