Docs · Concepts
Encryption and the recovery key
Your data is encrypted on your server before it leaves, with a key that never leaves it. Here is what that means in practice: where the keys are, where to keep the recovery key, and what we can’t do for you if it is lost.
Markdown versionThe CLI prints English by default (`--lang fr|es` for French or Spanish). Some output blocks come from a French session: they are labelled and translated in the text.
How it works
- The agent uses restic (version 0.18.1, open source) to encrypt everything on your server with AES-256 before sending it. Only locked blocks reach the storage.
- At install, a random repository key is generated on your server and written to
/etc/neverwiped/repo.key(readable by root only). It is never sent to us. - A second key, the recovery key, is added to the repository and shown to you once. It opens the same repository, so you can still read your backups if the server and its
repo.keyare gone. - Everything travels over TLS (HTTPS). The storage disks are encrypted at rest as well; that protects against a lost disk, not against someone on a running server.
- Restores are decrypted on your server, never on ours.
Where each key lives
| Key | Where | Who can read it |
|---|---|---|
| Repository key | /etc/neverwiped/repo.key on your server | root on that server |
| Recovery key | Your password manager | You. Shown once at install, never stored by us. |
| Storage login | /etc/neverwiped/config.json on your server | root on that server; it can add backups and read them, not delete them |
Account API key (nw_acc_…) | Your dashboard, shown once | You; used only to register a server or to recover a lost one (neverwiped recover) |
Several servers
Each server you install gets its own set of keys. Nothing is shared between two servers of your account:
| Per server | What it means |
|---|---|
Agent key (nw_agt_…) | Made at registration, bound to that server. It can’t act for another server. |
| Storage login | Opens that server’s repository only, in add-only mode. |
| Repository key | Generated on that server, never sent. |
| Recovery key | One per server, shown once at its install. |
So a leak on one server (root access, a copied config.json) exposes that server’s backups, not the others. Uninstalling or recovering one server revokes its keys only.
- One account API key for many installs is fine. It only registers servers (and recovers a lost one). Each server then has its own agent key, so you can revoke the account key afterwards. Your plan sets how many servers count at once; an install beyond it is refused, even when several start at the same moment.
- Label every recovery key. The box at install shows the server’s name, its ID and a check code such as
4342-B317. Write the three next to the key. The same code is on the server’s page in your dashboard, under “Clés de ce serveur”, and inneverwiped status. The code can’t open anything; it only tells which key belongs to which server. - **
neverwiped recoverchecks the key before it revokes anything.** If the key you type is another server’s, it says which one and stops: the server you picked keeps working. Servers installed before the check code existed get it at their next backup; until then the key is checked only after the credentials are reissued. - **Never clone a server with
/etc/neverwipedin it**, and never copy that folder to another machine. Two machines would share one server’s keys. The agent notices (the machine ID in/etc/machine-iddiffers) and refuses to back up there. On the copy, runneverwiped uninstall --yes: it removes the copied keys from that machine only and doesn’t tell the platform, so the original keeps its keys. Then install again: the copy becomes a new server with its own keys. If it is the same server and only its machine ID changed (OS reinstalled with/etc/neverwipedput back), runneverwiped install --same-server.
Keep the recovery key well
- Put it in a password manager the day you install, with the server’s name in the entry.
- Not on the server itself: if the server is lost, the key goes with it.
- Not in a Git repository, a project file, a chat with an AI agent, or a ticket.
- A printed copy in a safe place is fine.
- The key is shown only when the repository is created. Reinstalling on the same server doesn’t show it again.
Lost your recovery key?
What can be done depends on one thing: **does the server still run, with /etc/neverwiped/repo.key on it?**
| Your situation | What you can do |
|---|---|
| Server runs, recovery key lost | Make a new one now: sudo neverwiped recovery-key new. Nothing is lost. |
| Server runs, not sure the key you wrote is right | Test it: sudo neverwiped recovery-key check. The key isn’t sent anywhere. |
| Server gone, you still have a recovery key | Use it on a new server: [neverwiped recover](/docs/getting-started#whole-server). An older recovery key of that server works too. |
Server gone, but you have a copy of its /etc/neverwiped (or a disk snapshot from your host taken after the install) | repo.key in that copy opens the backups like a recovery key. Put it in a file and run neverwiped recover --recovery-key-file FILE --repo-key on a new server. |
Server gone, no recovery key, no copy of repo.key | The backups can’t be read, by you or by us. See What we can’t do. |
**What recovery-key new does.** It uses this server’s repo.key to add a second recovery key to the repository, checks that the new key opens the backups, then shows it once, with the server’s name and a new check code. Only the check code is sent to us. Your client area then shows the new code, and the account owner gets an e-mail about the change. The old code stays on record too, so neverwiped recover still accepts the old key if you find it.
What it doesn’t do. It doesn’t remove the old key. The storage only accepts additions from your server, and we hold no key, so the old key keeps opening these backups. That’s fine if you only lost it (a drawer, a deleted password-manager entry). If someone else may have seen it, that’s a leak, not a loss: see If you think a key leaked.
After a new key:
- Store it in your password manager, with the server’s name and the new check code.
- Test the written copy:
sudo neverwiped recovery-key check. - Throw away the copies of the old key only after that.
What support can do: help you find which server a check code belongs to, and record the code of a new key if the platform refused it (after ten replacements). Support can’t open, decrypt or restore your backups, and can’t make a recovery key for you. Backups you can no longer read still take space: delete that server in your dashboard (server page) to remove them.
What we can’t do
We can’t read your backups, decrypt them, or restore them for you. We don’t have the repository key or the recovery key, and no “master key” exists.
What our support console shows of your account: your address, billing, servers (name, agent version, size) and backup runs (dates, sizes, file counts, result). It doesn’t show your backup plan, and file paths in error messages are masked. It can’t make a storage login. Each support action needs a written reason and appears in your audit log with that reason.
So, if you lose both the server and the recovery key, your backups can’t be read, by you or by us. While the server still runs, nothing changes: the agent keeps using repo.key. That is the price of encryption we can’t open, and we’d rather say it plainly.
Team access
You can give colleagues access to your account from your dashboard › Team. Each person signs in with their own address and password; you pick a role:
| Role | What it allows |
|---|---|
| Owner | Everything, including deleting the account. The person who created the account; can’t be removed. |
| Admin | Servers, API keys, plan and invoices, and the team (technicians and viewers). Only the owner adds or removes admins. |
| Technician | Servers, retention, API keys and the install command. No billing, no team. |
| Viewer | Dashboard, history and server pages. Changes nothing, creates no key. |
No role gives access to what is inside your backups: the platform never has the recovery key. An invitation link is sent to one address, works once, for 7 days, and only for an account with that confirmed address. The owner gets an e-mail each time someone joins.
Removing someone ends their access at their next page and revokes the account API keys and API tokens they created. Servers already installed keep backing up: each has its own agent key. If that person had root on your servers, change that access too: we don’t control it.
Signing in: two-step and passkeys
In your dashboard › My account › Security you can protect the sign-in to this site with a second step:
- Passkey or security key: uses your device’s lock (fingerprint, face or PIN) or a USB/NFC key. It works only on this site, so a look-alike site can’t reuse it. You can also sign in with a passkey alone, without your password.
- Authenticator app: a 6-digit code from an app such as Aegis, Google Authenticator, 1Password or Bitwarden, asked after your password. Each code works once.
- 10 recovery codes, shown once when you turn on your first method. Each one replaces the second step one time. Keep them away from your phone.
Once it’s on, the password alone no longer opens your account, even after a password reset by e-mail. Turning it on signs out your other sessions, and every change is e-mailed to you. Each team member sets their own. Back-office accounts must have one.
This protects access to the website only. It changes nothing about how your backups are encrypted: the recovery key of each server stays the only key to its data.
Lost your phone, your key and your recovery codes? Write to support from the account’s address. An e-mail alone isn’t enough to remove the protection, because that’s exactly what someone holding your mailbox would ask: we check your identity first, which can take a few working days. Your backups keep running meanwhile.
API tokens for your scripts
In your dashboard › API keys › API tokens you can make a token for a monitoring script or dashboard. It opens the public API, which is read-only:
| Scope | What it reads |
|---|---|
servers:read | GET /api/v1/servers and /api/v1/servers/{id}: status, last backup, last check, space used |
runs:read | GET /api/v1/servers/{id}/runs?limit=50&before=…: backup, check and clean-up history, newest first |
usage:read | GET /api/v1/usage: plan, quota, space used |
invoices:read | GET /api/v1/invoices: numbers, dates, amounts (the PDFs stay in the dashboard) |
audit:read | GET /api/v1/audit?after=…: the account's audit log, oldest first (see Audit log) |
GET /api/v1/token tells you what a token is (scopes, expiry). Send it as Authorization: Bearer nw_tok_….
- A token can't change or delete anything, can't register a server and doesn't work for the agent. No token can read the content of your backups: we don't have the keys.
- You pick its scopes, within what your team role allows (only the owner and admins can give
invoices:readandaudit:read). If your role changes later, the token loses what the new role doesn't allow, at once. If you leave or are removed from the team, your tokens are revoked. - Every token expires after 30, 90 or 365 days (90 by default). It is shown once; we keep only a fingerprint.
- The API keys page shows, for each token, when and from which address it was last used and how many calls it made in the last 30 days. Making or revoking a token and every refused call are written to the account's log.
- Limit: 60 calls per minute per token.
Audit log
The owner and the admins have a page Audit log in the dashboard. It shows who did what on the account, when and from which address:
- sign-ins (password, two-step, passkey), password changes and two-step settings of the owner and of each member, from the day they joined the team;
- team invitations, arrivals, role changes and removals;
- API keys and tokens made or revoked, and API calls refused for a missing scope;
- servers deleted and retention changes, with the person who made them;
- plan changes, cancellations and resumptions;
- every action of NeverWiped support on your account (opening it, signing you out, resetting two-step, revoking a server's agent keys, a refund), shown as "NeverWiped support" with the reason given;
- each download of the log itself.
Backup runs are not in it: they are on the History page and in GET /api/v1/servers/{id}/runs.
Filter by dates and category, then download CSV (opens in a spreadsheet, UTF-8) or JSON. A file covers at most 366 days and 50,000 rows. Times in the files are UTC. Cells that a spreadsheet could run as a formula start with an apostrophe.
For a security tool (SIEM), make an API token with audit:read and read GET /api/v1/audit?after=<id>&limit=500: events come oldest first; keep next_after and send it back as after next time. Without after, it starts 30 days back (or at since=<ISO date>).
The log holds the addresses and IPs of your members, which is why technicians and read-only members don't see it.
If you think a key leaked
- **Recovery key or
repo.key:** whoever has it and the storage login can read that server’s backups. Rotating the repository key isn’t available from the CLI yet: write to support, and consider a fresh install on a new repository (neverwiped uninstall --yes, thenneverwiped installcreates a new repository). - Account API key: revoke it in your dashboard › API keys. Installed servers keep working.
- API token: revoke it in your dashboard › API keys › API tokens. It could only read, never change anything.
- Storage login (
config.json): it can’t delete backups, but write to support to have it reissued.
More on what an AI agent can and can’t do with these: For AI agents.