# 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.
