# Hardening checklist

A baseline for new deployments. Most of these are defaults; the
list is here to make audit easy.

## Server

- [ ] Reverse proxy in front, TLS terminating at the proxy
      (Caddy/nginx/Traefik).
- [ ] `RM_TRUSTED_PROXY` set to the proxy's CIDR.
- [ ] `RM_BASE_URL` matches the public hostname and the cookie
      scope you want.
- [ ] `RM_COOKIE_SECURE=true` (the default; only set `false`
      for local HTTP testing).
- [ ] HTTP listener bound to **localhost** in the compose file,
      not `0.0.0.0`. The reverse proxy is the only thing that
      should reach it.
- [ ] `secret.key` backed up separately from the database.
- [ ] Bootstrap token consumed and the printed log line scrubbed
      from any log archive.

## Authentication

- [ ] Admin user has a password ≥ 12 characters (the floor).
- [ ] OIDC enabled if you have an IdP — local password auth
      stays as a break-glass.
- [ ] Disabled (not deleted) any users who change roles or leave
      so their session is invalidated immediately.
- [ ] The last-admin guard isn't tripped — there's always at
      least one enabled admin user.

## Repo credentials

- [ ] Append-only credential set as the everyday cred for every
      host.
- [ ] Admin credential set only where prune cadence is enabled.
- [ ] No credentials reused across hosts. Each host should have
      its own credential pair so a single host compromise has a
      single blast radius.
- [ ] If using rest-server, `--append-only` flag is on for the
      everyday user; the prune user is a separate identity.

## Agent

- [ ] Agent runs as `root` (Linux) or `LocalSystem` (Windows)
      **only when** the source paths require it. Otherwise pin
      a service user that has read access to what's backed up
      and nothing else.
- [ ] systemd unit's sandboxing flags are intact
      (`NoNewPrivileges`, `Protect*`, `MemoryDenyWriteExecute`).
- [ ] Agent's config file `/etc/restic-manager/agent.yaml` is
      mode `0600` and owned by the service user. The bearer
      token lives in there.

## Operations

- [ ] Alerts wired to a real channel (webhook into Slack,
      ntfy topic, SMTP) — not just sitting in the UI.
- [ ] Test-fire each notification channel after configuring.
- [ ] Audit-log retention is long enough to cover the operator's
      incident-response window.
- [ ] Prometheus endpoint, if enabled, gated by token AND CIDR
      where practical (default is opt-in / off).

## Recovery

- [ ] A documented procedure for rotating a leaked agent bearer
      (delete + re-enrol the host).
- [ ] A test-restore done at least once, end-to-end, before
      relying on the system in anger.
- [ ] `secret.key` and the SQLite database covered by separate
      backup paths so neither alone reconstitutes the other.
