Security

Operator notes for running Frachtschiff on a single host. Frachtschiff is a homelab product by default - the Docker host is the trust boundary.

Host trust model

Anyone with:

can obtain application secrets and data. Treat the host accordingly.

With default Compose, secrets from deploy/.env are passed as environment variables - visible via docker inspect and process environ. Never commit deploy/.env.

Secret delivery

Mode How
Default Values in deploy/.env → Compose environment:
Hardened (optional) Files as Docker secrets → *_FILE paths (see deploy/examples/docker-compose.secrets.yml)

File-backed secrets remove values from container env listings but do not protect a fully compromised host.

Secret rotation

Container privileges and SMART

The API runs as root inside the container for drive I/O and optional SMART. That is intentional and is not multi-tenant isolation.

TLS and reverse proxy

Terminate TLS at your edge proxy. Strip or overwrite client-controlled forwarding headers (e.g. inbound X-Forwarded-For / True-Client-IP). Keep X-Forwarded-Proto so Secure cookies and refresh origin checks work.

Example Caddy / Traefik snippets: upstream deploy/examples/. Large tus uploads need long proxy timeouts (often up to an hour).

Database transport

Default stack uses sslmode=disable to Postgres on the internal Compose network - acceptable for that layout. If DATABASE_URL points at a remote host, enable TLS (require or verify-full).

Auth surfaces (do not mix)

Client Auth
Web UI HttpOnly cookies + CSRF on mutating requests
Sync client Bearer device token (no CSRF)
External API Bearer API key (no CSRF)
Share links Separate share session tokens

Optional TOTP for web login. Device tokens and API keys are issued after a full web sign-in and are not subject to 2FA on each request.

Encrypted archives

Password-protected ZIP/7z uses host 7z; passwords go on stdin (not argv). Still assumes a trusted host - not a multi-tenant isolation boundary.

Upstream detail: SECURITY-DEPLOY.md · SECURITY-AUTH.md.