Documentation
Bitwarden behavior and storage reference
backend-vault-http is a multi-instance, Bitwarden-compatible vault backend for
Everlock. The wire protocol, client crypto, and data model live in the
standalone apimeister-vault
engine; this page documents the Everlock-facing behavior.
Current state
- multi-instance and multi-vhost
- per-instance
versioned-storage, one record per file - serves the Bitwarden identity + API + real-time notification endpoints through
frontend-http - account registration, login, and vault unlock
- ciphers (logins, cards, identities, secure notes, SSH keys), folders, Sends, and file attachments — full server-side create, update, and delete
- real-time sync over the SignalR notifications websocket, so a change on one device appears on the others without a manual refresh
- verified end-to-end against the official Bitwarden desktop app and the
bwcommand-line client
Organizations, collections, and memberships exist in the data model and storage layer; the single-user vault is the verified, supported path today.
Shape
Each vault instance has:
- one instance name
- one dedicated store
- one or more vhosts
- one Bitwarden API surface served through
frontend-http
The instance's primary vhost sets the vault's token issuer and public base
URL (https://<vhost>): Bitwarden clients enforce the issuer and build absolute
attachment/Send URLs from it, so the vhost must be the address clients actually
use. The RS256 signing key is generated once and persisted in the instance store
(token-key.pem) so tokens survive restarts.
Example config (config/vault-http.toml in the system store; /backends enable vault-http in the admin console writes the enabled flag here):
enabled = true
[instances.default]
store = "everlock-vault"
vhosts = ["vault.example.com"]
open_signups = false # default: registration is invite-gated
The same single instance can be bootstrapped from the CLI or environment:
--backend-vault-http EVERLOCK_BACKEND_VAULT_HTTP=true
--backend-vault-http-vhost <host> EVERLOCK_BACKEND_VAULT_HTTP_VHOST
--backend-vault-http-store <name> EVERLOCK_BACKEND_VAULT_HTTP_STORE (default: everlock-vault)
--backend-vault-http-open-signups EVERLOCK_BACKEND_VAULT_HTTP_OPEN_SIGNUPS
Storage
Records are stored as one file per entity in versioned-storage; blobs
(attachments and file-Send payloads) are stored raw. The layout is:
accounts/<id>.toml
folders/<account>/<id>.toml
ciphers/<id>.toml
sends/<id>.toml
organizations/<id>.toml
memberships/<id>.toml
collections/<id>.toml
invites/<token>.toml
blobs/<category>/<owner>/<id>
token-key.pem
Every write is a Git commit, so the vault inherits full history: you can see when each item changed and recover prior state, the same way sites, mail, and calendars do. Item names, usernames, passwords, and notes are stored only as the client's encrypted CipherStrings — the store never contains plaintext.
Zero-knowledge model
The master password never reaches the server. Clients derive keys locally and send only:
- a master-password hash used purely as a login verifier
- the protected account key and other keys, each encrypted under keys derived from the master password
The server stores those values verbatim and hands them back at login; decryption happens entirely on the client. An operator with full store access sees ciphertext and verifiers, not secrets. Because the store is a plain Git repository, you can confirm this yourself by cloning it and inspecting the contents.
Access model
Three separate questions decide access, and the vault answers each in a different place.
Serving a request. The vault is the one backend whose request path does
not sit behind Everlock's HTTP Basic auth or the shared
role-on-access-path grant model. Bitwarden clients authenticate with the
account's own master-password/token flow, so Everlock bypasses its HTTP
middleware for the vault's vhost.
Administering an instance. Account administration is an ordinary grant on:
http/vault/<instance>
An instance's Owner may run /vault accounts list and
/vault accounts delete against it, as may a system administrator.
/vault create grants its caller Owner on the instance it creates. The grant
covers the account list, not the account contents: items are client-encrypted,
so an owner administers accounts without being able to read them.
Registering an account. Registration is set per instance by open_signups:
open_signups = false(default) — registration is invite-gated by the vault's provisioning policy, which reads invite records from the instance storeopen_signups = true— anyone who can reach the vhost may register
A future release ties registration to the Everlock user registry, so account
creation follows the same identity model as the rest of the system; see the
notes in docs/backends/vault.md in the repository.
TLS
Point the instance at a public vhost and configure an HTTPS listener on
frontend-http; the host becomes ACME-managed automatically, exactly like the
site, image, and OCI backends. Bitwarden clients require HTTPS, so a real
certificate (or a trusted tunnel) is expected in normal use.
Compatibility
- Clients: Bitwarden desktop, browser extensions, mobile, and
bwCLI. - Not included: emergency access, device-approval login, and the paid self-hosted admin portal. The engine's own docs track the full protocol surface and roadmap.