Jesse A. Green / notebook

Live demo: the DocCompiler guide library as a static, read-only snapshot (October 2026). No backend, no accounts, nothing to submit.

Vaultwarden — Administrator & Developer Guide

Generated May 2026 from dani-garcia/vaultwarden at f21a3ad

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

1. Architecture Overview

Vaultwarden is an unofficial, lightweight implementation of the Bitwarden server API written in Rust. It replaces the official multi-container .NET Bitwarden server with a single binary that implements the complete Bitwarden client API (268 endpoints), enabling compatibility with all official Bitwarden clients. The project is licensed under AGPL-3.0-only.

The server is built on the Rocket web framework with Diesel ORM for database access and supports SQLite, PostgreSQL, and MySQL/MariaDB backends. All authentication uses RS256 JWT tokens with an auto-generated RSA-2048 key pair. Configuration is driven entirely through environment variables processed by a custom make_config! macro that generates a type-safe configuration system with validation, admin panel integration, and runtime updates.

Architecture Diagram

┌─────────────────────────────────────────────────────────┐
│                    Bitwarden Clients                     │
│  (Browser, Desktop, Mobile, CLI)                        │
└──────────────────────┬──────────────────────────────────┘
                       │ HTTPS (via reverse proxy)
┌──────────────────────▼──────────────────────────────────┐
│                   Vaultwarden Binary                     │
│  ┌─────────────┐  ┌──────────┐  ┌────────────────────┐ │
│  │ Rocket HTTP  │  │ WebSocket│  │ Admin Panel (HBS)  │ │
│  │ Server       │  │ Hub      │  │                    │ │
│  └──────┬──────┘  └────┬─────┘  └────────┬───────────┘ │
│         │              │                  │              │
│  ┌──────▼──────────────▼──────────────────▼───────────┐ │
│  │                   API Layer                         │ │
│  │  /api/* (core)  /identity/* (auth)  /admin/*       │ │
│  │  /icons/*       /notifications/*    /events/*      │ │
│  └──────────────────────┬─────────────────────────────┘ │
│         │               │                │               │
│  ┌──────▼───┐  ┌───────▼────┐  ┌───────▼────────────┐  │
│  │ Auth/JWT  │  │ Diesel ORM │  │ Background Jobs    │  │
│  │ (RS256)   │  │            │  │ (job_scheduler_ng) │  │
│  └──────────┘  └──────┬─────┘  └────────────────────┘  │
│                        │                                 │
└────────────────────────┼─────────────────────────────────┘
                         │
              ┌──────────▼──────────┐
              │   Database Backend   │
              │  SQLite / PostgreSQL │
              │  / MySQL-MariaDB     │
              └─────────────────────┘

Note

Vaultwarden compiles database support via Cargo feature flags. The official Docker images include all three backends. Source builds must choose one: --features sqlite, --features postgresql, or --features mysql.

Component Inventory

Component Path Role
src/main.rs Entry point CLI parsing, startup, signal handling, job scheduling
src/config.rs Configuration make_config! macro, env var processing, validation
src/auth.rs Authentication JWT (RS256), RSA key management, request guards
src/crypto.rs Cryptography PBKDF2, HMAC, random generation
src/api/ API handlers All HTTP endpoint implementations
src/api/core/ Core API Ciphers, folders, collections, organizations, sends
src/api/core/two_factor/ 2FA TOTP, WebAuthn, Duo, YubiKey, Email implementations
src/api/identity/ Identity Login, token refresh, SSO flows
src/api/admin.rs Admin panel Web-based admin interface
src/api/icons.rs Icons Favicon proxy/cache service
src/api/notifications.rs Notifications WebSocket hub for real-time sync
src/db/ Database layer Diesel models, migrations, connection pool
src/db/models/ Data models All entity types (User, Cipher, Organization, etc.)
src/mail.rs Email SMTP/sendmail integration, Handlebars templates
src/sso.rs / src/sso_client.rs SSO OpenID Connect client implementation
src/http_client.rs HTTP client Outbound requests with IP blocking
src/ratelimit.rs Rate limiting Per-IP rate limiting for auth endpoints
docker/ Docker Dockerfiles, build scripts, healthcheck

Technology Stack

Layer Technology Version/Notes
Language Rust 1.92.0+ (1.94.1 in Docker builds)
Web Framework Rocket Async, custom config
ORM Diesel With r2d2 connection pool
Database SQLite / PostgreSQL / MySQL Compile-time feature selection
JWT jsonwebtoken RS256 with 2048-bit RSA
2FA webauthn-rs, yubico, oath WebAuthn, YubiKey OTP, TOTP
SSO openidconnect Full OIDC flow with PKCE
Email lettre SMTP + sendmail support
Templates Handlebars Email + admin panel rendering
Object Storage OpenDAL S3 via AWS credential chain
Allocator mimalloc (optional) enable_mimalloc feature flag
Container Docker Debian trixie / Alpine 3.23, multi-arch

2. System Requirements

Hardware

Deployment CPU RAM Disk
Personal (1-5 users) 1 core 64 MB 500 MB
Small team (5-50 users) 1-2 cores 256 MB 2 GB
Organization (50+ users) 2+ cores 512 MB+ 10 GB+

Software

Dependency Requirement
Docker 20.10+ (for container deployment)
Rust 1.92.0+ (for source builds)
OpenSSL Required for TLS and crypto operations
Web Vault v2026.2.0 (must match server version)

Supported Platforms

Architecture Debian Alpine
linux/amd64 Yes Yes
linux/arm64 Yes Yes
linux/arm/v7 Yes Yes
linux/arm/v6 Yes Yes

3. Configuration Reference

Vaultwarden uses a custom make_config! macro that generates a type-safe configuration system. All settings are environment variables (uppercased). Settings can also be modified at runtime through the admin panel (editable settings only) and are persisted to config.json in the data folder.

Important

Environment variables set at startup take precedence initially, but admin panel changes are persisted to config.json which overrides environment variables on subsequent startups. If a setting appears in both, the config.json value wins and a warning is logged listing the overridden variables.

Folders

Variable Type Default Editable Description
DATA_FOLDER String data No Main data directory
DATABASE_URL String {DATA_FOLDER}/db.sqlite3 No Database connection string
ICON_CACHE_FOLDER String {DATA_FOLDER}/icon_cache No Icon cache directory
ATTACHMENTS_FOLDER String {DATA_FOLDER}/attachments No File attachments directory
SENDS_FOLDER String {DATA_FOLDER}/sends No Send files directory
TMP_FOLDER String {DATA_FOLDER}/tmp No Temporary upload directory
TEMPLATES_FOLDER String {DATA_FOLDER}/templates No Custom template overrides
RSA_KEY_FILENAME String {DATA_FOLDER}/rsa_key No RSA key file path (without .pem)
WEB_VAULT_FOLDER String web-vault/ No Web vault static files

WebSocket

Variable Type Default Editable Description
ENABLE_WEBSOCKET bool true No Enable WebSocket notifications

Push Notifications

Variable Type Default Editable Description
PUSH_ENABLED bool false No Enable push notifications
PUSH_RELAY_URI String https://push.bitwarden.com No Push relay server URL
PUSH_IDENTITY_URI String https://identity.bitwarden.com No Push identity server URL
PUSH_INSTALLATION_ID Password (empty) No Installation ID from bitwarden.com/host
PUSH_INSTALLATION_KEY Password (empty) No Installation key from bitwarden.com/host

Important

Push relay and identity URIs must start with https://. All three push settings (enabled, ID, key) must be configured together.

Scheduled Jobs

All cron schedules use 6-field cron syntax (sec min hour day month weekday). Set a schedule to empty string to disable that job. Set JOB_POLL_INTERVAL_MS=0 to disable all scheduled jobs.

Variable Type Default Description
JOB_POLL_INTERVAL_MS u64 30000 How often the scheduler checks for jobs (ms). 0 = disable all.
SEND_PURGE_SCHEDULE String 0 5 * * * * Purge expired Sends (hourly)
TRASH_PURGE_SCHEDULE String 0 5 0 * * * Delete trashed items past retention (daily)
INCOMPLETE_2FA_SCHEDULE String 30 * * * * * Check for incomplete 2FA logins (every minute)
EMERGENCY_NOTIFICATION_REMINDER_SCHEDULE String 0 3 * * * * Send emergency access reminders (hourly)
EMERGENCY_REQUEST_TIMEOUT_SCHEDULE String 0 7 * * * * Grant timed-out emergency requests (hourly)
EVENT_CLEANUP_SCHEDULE String 0 10 0 * * * Clean old events (daily)
AUTH_REQUEST_PURGE_SCHEDULE String 30 * * * * * Clean old auth requests (every minute)
DUO_CONTEXT_PURGE_SCHEDULE String 30 * * * * * Clean expired Duo contexts (every minute)
PURGE_INCOMPLETE_SSO_AUTH String 0 20 0 * * * Clean incomplete SSO auth records (daily)

General Settings

Variable Type Default Editable Description
DOMAIN String http://localhost Yes Full server URL including protocol
WEB_VAULT_ENABLED bool true No Enable the web vault UI
SENDS_ALLOWED bool true Yes Allow users to create Sends
HIBP_API_KEY Password (unset) Yes HaveIBeenPwned API key for breach checking
USER_ATTACHMENT_LIMIT i64 (unset) Yes Per-user attachment storage limit (KB)
ORG_ATTACHMENT_LIMIT i64 (unset) Yes Per-org attachment storage limit (KB)
USER_SEND_LIMIT i64 (unset) Yes Per-user Send storage limit (KB)
TRASH_AUTO_DELETE_DAYS i64 (unset) Yes Days before trashed items are auto-deleted
INCOMPLETE_2FA_TIME_LIMIT i64 3 Yes Minutes before incomplete 2FA triggers notification (0 = disable)
DISABLE_ICON_DOWNLOAD bool false Yes Disable icon fetching (serves cached only)
SIGNUPS_ALLOWED bool true Yes Allow new user self-registration
SIGNUPS_VERIFY bool false Yes Require email verification for signups
SIGNUPS_VERIFY_RESEND_TIME u64 3600 Yes Seconds between auto-resent verification emails
SIGNUPS_VERIFY_RESEND_LIMIT u32 6 Yes Max auto-resent verification emails (0 = no limit)
SIGNUPS_DOMAINS_WHITELIST String (empty) Yes Comma-separated allowed signup domains
ORG_EVENTS_ENABLED bool false No Enable organization event logging
ORG_CREATION_USERS String (empty) Yes Comma-separated emails allowed to create orgs, all or none
INVITATIONS_ALLOWED bool true Yes Allow org admins to invite users
INVITATION_EXPIRATION_HOURS u32 120 No Token expiration for invites, email verify, delete requests (min: 1)
EMERGENCY_ACCESS_ALLOWED bool true Yes Enable emergency access feature
EMAIL_CHANGE_ALLOWED bool true Yes Allow users to change their email
PASSWORD_ITERATIONS i32 600000 Yes Server-side PBKDF2 iterations (min: 100,000)
PASSWORD_HINTS_ALLOWED bool true Yes Allow users to set password hints
SHOW_PASSWORD_HINT bool false Yes Show hints on login page when SMTP not configured
ADMIN_TOKEN Password (unset) Yes Admin panel authentication token (Argon2id PHC recommended)
INVITATION_ORG_NAME String Vaultwarden Yes Organization name in invitation emails
EVENTS_DAYS_RETAIN i64 (unset) No Days to retain events (unset = indefinite)

Advanced Settings

Variable Type Default Editable Description
IP_HEADER String X-Real-IP Yes Header for client IP detection (none to use remote IP)
ICON_SERVICE String internal No Icon service: internal, bitwarden, duckduckgo, google, or custom URL with {}
ICON_REDIRECT_CODE u32 302 Yes HTTP redirect code for external icon services (301/302/307/308)
ICON_CACHE_TTL u64 2592000 Yes Positive icon cache expiry (seconds, default 30 days)
ICON_CACHE_NEGTTL u64 259200 Yes Negative icon cache expiry (seconds, default 3 days)
ICON_DOWNLOAD_TIMEOUT u64 10 Yes Icon download timeout (seconds)
HTTP_REQUEST_BLOCK_REGEX String (unset) Yes Regex to block internal HTTP requests to specific domains/IPs
HTTP_REQUEST_BLOCK_NON_GLOBAL_IPS bool true Yes Block HTTP requests to non-global/reserved IPs
DISABLE_2FA_REMEMBER bool false Yes Force 2FA on every login (ignore "remember" checkbox)
AUTHENTICATOR_DISABLE_TIME_DRIFT bool false Yes Only accept current TOTP code (no ±30s drift)
EXPERIMENTAL_CLIENT_FEATURE_FLAGS String (empty) No Comma-separated list of client feature flags to enable
REQUIRE_DEVICE_EMAIL bool false Yes Require new device email notification on login
RELOAD_TEMPLATES bool false Yes Reload templates on every request (dev only)
EXTENDED_LOGGING bool true No Enable timestamp, target, and level in log output
LOG_TIMESTAMP_FORMAT String %Y-%m-%d %H:%M:%S.%3f Yes Timestamp format for extended logging
USE_SYSLOG bool false No Log to syslog (Unix only)
LOG_FILE String (unset) No File path for log output
LOG_LEVEL String info No Log level: trace/debug/info/warn/error/off (supports per-module overrides)
ENABLE_DB_WAL bool true No Enable SQLite WAL mode
DB_CONNECTION_RETRIES u32 15 No Database connection retry attempts (0 = infinite)
DATABASE_TIMEOUT u64 30 No Database connection acquisition timeout (seconds)
DATABASE_IDLE_TIMEOUT u64 600 No Idle connection timeout (seconds)
DATABASE_MAX_CONNS u32 10 No Maximum database connection pool size (1-256)
DATABASE_MIN_CONNS u32 2 No Minimum database connection pool size (1-256)
DATABASE_CONN_INIT String (empty) No SQL statements to run on new connections
DISABLE_ADMIN_TOKEN bool false No Disable admin token requirement (use external auth)
ALLOWED_IFRAME_ANCESTORS String (empty) Yes Domains allowed to embed web vault in iframe
ALLOWED_CONNECT_SRC String (empty) Yes Additional CSP connect-src domains (HTTPS only)
LOGIN_RATELIMIT_SECONDS u64 60 No Seconds between login attempts before rate limiting
LOGIN_RATELIMIT_MAX_BURST u32 10 No Burst size for login rate limiter
ADMIN_RATELIMIT_SECONDS u64 300 No Seconds between admin login attempts before rate limiting
ADMIN_RATELIMIT_MAX_BURST u32 3 No Burst size for admin rate limiter
ADMIN_SESSION_LIFETIME i64 20 Yes Admin session duration (minutes)
ORG_GROUPS_ENABLED bool false No Enable organization groups (beta)
INCREASE_NOTE_SIZE_LIMIT bool false Yes Raise secure note limit from 10,000 to 100,000 chars
ENFORCE_SINGLE_ORG_WITH_RESET_PW_POLICY bool false No Require Single Org policy before Reset Password policy
DNS_PREFER_IPV6 bool false Yes Prefer IPv6 (AAAA) DNS resolution

OpenID Connect SSO Settings

Variable Type Default Editable Description
SSO_ENABLED bool false Yes Enable SSO authentication
SSO_ONLY bool false Yes Disable password login (SSO only)
SSO_SIGNUPS_MATCH_EMAIL bool true Yes Match existing users by email on SSO login
SSO_ALLOW_UNKNOWN_EMAIL_VERIFICATION bool false Yes Allow SSO users with unknown email verification status
SSO_CLIENT_ID String (empty) Yes OIDC client ID
SSO_CLIENT_SECRET Password (empty) Yes OIDC client secret
SSO_AUTHORITY String (empty) Yes OIDC provider base URL
SSO_SCOPES String email profile Yes OIDC scopes (openid is implicit)
SSO_AUTHORIZE_EXTRA_PARAMS String (empty) Yes Extra URL parameters for the authorization request
SSO_PKCE bool true Yes Use PKCE in OIDC authorization flow
SSO_AUDIENCE_TRUSTED String (unset) Yes Regex for additional trusted ID token audiences
SSO_MASTER_PASSWORD_POLICY String (unset) Yes JSON policy object for SSO master password requirements
SSO_AUTH_ONLY_NOT_SESSION bool false Yes Use SSO only for auth, not session lifecycle
SSO_CLIENT_CACHE_EXPIRATION u64 0 Yes Discovery endpoint cache duration (seconds, 0 = disabled)
SSO_DEBUG_TOKENS bool false Yes Log SSO tokens (requires debug log level)

Warning

SSO_CLIENT_ID, SSO_CLIENT_SECRET, and SSO_AUTHORITY must all be set when SSO_ENABLED=true. The authority URL must not include /.well-known/openid-configuration.

YubiKey Settings

Variable Type Default Editable Description
YUBICO_CLIENT_ID String (unset) Yes YubiCloud API client ID
YUBICO_SECRET_KEY Password (unset) Yes YubiCloud API secret key
YUBICO_SERVER String (unset) Yes Custom YubiKey validation server URL (must be HTTPS)

Both YUBICO_CLIENT_ID and YUBICO_SECRET_KEY must be set together for custom YubiKey OTP support. Without them, the default YubiCloud service is used.

Duo Settings

Variable Type Default Editable Description
DUO_IKEY String (unset) Yes Duo client/integration key
DUO_SKEY Password (unset) Yes Duo secret key
DUO_HOST String (unset) Yes Duo API hostname
DUO_USE_IFRAME bool false No Use deprecated iframe-based Duo prompt (WebSDK 2)

All three Duo settings (DUO_IKEY, DUO_SKEY, DUO_HOST) must be set together for global Duo support. Individual users can also configure their own Duo credentials.

SMTP Email Settings

Variable Type Default Editable Description
USE_SENDMAIL bool false Yes Use sendmail command instead of SMTP
SENDMAIL_COMMAND String (auto-detect) No Path to sendmail binary
SMTP_HOST String (unset) Yes SMTP server hostname
SMTP_SECURITY String starttls Yes starttls, force_tls, or off
SMTP_PORT u16 (auto) Yes SMTP port (auto: 587/465/25 based on security)
SMTP_FROM String (empty) Yes Sender email address
SMTP_FROM_NAME String Vaultwarden Yes Sender display name
SMTP_USERNAME String (unset) Yes SMTP authentication username
SMTP_PASSWORD Password (unset) Yes SMTP authentication password
SMTP_AUTH_MECHANISM String (auto) Yes Auth methods: Plain, Login, Xoauth2 (comma-separated)
SMTP_TIMEOUT u64 15 Yes Connection timeout (seconds)
HELO_NAME String (hostname) Yes Server name sent during SMTP HELO
SMTP_EMBED_IMAGES bool true Yes Embed images in emails as attachments
SMTP_DEBUG bool false No Enable detailed SMTP logging (exposes sensitive data)
SMTP_ACCEPT_INVALID_CERTS bool false Yes Accept invalid TLS certificates (insecure)
SMTP_ACCEPT_INVALID_HOSTNAMES bool false Yes Accept invalid TLS hostnames (insecure)

Caution

SMTP_DEBUG=true outputs full SMTP session data including credentials. Only use during active troubleshooting and disable immediately after.

Email 2FA Settings

Variable Type Default Editable Description
EMAIL_TOKEN_SIZE u8 6 Yes Number of digits in email 2FA token (min: 6, max: 255)
EMAIL_EXPIRATION_TIME u64 600 Yes Token validity duration (seconds)
EMAIL_ATTEMPTS_LIMIT u64 3 Yes Max attempts before token is reset
EMAIL_2FA_ENFORCE_ON_VERIFIED_INVITE bool false Yes Auto-setup email 2FA on registration
EMAIL_2FA_AUTO_FALLBACK bool false Yes Auto-enable email 2FA as fallback when needed

Email 2FA requires a working mail transport (SMTP_HOST or USE_SENDMAIL). It is automatically enabled when SMTP is configured and a mail transport is available.

Other Environment Variables

Variable Description
ENV_FILE Path to .env file (default: .env)
CONFIG_FILE Path to config.json (default: {DATA_FOLDER}/config.json)
ROCKET_PORT Listening port (default: 80)
ROCKET_ADDRESS Bind address (default: 0.0.0.0)
ROCKET_TLS Rocket TLS configuration (use reverse proxy instead)
I_REALLY_WANT_VOLATILE_STORAGE Skip persistent volume check in containers
UMASK Set umask before starting (Docker start.sh)

4. Deployment & Scaling

Docker Deployment

Official images are built for four architectures from both Debian (trixie-slim) and Alpine (3.23) base images.

Production Docker Compose:

services:
  vaultwarden:
    image: vaultwarden/server:latest
    container_name: vaultwarden
    restart: unless-stopped
    environment:
      DOMAIN: "https://vw.example.com"
      SIGNUPS_ALLOWED: "false"
      ADMIN_TOKEN: "${ADMIN_TOKEN}"
      SMTP_HOST: "smtp.example.com"
      SMTP_FROM: "[email removed]"
      SMTP_PORT: "587"
      SMTP_SECURITY: "starttls"
      SMTP_USERNAME: "${SMTP_USER}"
      SMTP_PASSWORD: "${SMTP_PASS}"
      PUSH_ENABLED: "true"
      PUSH_INSTALLATION_ID: "${PUSH_ID}"
      PUSH_INSTALLATION_KEY: "${PUSH_KEY}"
    volumes:
      - ./vw-data/:/data/
    ports:
      - "127.0.0.1:8080:80"

Tip

Bind to 127.0.0.1 when running behind a reverse proxy to prevent direct external access to the unencrypted port.

S3 Storage

Set DATA_FOLDER to an S3 URL to store all data (database, attachments, sends, keys) in S3-compatible storage:

DATA_FOLDER=s3://my-vaultwarden-bucket/data

The s3 feature flag must be enabled (included in official Docker images). Vaultwarden uses the standard AWS credential chain via the official AWS SDK for credential resolution, supporting IAM roles, environment variables, SSO profiles, and credential files.

Reverse Proxy Configuration

Vaultwarden requires a reverse proxy for production HTTPS. Key considerations:

  • Pass the X-Real-IP header (or set IP_HEADER to your proxy's header name)
  • Forward WebSocket connections for real-time notifications
  • The /alive endpoint is suitable for health checks

Healthcheck (used in Docker):

curl --insecure --fail --silent --show-error \
  "http://localhost:${ROCKET_PORT}/alive"

Source Build for Production

cargo build --release --features "sqlite,enable_mimalloc"

Available feature flags:

Flag Purpose
sqlite SQLite database backend
postgresql PostgreSQL database backend
mysql MySQL/MariaDB database backend
s3 S3-compatible object storage
enable_mimalloc Use mimalloc allocator for better performance
vendored_openssl Statically link OpenSSL

5. Operations

Background Jobs

Vaultwarden runs 9 scheduled background jobs in a dedicated scheduler thread:

Job Default Schedule Purpose
Send purge Hourly (:05) Delete expired Sends
Trash purge Daily (00:05) Delete trashed items past retention
Incomplete 2FA check Every minute (:30) Notify on incomplete 2FA logins
Emergency request timeout Hourly (:07) Auto-grant emergency access requests
Emergency reminder Hourly (:03) Remind grantors of pending requests
Auth request purge Every minute (:30) Clean expired auth requests
Duo context purge Every minute (:30) Clean expired Duo auth contexts
Event cleanup Daily (00:10) Remove events older than retention period
SSO auth purge Daily (00:20) Clean incomplete SSO auth records

Tip

All schedules use 6-field cron syntax (second minute hour day month weekday). Set any schedule to an empty string to disable that specific job. Set JOB_POLL_INTERVAL_MS=0 to disable all jobs.

Backup

SQLite backup methods:

  1. CLI command: ./vaultwarden backup — creates db_YYYYMMDD_HHMMSS.sqlite3 in the data folder
  2. Signal (Unix): kill -USR1 $(pidof vaultwarden) — triggers hot backup while running
  3. File copy: Stop the server, copy db.sqlite3 and related WAL/SHM files

Note

The backup command and USR1 signal are SQLite-only. PostgreSQL and MySQL require native database backup tools (pg_dump, mysqldump).

Critical files to back up:

Path Contents
{DATA_FOLDER}/db.sqlite3 SQLite database (if using SQLite)
{DATA_FOLDER}/attachments/ Vault item file attachments
{DATA_FOLDER}/sends/ Bitwarden Send files
{DATA_FOLDER}/rsa_key.pem RSA private key for JWT signing
{DATA_FOLDER}/config.json Admin panel configuration overrides

Monitoring

  • Health endpoint: GET /alive — returns 200 when the server is running
  • Log levels: Configure via LOG_LEVEL with per-module overrides
# Enable query logging (slow queries only)
LOG_LEVEL=info,vaultwarden::db::query_logger=warn

# Full query logging
LOG_LEVEL=info,vaultwarden::db::query_logger=debug

Tip

Query logger levels: warn = queries over 5 seconds, info = queries over 1 second, debug = all queries.

Signal Handling

Signal Platform Action
SIGINT Unix Graceful shutdown
SIGTERM Unix Graceful shutdown
SIGQUIT Unix Graceful shutdown
SIGUSR1 Unix (SQLite only) Trigger SQLite backup
SIGHUP Unix Reopen log file (for log rotation)
Ctrl-C Windows Graceful shutdown

6. Performance

Database Tuning

Variable Default Guidance
DATABASE_MAX_CONNS 10 Increase for high-concurrency deployments (max: 256)
DATABASE_MIN_CONNS 2 Set to match minimum expected concurrency
DATABASE_TIMEOUT 30 Connection acquisition timeout (seconds)
DATABASE_IDLE_TIMEOUT 600 Close idle connections after this many seconds
DATABASE_CONN_INIT (empty) SQL to run on each new connection (e.g., PRAGMA statements for SQLite)
ENABLE_DB_WAL true SQLite WAL mode (better concurrent read performance)

Memory Optimization

  • Enable mimalloc via the enable_mimalloc feature flag for improved memory allocation performance
  • The Rocket request limits are fixed: 20 MB for JSON, 525 MB for data-form and file uploads (matches Bitwarden Send max file size)

Icon Caching

Variable Effect
ICON_SERVICE=internal Vaultwarden fetches and caches icons locally (default)
ICON_SERVICE=bitwarden Redirect to Bitwarden's icon service
ICON_SERVICE=duckduckgo Redirect to DuckDuckGo's icon service
ICON_SERVICE=google Redirect to Google's favicon service
DISABLE_ICON_DOWNLOAD=true Serve cached icons only, no new downloads

7. Security

Authentication Architecture

Vaultwarden uses RS256 JWT tokens signed with an auto-generated RSA-2048 key pair stored at {DATA_FOLDER}/rsa_key.pem. If the key file doesn't exist, it is generated automatically on first startup.

Token types and lifetimes:

Token Lifetime Purpose
Access token 2 hours API authentication
Refresh token (desktop/web) 30 days Token renewal
Refresh token (mobile) 90 days Token renewal (mobile devices)
Invite token INVITATION_EXPIRATION_HOURS (120h) Organization invitations
File download token 5 minutes Temporary file access
Register verify token 30 minutes Email verification during registration
2FA remember token 30 days Skip 2FA on remembered devices
Admin session ADMIN_SESSION_LIFETIME (20 min) Admin panel access
Send access token 2 minutes Send file download

Warning

The RSA private key (rsa_key.pem) is the root of trust for all authentication. If this file is compromised, all tokens can be forged. Protect it with restrictive file permissions and include it in backup procedures.

Rate Limiting

Endpoint Seconds Between Requests Burst Size
Login / 2FA LOGIN_RATELIMIT_SECONDS (60) LOGIN_RATELIMIT_MAX_BURST (10)
Admin panel ADMIN_RATELIMIT_SECONDS (300) ADMIN_RATELIMIT_MAX_BURST (3)

Admin Panel Security

The admin token supports two formats:

  1. Argon2id PHC string (recommended): Generated via vaultwarden hash
  2. Plain text (insecure): Generates a startup warning recommending migration to Argon2id

Set DISABLE_ADMIN_TOKEN=true only when the admin panel is protected by an external authentication layer (e.g., reverse proxy auth).

Network Security

Setting Default Purpose
HTTP_REQUEST_BLOCK_NON_GLOBAL_IPS true Prevent SSRF by blocking requests to private/reserved IPs
HTTP_REQUEST_BLOCK_REGEX (unset) Regex to block specific domains/IPs from internal HTTP requests
IP_HEADER X-Real-IP Client IP detection header (set to none to use remote IP)

Caution

Disabling HTTP_REQUEST_BLOCK_NON_GLOBAL_IPS may expose internal network services to SSRF attacks through the icon fetching functionality.

Password Security

  • Server-side hashing uses PBKDF2-SHA256 with PASSWORD_ITERATIONS (default: 600,000, minimum: 100,000)
  • The iteration count is updated on login if the configured value changes
  • SHOW_PASSWORD_HINT=true exposes password hints without authentication — not recommended for public instances

Two-Factor Authentication Security

  • DISABLE_2FA_REMEMBER=true forces 2FA on every login
  • AUTHENTICATOR_DISABLE_TIME_DRIFT=true accepts only the current 30-second TOTP window
  • Incomplete 2FA attempts (correct password, missing 2FA) trigger email notifications after INCOMPLETE_2FA_TIME_LIMIT minutes
  • WebAuthn requires DOMAIN to be set with an HTTPS scheme and a valid domain name

SSO Security Considerations

  • SSO_ALLOW_UNKNOWN_EMAIL_VERIFICATION=true with SSO_SIGNUPS_MATCH_EMAIL=true creates an account takeover risk — only use with trusted identity providers
  • SSO_PKCE=true (default) adds PKCE protection to the OIDC authorization flow
  • SSO_AUDIENCE_TRUSTED accepts a regex — validate that it cannot match unintended audiences

8. Developer Internals

Repository Structure

vaultwarden/
├── src/
│   ├── main.rs                 Entry point, CLI, startup sequence
│   ├── config.rs               make_config! macro, env var processing
│   ├── auth.rs                 JWT authentication, request guards
│   ├── crypto.rs               PBKDF2, HMAC, random generation
│   ├── error.rs                Error types, API error formatting
│   ├── mail.rs                 Email sending (SMTP/sendmail)
│   ├── http_client.rs          Outbound HTTP with IP blocking
│   ├── ratelimit.rs            Rate limiting implementation
│   ├── sso.rs                  SSO/OIDC flow logic
│   ├── sso_client.rs           OIDC client configuration
│   ├── util.rs                 Shared utilities
│   ├── api/
│   │   ├── mod.rs              Route registration
│   │   ├── admin.rs            Admin panel routes
│   │   ├── icons.rs            Favicon proxy/cache
│   │   ├── notifications.rs    WebSocket hub
│   │   ├── web.rs              Static file serving
│   │   ├── identity/           Login, token, SSO endpoints
│   │   └── core/
│   │       ├── accounts.rs     User account management
│   │       ├── ciphers.rs      Vault item CRUD
│   │       ├── collections.rs  Collection management
│   │       ├── folders.rs      Folder management
│   │       ├── organizations.rs Organization management
│   │       ├── sends.rs        Bitwarden Send
│   │       ├── emergency_access.rs Emergency access
│   │       ├── events.rs       Event logging
│   │       └── two_factor/     2FA implementations
│   │           ├── authenticator.rs  TOTP
│   │           ├── webauthn.rs       WebAuthn/FIDO2
│   │           ├── duo.rs / duo_oidc.rs  Duo Security
│   │           ├── yubikey.rs        YubiKey OTP
│   │           └── email.rs          Email 2FA
│   └── db/
│       ├── mod.rs              Database pool, migrations
│       ├── schemas/            Diesel table schemas
│       └── models/             Entity models (User, Cipher, etc.)
├── migrations/                 Database migration files per backend
├── macros/                     Procedural macros (db_* derives)
├── docker/                     Docker build infrastructure
├── playwright/                 End-to-end browser tests
└── Cargo.toml                  Dependencies and feature flags

Configuration System Deep Dive

The make_config! macro in src/config.rs is the central configuration mechanism. It generates:

  1. ConfigBuilder — a struct where all fields are Option<T>, populated from environment variables and config.json
  2. ConfigItems — the resolved configuration with concrete types and defaults applied
  3. Config — the thread-safe wrapper (RwLock<Inner>) exposed as a global CONFIG static
  4. Admin panel data — prepare_json() serializes all settings for the web admin UI
  5. Support diagnostics — get_support_json() masks sensitive values for diagnostic output

The config loading order is:

  1. .env file (via dotenvy)
  2. Environment variables → ConfigBuilder::from_env()
  3. config.json → ConfigBuilder::from_file()
  4. Merge: env ← config.json (config.json overrides env for editable settings)
  5. Build: apply defaults, auto-computed values, and generated values
  6. Validate: validate_config() checks constraints

Request Guard System

Rocket request guards enforce authentication and authorization at the type level:

Guard Access Level
Headers Authenticated user with valid JWT
OrgHeaders Authenticated user who is a member of the requested organization
OrgMemberHeaders Non-revoked organization member
ManagerHeaders Confirmed manager with collection access
ManagerHeadersLoose Confirmed manager (no collection check)
AdminHeaders Confirmed admin or owner
OwnerHeaders Confirmed owner only
ClientHeaders Client IP + device type (no auth required)
ClientIp Extracted client IP (honors IP_HEADER)

API Surface

Vaultwarden implements 268 API endpoints across these mount points:

Mount Prefix Purpose
Web / Static files, web vault
Core API /api Vault operations (ciphers, folders, collections, orgs)
Admin /admin Admin panel
Events /events Event logging API
Identity /identity Authentication, token exchange
Icons /icons Favicon proxy
Notifications /notifications WebSocket hub

Database Migrations

Diesel migrations are organized per backend in the migrations/ directory. Migrations run automatically on startup. The application also performs data migrations in code:

  • TwoFactor::migrate_u2f_to_webauthn() — migrates legacy U2F registrations to WebAuthn
  • TwoFactor::migrate_credential_to_passkey() — migrates credentials to passkey format

Testing

End-to-end tests use Playwright in playwright/ and cover:

  • SSO login flows
  • 2FA setup and verification (TOTP, Email)
  • Organization management
  • Collection creation and assignment

Code Patterns

  • Error handling: Custom make_error! macro generates a unified Error type wrapping 20+ source error types with err!() / err_handler!() macros for ergonomic error creation
  • Lazy statics: LazyLock for global configuration, JWT keys, compiled regexes
  • Atomic operations: OnceLock for RSA keys (initialized once, then immutable)
  • Template rendering: Handlebars with custom helpers (case, to_json, webver, vwver)
  • Feature flags: Compile-time (cfg(sqlite), cfg(s3)) and runtime (SUPPORTED_FEATURE_FLAGS for client-side flags)

9. Integration Points

Bitwarden Client Compatibility

Vaultwarden implements the Bitwarden API surface to be compatible with all official clients. The web vault version (v2026.2.0) is bundled and served by the server. Client version detection uses the Bitwarden-Client-Version header.

Push Notification Relay

Push notifications require registration with the Bitwarden push relay service:

  1. Register at https://bitwarden.com/host to get installation ID and key
  2. Set PUSH_ENABLED=true, PUSH_INSTALLATION_ID, and PUSH_INSTALLATION_KEY
  3. Notifications are relayed through PUSH_RELAY_URI (default: https://push.bitwarden.com)

OIDC Identity Providers

Vaultwarden supports any OpenID Connect compliant provider. The callback URL is {DOMAIN}/identity/connect/oidc-signin.

Email Integration

28 email templates (HTML + plain text) are built in, covering all user lifecycle events. Templates use Handlebars and can be overridden by placing .hbs files in the templates folder.

HaveIBeenPwned

Set HIBP_API_KEY to enable password breach checking through the HaveIBeenPwned API.

Container Startup Hooks

Docker containers source shell scripts before starting:

  1. /etc/vaultwarden.sh — single initialization script
  2. /etc/vaultwarden.d/*.sh — directory of initialization scripts

Legacy paths (/etc/bitwarden_rs.sh, /etc/bitwarden_rs.d/) are supported with deprecation warnings.