Postgres · MySQL · MongoDB · Files · Mail

Database backups, tested by restoring them.

SafeGrd backs up your databases, files and mail, encrypts and locks each copy, and restores it on a schedule to prove it works. An agent with your production keys can drop the database, but not the backups.

14 days free, no card. A full refund of any payment within 30 days. About 2 minutes from install to the first backup. Plans from $15 a month, unlimited databases.

Certificate of restore No. verif-cc68f9a0

shop restored in full.

Snapshot
snap-20261031-135407-16c6d3
Node
node-bebbec48--shop-db
Tables
4 of 4
Rows
45,404 of 45,404
Restore time
236 ms
Signed by
sgd_attest_770109543f7335c6
Pipeline
COPY → zstd → age
Certificate
d052 60a5 … 8ecf

Restored into a sandbox at 13:54 UTC, then signed and added to the attestation record.

Customer-managed key. Only you can decrypt these backups.

A certificate from a drill of SafeGrd's demo database on 31 October 2026. See its full record.
How it works

Three steps to set up, then it runs on a schedule.

The daemon runs beside your database and backs up straight to a bucket, yours or ours. SafeGrd receives a record of each backup, not the data. If you have no server, SafeGrd runs the backup on a machine it starts for the job.

1. Install it beside the database

One command on a server that can reach the database, or the Docker image beside it. On Supabase, Neon or RDS, paste the connection string in the console.

2. Add what to protect

Name a database, a directory or a mailbox in the console. It backs up on schedule, hourly on paid plans. A failed or late backup sends an alert.

3. Let the restore tests run

SafeGrd restores the newest backup into a throwaway database, counts every table and row, and signs the result. We call this a Fire Drill, and it runs weekly or daily depending on your plan.

Your host encrypts each backup and sends it straight to your bucket. SafeGrd receives only a record of it: sizes, checksums, row counts and drill results. your host encrypts each backup the backup, encrypted a record of it your bucket locked for the days you set SafeGrd sizes, checksums, row counts, drill results Your host encrypts each backup and sends it straight to your bucket. SafeGrd receives only a record of it: sizes, checksums, row counts and drill results. your host encrypts each backup backup, encrypted record only your bucket locked for the days you set SafeGrd sizes, checksums, row counts, drill results
The backup goes from your host to the bucket. SafeGrd gets a record of it, which is what the console shows.
curl -fsSL https://safegrd.dev/install.sh | sh

Then safegrd try postgres://… backs up your database and restores it to check, before you sign up. safegrd signup keeps the backup and the host (how it works).

Also a GitHub Action and a Helm chart. Details in the install guide and the docs.

$ safegrd verify --snapshot <newest> --sandbox-target postgres://…/drill_sandbox
Warning: the value of --sandbox-target is visible in `ps` and shell history. Pass env:VAR or file:/path instead.
Verifying snap-20261031-135407-16c6d3 (epoch e202610-b3036e43, shop-db): checking the packs, restoring it into postgres://postgres:xxxxx@localhost:62309/drill_sandbox?sslmode=disable.
   [PASS] DecryptionIntegrity (Expected: the run, its indexes and trees open with the identity, Actual: they do)
   [PASS] RepositoryIntegrity (Expected: every pack present and agreeing with its index, Actual: 3 packs checked)
   [PASS] DigestIntegrity (Expected: f9eef402a29aca7aac7575ff9de386b4e31978b155fc35b5affd11e1923133b1, Actual: f9eef402a29aca7aac7575ff9de386b4e31978b155fc35b5affd11e1923133b1)
   [PASS] TableCountMatch (Expected: 4 tables, Actual: 4 tables)
   [PASS] RowCountMatch (Expected: 45404 rows, Actual: 45404 rows)
   [PASS] Row Count: public.customers (Expected: 1840 rows, Actual: 1840 rows)
   [PASS] Row Count: public.order_items (Expected: 31000 rows, Actual: 31000 rows)
   [PASS] Row Count: public.orders (Expected: 12500 rows, Actual: 12500 rows)
   [PASS] Row Count: public.products (Expected: 64 rows, Actual: 64 rows)
   [PASS] Newest Row: public.customers (Expected: created_at 2026-10-31T13:53:57.447761Z, Actual: created_at 2026-10-31T13:53:57.447761Z)
   [PASS] ExtensionBootCheck (Expected: [], Actual: [])
   [PASS] Schema Captured By pg_dump (Expected: schema from pg_dump, Actual: pg_dump 18.6)
   [PASS] Data Check: amcheck (Expected: every heap and B-tree index readable, Actual: 4 tables, 3 B-tree indexes, no corruption)

Fire Drill Passed
   Verification ID: verif-cc68f9a0
   Duration:        236ms
   Tables:          4
   Rows:            45,404
   Certificate:     cert_sg_d05260a52f24625bb27f4687d67b67781d72da6b13b2003c33128037d1f88ecf
A drill run by hand with safegrd verify: the newest backup restored into an empty database and checked.
Works with

Use the database, platform and bucket you already have.

Databases, files and mail

PostgreSQLMySQLMariaDBMongoDBSQLiteDirectoriesIMAPGoogle WorkspaceWordPressLaravel

Platforms

SupabaseNeonAmazon RDSRailwayRenderFly.ioDigitalOceanHetznerHerokuCoolifyKubernetesGitHub Actions

Storage

Amazon S3Backblaze B2Cloudflare R2WasabiMinIOHetznerDigitalOcean SpacesSafeGrd hosted

Any S3-compatible bucket works, and SafeGrd does not meter what you store in it. Setup for each one.

What it protects

Databases, files and mail are all backed up the same way.

Every backup is encrypted and locked under one key, and the newest is restored on a schedule.

