What runs
Every container on the box, what each one does, and which of them may talk to anything outside.
Outside the house
- Your laptop or phonethrough Tailscale, at your domain, or on your own network
- Your mailboxIMAP, read only
- The model you chosetext of each document
- Your backup targetencrypted snapshots, nightly
The box
- tailscaleoptional: serves the app on your tailnettalks to your laptop or phone
- caddyoptional: serves the app at your domain, over HTTPStalks to your laptop or phone
- webthe appinternal only
- apiHTTP API, sessions, migrationsinternal only
- workerOCR and text extraction; the only process that opens a documentno route out
- suggestertitles, categories, dates, summariestalks to the model you chose
- mailfetchreads connected mailboxestalks to your mailbox
- backupnightly dump and snapshot, monthly restore testtalks to your backup target
- postgres · redisstate and queuesinternal only
/data one encrypted volume: documents, database, queues, secrets
The containers#
| Container | Does | Network |
|---|---|---|
tailscale | Optional. Serves the app on your tailnet over HTTPS | When present, the only thing reachable, and only from your tailnet |
caddy | Optional. Serves the app at your domain over HTTPS, with a certificate from Let's Encrypt, and lets the first account be created only through the setup link | When present, the only thing listening, on ports 80 and 443 |
web | The app | No host port of its own behind Tailscale or Caddy; otherwise a port on the address you chose |
api | HTTP API, migrations, sessions | Internal, plus mail autodiscover during setup |
worker | OCR, thumbnails, and text extraction | No route out |
suggester | Titles, categories and dates from the text, via the model you chose or none | Out to that provider only |
mailfetch | Reads connected mailboxes over IMAP; the only process that unseals mail passwords | Out to IMAP hosts only |
backup | Nightly database dump and snapshot, monthly restore test | Out to the backup target only |
postgres, redis | State and queues, on the encrypted volume | Internal |
Isolation#
The OCR toolchain has a long history of vulnerabilities, and email-in lets strangers hand you a file. The worker is isolated in a container with access to internal services, no direct internet route, a read-only filesystem, no root privileges, and a timeout per job. Isolation limits exposure; it does not make malicious files harmless.
Keys#
Volume passphrase, typed at boot ————— protects the powered-off box
└─ master key, a file on that volume —— protects document keys and sealed secrets
└─ a key per file ————————————— protects each document independentlyEvery document is encrypted under a key of its own, wrapped by the master key. The master key lives only on the encrypted volume and on the envelope. Rotating it re-wraps the per-file keys rather than re-encrypting each document.
The database keeps each document's text in the clear so that search is fast, which is why the data volume must be encrypted and the installer refuses otherwise.
Protections and limits#
| Someone | Gets | Protection and remaining limits |
|---|---|---|
| A burglar who takes the box | A powered-off appliance | With manual unlocking, the encrypted volume requires a passphrase kept separately |
| A breach at the backup provider | Snapshots | Snapshots are encrypted before upload; keep recovery keys separate from the provider |
| An attacker on the internet | Nothing to connect to, unless you chose the internet | Zero inbound ports on the tailnet path and on your own network. On the internet path, Caddy and the sign-in page, which needs a password and an authenticator code; the first account can only be created through the setup link |
| A malicious PDF sent by email | Code running in the OCR worker | The worker has no direct internet access or root privileges, but can reach required internal services |
| Someone with a stolen family laptop | A session | An existing session may still allow access. Revoke it promptly; MFA protects new sign-ins, not an already authenticated session |
Not defended against, by design: a compromised running server, which holds plaintext; a malicious owner account; and the model provider, which sees document text. There is no end-to-end encryption between household members. The repository's security page states this in full.