# Security policy restic-manager handles credentials that grant access to backup repositories — losing them means an attacker can read or destroy a fleet's backups. We take security reports seriously even at this project's small scale. ## Supported versions Pre-1.0, only the latest tagged release on `main` is supported. Backporting fixes to older tags is not currently offered. | Version | Supported | |--------------------|----------------| | `main` HEAD | Yes | | Latest released tag| Yes | | Anything older | No | ## Reporting a vulnerability **Please don't open a public issue for security problems.** Instead, use one of these private channels: 1. **Gitea private message** to the repository owner. The instance is at and the owner's profile (`steve`) has direct-message contact set up. 2. **Email** to the address on the maintainer's Gitea profile. Use a subject like `[SECURITY] restic-manager: ` so it doesn't get lost. PGP optional — if you want to encrypt, ask for a key first. If you don't get an acknowledgement within **3 working days**, please escalate through the other channel — solo maintainers do miss things, and the goal here is to fix the problem, not to preserve protocol. ### What to include - A description of the issue and the impact (what does an attacker gain? confidentiality, integrity, availability?). - Affected component (server, agent, install script, docs). - Affected version (`restic-manager-server --version`). - Reproduction steps if you have them. A working PoC is welcome but not required — a credible threat model is enough. - Whether you intend to publish a writeup, and any timing preferences. ### What we'll do 1. Acknowledge receipt within 3 working days. 2. Confirm or refute the issue, and agree a rough severity (CVSS or just "this is bad / this isn't"). Asking clarifying questions is normal at this stage — please don't read it as foot-dragging. 3. Develop a fix on a private branch, test it, and prepare a release. 4. Coordinate disclosure timing with you. The default is **30 days from confirmed report to public disclosure**, with a patched release published before the disclosure date. Faster if a workable PoC is already circulating; slower only by mutual agreement. 5. Credit the reporter in the release notes (or omit the credit if you'd rather stay anonymous — your choice). ## Scope In scope: - The server binary (`cmd/server`) and any HTTP, WebSocket, or CLI surface it exposes. - The agent binary (`cmd/agent`) and the way it consumes commands from the server. - The install scripts (`deploy/install/install.sh`, `install.ps1`) and the systemd unit shipped with them. - The docker-compose reference deployment and the docker image we publish. - Any cryptographic primitive choice or implementation detail (AEAD, token hashing, session handling, OIDC handshake). - Documentation that, if followed, leads operators into an insecure configuration. Out of scope (not because they aren't real problems, just not ones this report channel can act on): - Vulnerabilities in restic itself — report those upstream at . - Vulnerabilities in third-party dependencies that haven't yet been patched upstream — report upstream first. - Issues that require pre-authenticated admin access on the control plane (admins can already do everything; that's not a privilege escalation, that's the design). - DoS via resource exhaustion on a deployment without the recommended reverse proxy / rate limiting in front (see `docs/reverse-proxy.md`). - Social-engineering scenarios that don't have a technical hook into the project's own surfaces. ## Threat model summary For context (longer version in [`spec.md`](./spec.md) §11): - The server is **HTTP-only**; TLS termination, ACME, HSTS, and edge rate-limiting are the reverse proxy's job. - Credentials are encrypted at rest with an AEAD key loaded from `RM_SECRET_KEY_FILE`. The same key encrypts agent secrets that travel to the agent over the WS channel. - Agents authenticate with bearer tokens issued at enrolment and hashed at rest. Compromise of the server DB does **not** leak bearer tokens in plaintext, but does leak the hashes (which is enough to log in *as* the agent until the operator revokes — see [NS-01 / NS-02](./tasks.md) for the revoke + regenerate flows). - The control plane intentionally **never touches backup bytes** — the agent runs `restic` directly against the repo. A compromised control plane can dispatch new jobs but cannot exfiltrate snapshot contents in-band. - Append-only credentials are first-class. Forget/prune jobs use a separate, admin-marked credential that the server only pushes for the duration of a maintenance dispatch. ## Hardening checklist for operators - Run behind a TLS-terminating reverse proxy (Caddy/nginx/Traefik). - Set `RM_TRUSTED_PROXY` to the proxy's CIDR so request IPs aren't spoofable. - Back up `RM_SECRET_KEY_FILE` separately from the database. Without it the encrypted creds are unrecoverable. - Use append-only credentials for the everyday backup path; only the optional admin credential should have write/forget/prune power. - Disable users (don't delete) when staff change roles — bearer tokens stay valid until rotated. - Watch the alert and audit-log views during enrolment of new hosts. Thanks for helping keep restic-manager users safe.