Security
Your key, your server, your data.
Your box runs in your own Hetzner account. Here is what ShipTiffin, the company, can reach, what it can’t, and what the box does to protect your apps.
Updated
In short
ShipTiffin uses your Hetzner API key to build your server, then forgets it, and lists every call it made in your account. After setup it has no SSH access, never holds your box’s owner token, and can’t read your backups: your box encrypts them with a passphrase only you hold.
The box pulls signed updates itself. The only thing of ours that connects to it is a monitor that loads its health page.
What ShipTiffin can and can't reach.
For a managed box. A box you run yourself has nothing of ours in it.
| Can ShipTiffin reach it? | How | |
|---|---|---|
| Your Hetzner key | Only during a job | Sealed in your browser to our setup worker, used for setup (or a resize or delete), then forgotten. We keep a 12-character fingerprint so you can tell which key it was. |
| Your Hetzner login, password and billing | No | A token reaches only the Hetzner project it was made in. |
| Your server over SSH | No | After install, the setup key is removed from the server and from your project, and port 22 is closed to everyone. |
| Your dashboard | No, once you sign in | We keep one sign-in link for your first sign-in. It works once, and your box refuses it 24 hours after making it. After you sign in, the box makes no more for us. |
| Your apps, databases and files | No | They live on your server and never pass through us. |
| Your backups off the server | Stored, not readable | Copied to our storage, encrypted on your box with a passphrase we never see. |
| What your box tells us | Health only | Every 6 hours: Tiffin version, uptime, the names of failing checks, and whether you've signed in. No project names, data, logs or visitors. |
| Pushing anything to your box | No | The box fetches signed releases itself. Our monitor only loads its health page, every five minutes. |
Your Hetzner key: used to build, then forgotten.
ShipTiffin needs a Hetzner API key to make your server. Here is everything that happens to it.
A project just for ShipTiffin
You make a new Hetzner project for your box and a Read & Write key in it, so the key can only see that project.
Sealed in your browser
The key stays in your browser until you click Create. The website then seals it to the setup worker’s public key (X25519 and AES-256-GCM, bound to your box). The website can’t open it; only the worker can, a separate service whose secrets the website never sees.
Used once, then forgotten
The worker clears the key when the job ends, whether setup worked or not, and anything older than two hours is wiped regardless. A resize or a delete asks you for a key again, for that one job.
Only what we made
Everything we create carries a label with your box’s id. Nothing without that label is changed or deleted.
Every call listed
Each request we make with your key is in your account: method, path, time and Hetzner’s answer. The key itself is never logged.
Revoke it any time
Delete the key in Hetzner whenever you like. Your box keeps running.
Updates are signed, and pulled by the box.
Nothing is pushed to your server. Every box, managed or self-hosted, updates itself the same way.
Checked against a signature
About every hour the box reads its channel’s release list and checks its signature against release keys built into Tiffin. A list or build that doesn’t match is refused, and so is anything older than what runs.
A backup first, a way back after
The box checks the build’s sha256, takes a backup, then switches. Apps keep serving; if the new build isn’t healthy within 90 seconds, the previous one comes back.
When you want them
Give the box an update window to install only at a set time, or turn automatic updates off. Each update is in the audit log.
The installer checks too
install.shpicks your build from the signed release list and checks its sha256 (and the list’s signature whenminisignis installed).
What the box protects.
On by default, on every box. The full list, with the mechanisms, is in the security model and protection docs.
Sign-in
Passkeys, one-time links, or Google and GitHub for people already on the box. Sessions last 12 hours in a host-only, HttpOnly cookie. A new browser gets an email, and Settings › Sign-ins ends any session.
Confirm it's you
Creating an API key that lasts over a day or has full access, adding a passkey, or changing an email address needs a strong sign-in in the last 10 minutes. Each new key or passkey is emailed to you.
Keys and secrets
API keys are random 200-bit secrets; only their SHA-256 is stored. Secrets are encrypted with the box’s own key and never shown after you set them.
Network
The firewall lets in only the edge’s ports (and SSH on a box you run yourself). App ports answer only the box, and apps can’t send mail straight out on port 25.
Apps kept apart
Apps run in containers without raw sockets. Every connection the box opens to an app is checked to reach that app’s own project.
Traffic protection
Rate limits per IP (strict on sign-in), security headers, CrowdSec banning scanners and brute-forcers, and cut-offs for slow clients. An under-attack mode and a WAF are there when you need them.
The server itself
Daily security updates and SSH keys only. A kernel update reboots the server only at a time you choose.
A record of everything
Every change and security event is logged with the key or person that made it: keys created and revoked, sign-ins, secrets.
Read the security model, protection and, for coding agents, what an agent can and can’t do.
Backups you can restore, and only you can read.
Backups on the box undo mistakes. Copies off the box survive losing the server.
On the box
A full backup every day and an incremental one every 6 hours, of Postgres, KV, files, email, analytics and the box’s settings. A restore takes a safety backup first.
Any second of the last 7 days
Postgres keeps its log of changes, so it can go back to any moment of the last week. KV and files come back from the nearest backup.
Off the box, managed
Every 6 hours, to our storage, encrypted with a passphrase your box makes and shows only to you. Kept 30 days. The box reaches only its own folder, with keys that last 48 hours.
Off the box, your own bucket
Set any S3-compatible bucket instead (Cloudflare R2, AWS S3, Hetzner Object Storage, MinIO), managed box or not. Keep the passphrase off the box: nothing restores without it.
Details: backups and restore.
The honest limits.
What this doesn't protect you from yet. Every gap is also in the limits page.
It's one server
A hardware fault means downtime until the server is back. Copies off the box survive it, but bringing a lost managed box’s copies to a new box goes through support for now.
It's before version 1.0
ShipTiffin is young and made by a small team. Expect changes, and keep your passphrase safe.
The box is the boundary
Apps share the server’s network. The box checks every connection it opens to an app, but full isolation between apps isn’t done yet. Don’t share a box with people you don’t trust.
Sign in right away
Until your first sign-in, whoever controls your ShipTiffin account (or our website’s database) could get an owner sign-in link. Sign in and add a passkey as soon as the box is ready.
A full key needs no second yes
A key with full access applies changes without asking anyone; your agent’s client is what asks you. Give unattended agents a read-only key for one project.
Our side has gaps too
Monitoring runs from one place. shiptiffin.app isn’t on the Public Suffix List yet, so don’t set cookies on the parent domain. A compromised website could get credentials to delete your off-box copies, though not to read them.
The full list: managed boxes and isolation between apps on the limits page.
Found a problem?
Please don’t open a public issue. Email hello@shiptiffin.com with “Security” in the subject: what you found, how to reproduce it, the version (tiffin version) and what someone could do with it. We aim to reply within a few working days and credit you in the release notes if you’d like. There is no bug bounty.
Only the latest release gets security fixes, and boxes install it by themselves within about an hour. Phishing or malware on a shiptiffin.app address is abuse: report it here.
Questions
Can ShipTiffin staff log in to my server?
Not after setup. The setup SSH key is removed and port 22 is closed, and once you’ve signed in we have no way into your dashboard. If you want us to look at the server, write to hello@shiptiffin.com: you add a temporary SSH key and open port 22 for us, and remove both afterwards. There is no button for it yet.
What if my Hetzner token leaks?
Delete it in Hetzner (Security → API tokens). A token reaches only the Hetzner project it was made in, which is why you make a project just for ShipTiffin. It can’t reach your Hetzner login, password or billing.
Do you see my visitors or analytics?
No. Analytics are counted on your box. The six-hourly check-in carries the Tiffin version, uptime, the names of failing checks and whether you’ve signed in, nothing about projects, data, logs or visitors.
Can I read the code that handles my key?
Yes. The managed service’s control plane is in the same public repository as the box: internal/cloud and the worker in cmd/tiffin-provisioner.
What if ShipTiffin goes away?
Your server is in your Hetzner account and keeps running. The software on it is open source, your data is in standard formats (Postgres, S3-compatible files, a Redis-compatible store), and any project exports to a single file. See running Tiffin yourself.
A server that stays yours.
$19 a month per box, plus the server, billed by Hetzner to you at their prices. Or run it yourself, free.