Installing Revaulter
Revaulter is distributed as a container image and runs as a single-container service.
Requirements#
- A container runtime (Docker, Podman, etc.)
- A database: SQLite or PostgreSQL
- HTTPS access for the web UI
- A webhook endpoint for notifications (Discord, Slack, or any HTTP endpoint)
HTTPS is required for Revaulter because it uses WebCrypto. You can either configure Revaulter to start a HTTPS server (which requires providing TLS certificates to Revaulter directly) or use a reverse proxy that performs TLS termination, such as Caddy, Traefik, Nginx, etc.
Container images#
| Image | Description |
|---|---|
ghcr.io/italypaleale/revaulter:2 | Revaulter server |
ghcr.io/italypaleale/revaulter-cli:2 | Revaulter CLI |
Both images are available for amd64 and arm64.
Configuration#
Revaulter is configured via a YAML file and/or environment variables. Inside the container, it looks for config.yaml at:
- The path set in the
REVAULTER_CONFIGenvironment variable /etc/revaulter/config.yaml$HOME/.revaulter/config.yaml- The same directory as the binary
Required configuration#
| Key | Env var | Description |
|---|---|---|
webhookUrl | WEBHOOKURL | Webhook endpoint for notifications |
databaseDSN | DATABASEDSN | Database connection string (see Database below) |
secretKey | SECRETKEY | Instance-wide secret for key derivation (see Secret key below) |
Recommended configuration#
| Key | Env var | Default | Description |
|---|---|---|---|
baseUrl | BASEURL | https://localhost:<port> | Public URL where users access the web UI. Used for webhook links and WebAuthn origin validation. |
sessionSigningKey | SESSIONSIGNINGKEY | Random at startup | Secret used to sign session tokens. Set this in production so sessions survive restarts. |
tlsPath | TLSPATH | Config file directory | Directory containing tls-cert.pem and tls-key.pem. Revaulter watches for changes and auto-reloads. |
tlsCertPEM | TLSCERTPEM | PEM-encoded TLS certificate (alternative to tlsPath) | |
tlsKeyPEM | TLSKEYPEM | PEM-encoded TLS key (alternative to tlsPath) |
Optional configuration#
| Key | Env var | Default | Description |
|---|---|---|---|
webhookFormat | WEBHOOKFORMAT | plain | Webhook format: plain, slack, or discord |
webhookKey | WEBHOOKKEY | Value sent as Authorization header on webhook requests (include the scheme, e.g. Bearer abc123) | |
port | PORT | 8080 | Port to bind to |
bind | BIND | 0.0.0.0 | Address/interface to bind to |
disableSignup | DISABLESIGNUP | false | Disable creation of new user accounts |
sessionTimeout | SESSIONTIMEOUT | 5m | Session duration before re-authentication is required (max: 1h) |
requestTimeout | REQUESTTIMEOUT | 5m | Default timeout for requests (can be overridden per-request; max: 24h) |
trustedProxies | TRUSTEDPROXIES | Comma-separated list of IPs/CIDRs to trust for X-Forwarded-* headers | |
forceSecureCookies | FORCESECURECOOKIES | false | Force the Secure flag on cookies (set to true when behind a TLS-terminating reverse proxy) |
trustedRequestIdHeader | TRUSTEDREQUESTIDHEADER | Header to trust as request ID (e.g. X-Request-ID, CF-Ray) | |
logHealthChecks | LOGHEALTHCHECKS | false | Include /healthz requests in the request logs |
logLevel | LOGLEVEL | info | Log level: debug, info, warn, error |
logAsJson | LOGASJSON | auto | Emit JSON logs (defaults to true when no TTY is attached) |
Optional WebAuthn configuration#
These settings are necessary in some scenarios only. Revaulter derives sensible defaults from baseUrl.
| Key | Env var | Default | Description |
|---|---|---|---|
webauthnRpId | WEBAUTHNRPID | Derived from baseUrl | WebAuthn Relying Party ID |
webauthnRpName | WEBAUTHNRPNAME | Revaulter | WebAuthn Relying Party display name |
webauthnOrigins | WEBAUTHNORIGINS | baseUrl | Allowed WebAuthn origins |
Database#
Revaulter supports SQLite and PostgreSQL. The backend is detected automatically from the DSN:
| DSN format | Backend |
|---|---|
postgres://user:pass@host:5432/dbname | PostgreSQL |
sqlite:///path/to/file.db | SQLite |
/path/to/file.db (no scheme) | SQLite |
SQLite requires no external dependencies and is a good default for single-node deployments.
For PostgreSQL, use a standard connection string, for example:
postgres://revaulter:password@db.example.com:5432/revaulter⚠️ Warning: When using SQLite, the database file must not be stored on a networked filesystem, like NFS or SMB.
Secret key#
Generate a secret key:
openssl rand -base64 32⚠️ Warning: Rotating
secretKeybricks every existing account on the instance. The secret key is used to derive the WebAuthn PRF salt that every user’s in-browser key derivation is bound to. Treat this value as immutable for the lifetime of the instance. If you must rotate it, every user will need to re-register from scratch.
📝 Note:
secretKeyis not used to encrypt anything stored in the database. All request payloads and responses are end-to-end encrypted in the browser; the server only stores opaque envelopes.
Session signing key#
Generate a session signing key:
openssl rand -base64 32Set sessionSigningKey in production so session tokens remain valid across restarts. If this value is omitted, Revaulter generates a random signing key at startup; existing sessions are invalidated whenever the process restarts.
TLS#
Revaulter requires HTTPS for WebAuthn to work (browsers enforce a secure context). You have two options:
- Reverse proxy (recommended): Terminate TLS at a reverse proxy (Caddy, Traefik, Nginx, etc.) and forward plain HTTP to Revaulter.
- Set
forceSecureCookies: truein this case.
- Set
- Direct TLS: Provide certificates via
tlsPath(a directory containingtls-cert.pemandtls-key.pem) or viatlsCertPEM/tlsKeyPEM. Revaulter watches thetlsPathdirectory and auto-reloads certificates.
Docker Compose example#
services:
revaulter:
image: ghcr.io/italypaleale/revaulter:2
ports:
- "8080:8080"
volumes:
- ./config.yaml:/etc/revaulter/config.yaml:ro
- revaulter-data:/data
restart: unless-stopped
volumes:
revaulter-data:With a config.yaml:
webhookUrl: "https://discord.com/api/webhooks/your-webhook-id/your-webhook-token"
webhookFormat: "discord"
databaseDSN: "/data/revaulter.db"
secretKey: "<your-secret-key>"
sessionSigningKey: "<your-session-signing-key>"
baseUrl: "https://revaulter.example.com"If you want Revaulter to handle TLS directly:
services:
revaulter:
image: ghcr.io/italypaleale/revaulter:2
ports:
- "443:8080"
volumes:
- ./config.yaml:/etc/revaulter/config.yaml:ro
- ./tls:/etc/revaulter/tls:ro
- revaulter-data:/data
restart: unless-stopped
volumes:
revaulter-data:And add to config.yaml:
tlsPath: "/etc/revaulter/tls"
port: 8080Place tls-cert.pem and tls-key.pem in the ./tls directory.
Podman Quadlet example#
First, store the config file as a Podman secret:
podman secret create revaulter-config ~/.config/revaulter/config.yamlCreate a container unit file at ~/.config/containers/systemd/revaulter.container (rootless) or /etc/containers/systemd/revaulter.container (rootful):
[Unit]
Description=Revaulter
After=network-online.target
[Container]
Image=ghcr.io/italypaleale/revaulter:latest
PublishPort=8080:8080
Secret=revaulter-config,target=/etc/revaulter/config.yaml
Volume=revaulter-data.volume:/data
AutoUpdate=registry
[Service]
Restart=always
[Install]
WantedBy=default.targetCreate a volume unit file at the same location, revaulter-data.volume:
[Volume]Then reload and start:
# Rootless
systemctl --user daemon-reload
systemctl --user enable --now revaulter
# Rootful
systemctl daemon-reload
systemctl enable --now revaulterTo update the config later, recreate the secret and restart the service:
podman secret rm revaulter-config
podman secret create revaulter-config ~/.config/revaulter/config.yaml
systemctl --user restart revaulterUser setup#
After starting Revaulter:
- Open the web UI at your configured
baseUrl. - Create an account: registration uses WebAuthn, so you’ll need a passkey-capable authenticator with PRF support.
- After registration, the UI shows your request key: this is the per-user key that CLI requests are routed by.
- Optionally configure allowed IP addresses for your account from the settings page.
Account self-registration can be disabled by setting
disableSignup: trueafter initial setup.