Files
arboretum/docs/ENTERPRISE_DEPLOYMENT.md
Johan LEROY 65ef616867
Some checks failed
CI / Build & test (Node 24) (push) Has been cancelled
CI / Pack & boot smoke (Node 22) (push) Has been cancelled
CI / No em/en dashes (push) Has been cancelled
CI / Build & test (Node 22) (push) Has been cancelled
Deploy site (production) / build-and-deploy (push) Successful in 20s
chore(typo): retire tous les tirets cadratins/demi-cadratins + garde CI
Remplace les 547 tirets cadratins (U+2014) et demi-cadratins (U+2013) des fichiers versionnés par la ponctuation contextuelle adaptée (point médian, deux-points, virgule, parenthèses ; tiret simple pour les plages), sur 122 fichiers (appli, vitrine, doc, tests, workflows, scripts).

Ajoute le job CI « lint-dashes » (git grep -P) qui échoue si un tiret cadratin/demi-cadratin réapparaît, hors logo binaire et captures brutes du terminal (fidélité des fixtures de détection de dialogue).
2026-07-17 16:44:00 +02:00

4.0 KiB

Enterprise deployment guide

This guide complements ../SECURITY.md with the operational steps a regulated or security-conscious organization needs to deploy Arboretum with confidence.

Never open a public port. Keep the default 127.0.0.1 bind and put Arboretum behind Tailscale Serve:

# on the host running arboretum (default bind 127.0.0.1:7317)
tailscale serve --bg 7317

This gives you TLS, a stable *.ts.net hostname, and tailnet identity. Then add that origin to the allow-list so the strict Origin check accepts it:

arboretum --allow-origin https://my-host.tailnet.ts.net

The --i-know-this-exposes-a-terminal flag exists only as an escape hatch for non-loopback binds; it is never a deployment mode and is never injected automatically by arboretum install.

2. Encryption at rest

Sensitive secrets (the HMAC server secret and the VAPID private key) are encrypted with AES-256-GCM before being stored in SQLite. Token values are never stored, only their SHA-256 hashes.

For strong protection (key not co-located with the database), provide a passphrase via the environment instead of the on-disk key file:

ARBORETUM_SECRET_KEY='<a long random passphrase from your secrets manager>' arboretum
  • Store this passphrase in your secrets manager / KMS, separately from database backups.
  • Without it, the key is auto-generated in dataDir/secret.key (0o600). This still protects a leaked database copy, but not a full dataDir compromise.
  • Rotating the passphrase requires re-encrypting existing values; the simplest path is to revoke and recreate the bootstrap token after rotation.

3. Filesystem permissions

On startup Arboretum forces dataDir to 0o700 and the database files (*.db, -wal, -shm) to 0o600. Verify after first run:

stat -c '%a %n' ~/.local/share/arboretum ~/.local/share/arboretum/*.db
# expect: 700 …/arboretum   and   600 …/arboretum.db

Keep $HOME private (standard 0o700). If you relocate data with --db or XDG_DATA_HOME, make sure the target directory is not world-readable.

4. Audit logging

All sensitive mutations are recorded in an append-only audit_logs table: token create/revoke, login success/failure, settings changes, secret generation, push subscribe/unsubscribe, group CRUD, and data erasure. Query it via the API (paginated):

curl -s -H "Authorization: Bearer $TOKEN" \
  'http://127.0.0.1:7317/api/v1/audit-logs?limit=100'

The audit log never contains secret values, only non-sensitive metadata (ids, labels, counters). It is also visible in the dashboard under Settings → Security & compliance.

5. GDPR (data subject requests)

  • Export: GET /api/v1/data/export returns every record tied to the authenticated token (token metadata, push subscriptions, session history, settings) as JSON. Also available as a one-click download in Settings → Security & compliance.
  • Erasure: POST /api/v1/data/delete-my-data is a two-step call: the first response returns a confirm code that must be POSTed back to execute. It purges the token's push subscriptions and revokes the token (unless it is the last active one).

6. Backups & retention

  • Back up the SQLite database (arboretum.db) with the WAL checkpointed. Treat backups as sensitive.
  • If you use ARBORETUM_SECRET_KEY, back the key up separately: a database backup is useless (and safe) without it, which is the point.
  • Session history is retained until the database is reset. To start clean, stop the service and remove the database file.

7. Logging hygiene

The log level is controlled by ARBORETUM_LOG (default info). Do not run debug/trace in production: verbose levels may log request metadata. Keep info or higher.

8. Supply chain

Each published release ships with a CycloneDX SBOM (sbom.json) generated in CI, so you can scan the dependency tree for known vulnerabilities before deploying.