How it works
Every customer gets their own Vaultwarden process with its own data directory, in its own sandbox. All of them run on one host.
The path of a request
- Caddy is the only program listening on the public interface. It terminates TLS for every vault, with one wildcard certificate for all the vaults' hostnames, so that no vault's name is published in the public Certificate Transparency logs.
- The activator, Libreyard's own program, reads the hostname, starts your instance if it is stopped, and passes the request on.
- Your Vaultwarden answers, from its own port and its own data directory.
The portal, where you sign up and pay, runs beside these and decides which instances exist. Your vault's traffic does not go through it.
Stock Vaultwarden
The server and the web vault are taken from the official vaultwarden/server image at a pinned digest, without changes. Settings are ordinary environment variables: the address, the admin token, sign-ups off, invitations on, and three values that keep memory use low.
The server runs directly on the host rather than inside Docker, but its data directory is the same. The archive you download starts under the official image, and the test suite checks that on every run. The digest is named in the archive's README.
The sandbox
Each instance runs without root, with:
- a limit of 128 MB of memory, one CPU core and a small number of processes;
- its own process, mount, IPC and hostname namespaces;
- a read-only view of the file system, apart from its own data directory;
- no capabilities, and a system-call filter;
- network rules that let it listen only on its own port, and connect out only to DNS, HTTPS and mail ports.
If the sandbox cannot be set up, the instance does not start.
Known limits
- All instances run as the same user on the host. A user per customer needs root, and is not built.
- There is no disk quota.
- Network rules are by port, not by address.
- The sandbox tests have run on a development laptop, not yet on the production host.
Stopped when idle
A household's vault is idle almost all the time, so an instance with no requests is stopped after a short while and started again by the next request. On a laptop, with Vaultwarden 1.37.4 and the Bitwarden web vault, a client saw the start take 115 to 135 milliseconds. The activator keeps each client's notification connection open while the instance is stopped, so changes made on one device still reach the others.
Vaultwarden's scheduled jobs only run while it is running, so the activator wakes each instance for them.
Upgrades
All instances run the same Vaultwarden version. A new release goes on Libreyard's own instances first, then on everyone's.
Now and then a Bitwarden client release breaks compatibility until Vaultwarden catches up. When that happens the fix comes from upstream, and Libreyard upgrades when it arrives.
Backups
Every vault's data directory is backed up regularly with restic, encrypted on the host, to object storage. You can also take a backup yourself at any time with "Back up now" in the portal, for example before a large import. Each week a recent backup is restored, checked, and one vault from it is started. Backups are kept for about two months.
Restoring is done by Libreyard for now: write in, and say which backup. You can also download your data at any time.
One host
Everything runs on one virtual machine at Linode. One host is one point of failure. If it is down, clients keep working from their offline copy but cannot sync.
What you cannot check
Libreyard's own code, the portal, activator and sandbox, is not open source. What you can check is that your data directory is ordinary Vaultwarden data, by running it yourself.