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

96 lines
4.0 KiB
Markdown

# Enterprise deployment guide
This guide complements [`../SECURITY.md`](../SECURITY.md) with the operational steps a regulated or
security-conscious organization needs to deploy Arboretum with confidence.
## 1. Remote access: Tailscale Serve (recommended)
Never open a public port. Keep the default `127.0.0.1` bind and put Arboretum behind Tailscale Serve:
```bash
# 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:
```bash
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:
```bash
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:
```bash
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):
```bash
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.