What happens to each backup
shop · ordersPlaintextEncrypted
-----BEGIN AGE ENCRYPTED FILE-----YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQVkR4cXZtbE1HQjJhQ2dIOUd0RHZx-----END AGE ENCRYPTED FILE-----
COPY→zstd→age X25519
snap-20261031-135407-16c6d3
s3://your-bucket/shop/
22d 04huntil it can be deleted. S3 Object Lock, compliance mode.
$ aws s3 rm --recursive s3://your-bucket/delete failed: AccessDenied (Object Lock)Refused
Fire Drillshop → a throwaway database
RestoringPassed
Tables
4 of 4
Rows
45,404 of 45,404
Restore time
236 ms
  • Digest matches
  • Every table
  • Every row
Certificate of restoreNo. verif-cc68f9a0

shop restored in full.

Snapshot
snap-20261031-135407-16c6d3
Rows
45,404 of 45,404
Restore time
236 ms
Signed by
sgd_attest_770109543f7335c6

Restored into a sandbox at 13:54 UTC, then signed and added to the attestation record.

The restore and the certificate are from a drill of SafeGrd's demo database on 31 October 2026.

Surfaces

One key for everything you back up

Databases, directories and mailboxes, each with its own drill record.

Databaserestored 3h ago
Filesrestored 1d ago
Mailrestored 2d ago
Verified Backed up No backup
Badge

A status badge for your README

Green when the last drill passed, amber when one runs late, red when one fails.

SafeGrdverified 3h ago
AI agents

An agent with your keys still can’t reach the backups.

Connect an agent over MCP and it can check backups, take one before a risky migration and test a restore. Its token can add backups but cannot remove one.

Agent token sg_pat_… over MCP

What your agent can do with it.

Check status
Allowed
Delete a backup
Refused
Take a backup
Allowed
Shorten retention
Refused
Run a restore test
Allowed
Change where backups go
Refused
Token

A token that cannot delete

No token can delete a backup or shorten retention. Every call is logged. Revoke the token and the agent stops.

Restore

Restores never write over data

An agent can restore only into an empty directory, or a database SafeGrd confirms is empty.

Into orders_restore (empty)Allowed
Into orders (48 tables)Refused
Guard

A locked snapshot before every destructive command

safegrd guard -- <command> takes a locked snapshot, then runs the command. Hooks for Claude Code, Cursor and Codex call it before every destructive shell command. If the backup fails, the command does not run. Hook recipes.

DROP TABLE, TRUNCATESnapshot first
prisma migrate resetSnapshot first
terraform destroySnapshot first
SELECT count(*) FROM ordersRuns as is
Audit

Check a host in one command

safegrd doctor --agent-proof runs five checks that the backups survive an agent holding this host’s credentials. A failing check prints its fix.

The risk

Credentials that can drop the database can usually delete its backups too.

SafeGrd writes each backup under S3 Object Lock, and nothing can delete it until the lock ends. Your plan or your retention settings set that date.

Key custody

Choose how your key is managed.

SafeGrd keeps your key sealed and releases it only to your enrolled hosts, so you can restore even after losing a host. Or manage the key yourself, and only you can decrypt the backups.

SafeGrd-managed keySealed, and released only to hosts you enrolled. Each release is audited.
Customer-managed keyOnly you can decrypt these backups. Keep a copy of the key somewhere safe.
See it run

A PostgreSQL database, from connection URL to a tested restore.

A PostgreSQL database with no server, added with its connection URL, backed up on a machine SafeGrd starts for the job, then restored and checked by a Fire Drill. Recorded from the console; the waits are cut.
Questions

What people ask before they sign up.

How long does setup take?

About 2 minutes from install to the first backup, and under 15 minutes to a first tested restore. Click Drill now in the console to run the first Fire Drill straight away.

How is this different from a cron job running pg_dump?

A cron job copies the database, and that is all it does. SafeGrd also encrypts and locks each copy, alerts you when a backup fails, and restores it on a schedule. To do that by hand, see how to test that a backup restores.

What happens to my backups if SafeGrd shuts down?

In your own bucket, they stay where they are. The daemon keeps backing up on its own schedule, and the source-available CLI restores without an account. Each enrolled host also keeps a copy of its key. safegrd export copies hosted snapshots to your own bucket at any time.

What does it cost?

From $15 a month, with unlimited surfaces and team members. Plans differ in how often SafeGrd tests your backups. See Pricing, or compare with AWS Backup, SimpleBackups and Ottomatik.

Do I need a server?

Any machine that can reach the database works: a server, a container, a Kubernetes cluster or a scheduled GitHub Actions job. A database with no server beside it can be backed up and drilled on SafeGrd’s own machines. Install and enroll covers each option.

What access does SafeGrd need to my database?

Read access only. On PostgreSQL 14 and newer that is a role granted pg_read_all_data, and safegrd doctor warns if the role can write. Files need read access, a mailbox its IMAP login. Give SafeGrd a read-only role has the grants.

My cloud provider already takes backups. Why add this?

Provider snapshots sit in the same account as the database, so whoever can drop the database can often delete them, and nothing tests them. SafeGrd keeps a separate, locked copy and tests it.

Can a rogue agent delete my backups?

Not on a bucket with S3 Object Lock in compliance mode. The storage provider refuses to delete a locked backup before its lock ends, even for root credentials. An agent’s token can check status, take a backup or ask for a drill, and nothing else. AI agents (MCP).

What do I give an auditor?

The signed record of each Fire Drill, which they can verify offline with SafeGrd’s public key. On Scale, the Evidence Pack collects them with your retention and lock settings. Backup controls maps records to controls.

Test your first restore in under 15 minutes.

Install the CLI, add a database and run safegrd verify. The first backup takes about 2 minutes. 14 days free, no card.