Security model
This page describes what protects the backups of an endpoint, and where the protection stops. It follows the design of the agent and the server. Read it before you roll the agent out widely, especially the section on root rights.
Outbound only
Section titled “Outbound only”The agent opens no listening port. It connects out to your Restow instance over HTTPS, and to nothing else. The instance never connects to the endpoint. Tasks such as “back up now”, “restore” or “uninstall” travel in the answer to the agent’s regular contact with the instance.
Append-only, enforced by the instance
Section titled “Append-only, enforced by the instance”The agent writes to a restic repository that your instance exposes. The instance decides what the agent may do, not the agent and not restic:
- The agent authenticates with its own secret. The repository endpoint refuses every delete and every overwrite, except for lock files.
- The agent also never calls
forget,pruneor any delete operation itself. - Retention, pruning and integrity checks run only on the Restow server.
- The integration tests run the real agent against restic’s append-only REST server and assert that
restic forget --prunewith the agent’s credentials fails and leaves the snapshots in place.
Further protections of the repository endpoint:
- Object names must be a SHA-256 in hex, so no path can leave the repository. The server checks on upload that the content matches its name and stores nothing if it does not.
- Bodies over 128 MiB are refused. Requests are limited per endpoint, and wrong credentials are limited per address.
- Every attempt by an agent to do something forbidden is written to the audit log (
endpoint.repository.denied, at most one entry per endpoint and kind every 10 minutes). A machine that tries to delete its backups is a case for an administrator. - A revoked endpoint is refused and no longer backs up. A tenant that is suspended is refused too.
The agent never holds storage credentials
Section titled “The agent never holds storage credentials”The agent knows its own agent secret and the repository password of its own repository. It never receives the credentials of the storage target, such as S3 keys or mount paths. It has no access to other endpoints or to the storage target itself.
One repository and one password per endpoint
Section titled “One repository and one password per endpoint”The server generates the repository password, stores it encrypted with the tenant key and hands it to the agent at enrollment. Because the server keeps it, an administrator can restore even if the endpoint no longer exists. See Restore.
How the server reaches the repository
Section titled “How the server reaches the repository”Retention, repository checks, restore tests, browsing, downloads and the creation of the repository need more than append-only access. They run as restic processes on the server, through a listener on 127.0.0.1 that lives for exactly one operation. Its credentials are random for that one listener and are passed to restic through its environment. There is no publicly reachable maintenance access and no stored maintenance password. These restic processes receive only PATH, TMPDIR and the RESTIC_* variables, not the environment of the server, so they see neither the database URL nor the master key.
Secrets
Section titled “Secrets”| Secret | Where it is | How |
|---|---|---|
| Enrollment token | The command you copy | Valid 24 hours, single use. Restow stores only a SHA-256 hash. The agent reads it from the environment, never from a flag or a URL, and removes it from the environment at once. |
| Agent secret | /etc/restow-agent/state.json on the endpoint |
Stored on the server only as a SHA-256 hash. |
| Repository password | /etc/restow-agent/state.json on the endpoint |
On the server, encrypted with the tenant key. |
- At rest on the endpoint.
/etc/restow-agent/state.jsonholds the agent secret and the repository password in plain text. The file has mode 0600 in a directory with mode 0700, owned by root. The agent corrects looser permissions and refuses a file owned by someone else. Nothing else secret is stored.status.jsonis readable by everyone and contains no secrets. - In use. restic receives the repository password and the REST credentials only through environment variables, never on a command line. Child processes (restic and hooks) inherit only a short list of variables.
- In logs. Everything the agent logs, the log tail sent to the server and error messages pass a redactor. It masks the exact secret values, tokens,
Authorizationheaders, credentials inside URLs andNAME=valuepairs whose name suggests a secret. A hook that prints a secret of its own is not covered, see Profiles, schedule and hooks. - On the server. None of these secrets appear in logs or in audit details, and error messages from restic are redacted.
Integrity of what is installed
Section titled “Integrity of what is installed”The install scripts and the self-update verify SHA-256 checksums. Those checksums come from the same instance as the binaries. They protect against corrupted or truncated downloads. They do not protect against a compromised instance: whoever controls the instance controls what the agents download.
- Agent updates are not signed. Signed agent releases are a later step.
- The agent checks for a newer version every 6 hours. It downloads it from the same host as your instance, checks that the SHA-256 matches the announcement, runs it to see that it reports the announced version, and only then replaces the current binary. The old one stays as
restow-agent.prev. Updates are applied only while no run is active. - restic is pinned to version 0.19.1 with checksums that were verified against the GPG-signed
SHA256SUMSof the official release.
The agent runs as root, unconfined
Section titled “The agent runs as root, unconfined”The agent must read every file it backs up and write restores anywhere. Hooks are arbitrary commands chosen by an administrator in Restow. Whoever can change an endpoint’s configuration in Restow can therefore run commands as root on that machine. Treat administrator access to Restow accordingly and keep the number of administrators small.
The service runs with low CPU and I/O priority and is restarted by systemd or launchd if it stops.
Who may do what
Section titled “Who may do what”All endpoint functions in the web interface and the API need a tenant administrator or a provider administrator. Provider team roles are split like this:
| Provider role | May |
|---|---|
| Read only | See the list, the details, the runs and the restore points. |
| Technician | Back up now, restore, restore test, browse and download backed-up files. |
| Administrator | Create and revoke install commands, change the configuration and hooks, revoke and uninstall endpoints, show the repository password. |
See Team and roles for the roles themselves.
What a compromised endpoint can and cannot do
Section titled “What a compromised endpoint can and cannot do”The endpoint holds the password and the credentials of its own repository, because it has to write and to read for restores. An attacker with root on the endpoint therefore can:
- add new backups, including junk (restore tests and repository checks rate that, and retention cleans up),
- read its own repository, and so decrypt it,
- not delete or overwrite a backup, and not write a new repository configuration. The instance enforces this,
- not reach other endpoints, other tenants or the storage target.
A stolen agent secret gives the same: writing new backups to that endpoint’s repository and reading it, but not deleting anything. To cut it off, revoke the endpoint in Restow.
Audit log
Section titled “Audit log”Every read of backed-up files and every change is recorded in the audit log, in every edition. Viewing the log (search, details, chain verification) belongs to Business and Service Provider and is in development, see Audit log.
| Action | Recorded when |
|---|---|
endpoint.token.created, endpoint.token.revoked |
An install command is created or revoked. |
endpoint.enrolled |
A machine enrolls (host name, system, architecture, profile, token id, never a secret). |
endpoint.config.changed |
Settings change. For hooks, a fingerprint, not the text. |
endpoint.backup.requested, endpoint.restore_test.requested |
Someone starts a backup or a restore test. |
endpoint.snapshot.browsed, endpoint.snapshot.downloaded |
Backed-up files are browsed or downloaded. |
endpoint.restore.requested, endpoint.restore.finished |
A restore onto the machine is requested and when it finishes. |
endpoint.repository.password.revealed |
Someone shows the repository password. |
endpoint.uninstall.requested, endpoint.revoked |
An uninstall is requested or an endpoint is revoked. |
endpoint.repository.denied |
An agent tried something the append-only rules forbid. |
Known limits
Section titled “Known limits”- No mTLS yet. Version 1 authenticates each agent with a per-agent secret over HTTPS. A stolen secret (root on the endpoint) allows writing new backups to that endpoint’s repository and reading it. It does not allow deleting anything. mTLS per agent is planned for a later release.
- Checksums from the same instance. See above: a compromised instance can hand out a different agent, and agent updates are not signed.
- Root and hooks. The agent and its hooks run as root.
- The repository password decrypts the whole backup of an endpoint. Anyone who has it and can read the storage target can read every backed-up file.