Security and data
The short version: restoredrill receives reports about your restore drills, not your data. It never connects to your database and never sees a backup.
What your CLI sends
After each drill, the CLI posts its JSON report. It is the same file the CLI writes on your side, so you can read exactly what is sent. It contains:
- When the drill ran, whether it passed, and what triggered it (a schedule, or a person you name).
- The database name, the backup source and the backup file that was used. For an S3 source, that is the bucket and object key.
- Backup size, backup age, restore time, and your RPO and RTO targets.
- Each check and its result, including table names and row counts.
- Error text, when something failed.
It does not contain row contents. When an SQL assertion fails, the CLI leaves the rows out of the report on purpose. Passwords in a connection string are removed before the report is written.
Error messages come from your database and your tools. Read a failed report once if you are unsure what yours say.
How it arrives
- Only over HTTPS. Plain HTTP is redirected.
- To a private address with a token in it. The token is 32 random bytes. Only its SHA-256 hash is stored, so the token cannot be read back from the database. If it leaks, I revoke it and give you a new one.
- A report larger than 1 MB is refused.
Where it is kept
- In one database on Fly.io, in Frankfurt, on a volume Fly encrypts at rest.
- Once a night, a compressed copy of that database goes to Cloudflare R2, which also encrypts at rest. The 30 newest copies are kept, and older ones are deleted.
Reports cannot quietly change
The database refuses to edit a stored report, and refuses to delete one younger than 13 months. Each report is also chained to the one before it by a SHA-256 hash, so a changed or missing report breaks the chain.
I run the server, so in theory I could go around the database rules. The hash chain is how you would catch that. Every alert and every monthly pack shows the newest hash. Keep one. If a later history no longer contains it, something was changed.
Who can see it
- Me, as the operator, to run the service and help you.
- Anyone you give an auditor link to. It is read-only, expires after 90 days unless you ask for another period, and can be revoked at any time. It uses its own token, never the one your CLI posts with. It can be made without the raw reports and backup sources. Search engines are told not to index it.
- Anyone with a pack's verification address. That page shows only the customer name, the month, the issue date and the file's SHA-256. No report data.
Alerts and packs
- Email goes out through Resend. An alert names the database and backup source, and includes the error text and the report hash.
- Slack alerts go only to the incoming webhook you give me. Slack messages carry the same text as the email. They are sent with link previews off.
- The monthly PDF never shows a backup source, because packs get forwarded. It uses the database name instead.
How long it is kept
| What | Kept for |
|---|---|
| Reports | 13 months |
| Monthly pack PDFs | 13 months |
| Pack hash records, for the verification page | 36 months, so an auditor can still check a pack during a later audit |
| Nightly backups | 30 days after the data they hold is deleted |
The privacy page covers your contact details and your rights.
Found a problem?
Email hello at restoredrill dot io with "Security" in the subject. I read every message.