Skip to content

Security overview

Pier’s threat model assumes:

  • The operator controls the server and the Pier binary.
  • The operator wants secrets safe even if the SQLite file leaks.
  • The dashboard is on the public internet, behind Traefik TLS.
  • Encryption at rest — every environment variable is encrypted with AES-256-GCM before being stored. The key comes from PIER_SECRET (systemd reads it from /opt/pier/.env); if that variable is unset, Pier persists and reuses a .pier-secret file in the data directory. Either way the key lives separately from the database.
  • Opaque cookie sessions with bcrypt passwords — login issues a random, opaque session ID stored in the SQLite sessions table (not a JWT), so logout and revocation invalidate it server-side. Passwords are hashed with bcrypt. No third-party auth dependencies.
  • Two-factor auth (TOTP) — optional TOTP-based 2FA with one-time recovery codes.
  • Session hardening — sessions expire after an idle timeout (8 h default) and an absolute maximum lifetime (72 h), and can be revoked individually or all at once.
  • No secret echoing — API responses never return decrypted env vars except through an explicit GET /env endpoint.
  • Dependency detection on the backend — the Canvas view computes service relationships on the server so the browser never sees env-var values.
  • Permissions.env and pier.db are chmod 600.
  • Daily backups — the database and key are snapshotted to data/backups/system/; 7 rolling copies kept.
  • Open only ports 80, 443, and 8443 on the firewall.
  • Use a strong admin password on first setup.
  • Keep the /opt/pier/.env file (and the .pier-secret fallback in the data dir, if present) out of any repository. Back it up separately.
  • Rotate PIER_SECRET only if the old key is compromised — rotation requires re-encrypting all rows.
  • Consider running the dashboard behind a VPN instead of exposing port 8443 publicly. Pier supports this (bind the dashboard to 127.0.0.1 and access it via SSH tunnel or a WireGuard/AmneziaWG link).

Send details to the address in /.well-known/security.txt. We respond within 72 hours and publish acknowledgements with each release.