# Vaultwarden — User Guide

## 1. Quick Start

Vaultwarden is an unofficial Bitwarden-compatible server written in Rust, providing a lightweight, self-hosted password management solution. It implements the Bitwarden client API, allowing you to use official Bitwarden apps and browser extensions with your own server.

**Key features:**

- Full vault management — passwords, notes, cards, identities with folder organization
- Organizations and collections for shared credential management
- Five two-factor authentication methods — TOTP, WebAuthn/FIDO2, Duo, YubiKey OTP, Email
- Bitwarden Send for secure temporary file and text sharing
- Emergency access — grant trusted contacts access to your vault
- SSO/OpenID Connect authentication support
- Built-in admin panel for server management
- Push notifications for real-time sync across devices
- S3-compatible object storage support

**Prerequisites:**

- Docker installed on your host system
- A persistent storage directory for vault data

**Quickest start — Docker:**

```bash
docker run -d --name vaultwarden \
  -v /vw-data/:/data/ \
  -p 80:80 \
  vaultwarden/server:latest
```

```text
Unable to find image 'vaultwarden/server:latest' locally
latest: Pulling from vaultwarden/server
...
Status: Downloaded newer image for vaultwarden/server:latest
```

Open `http://localhost` in your browser, create an account, and start adding passwords.

> [!TIP]
> For production use, set `DOMAIN=https://your.domain.com` and place a reverse proxy (Traefik, Caddy, nginx) in front of Vaultwarden to handle HTTPS.

**What to try next:**

- Set up HTTPS with a reverse proxy (see Installation)
- Enable push notifications for real-time sync
- Configure SMTP for email features
- Enable two-factor authentication on your account

---

## 2. Installation

### System Requirements

| Requirement | Minimum | Recommended |
|---|---|---|
| Architecture | amd64, arm64, armv7, armv6 | amd64 or arm64 |
| RAM | 64 MB | 256 MB+ |
| Disk | 100 MB + vault data | 1 GB+ |
| Database | SQLite (default) | PostgreSQL or MySQL for multi-user |
| Rust (source build) | 1.92.0+ | 1.94.1+ |
| Web Vault | v2026.2.0 | Latest matching release |

### Docker Installation (Recommended)

Vaultwarden provides multi-architecture Docker images in both Debian and Alpine variants.

**Debian-based (default):**

```bash
docker run -d --name vaultwarden \
  -v /vw-data/:/data/ \
  -p 80:80 \
  -e DOMAIN=https://vw.example.com \
  vaultwarden/server:latest
```

**Alpine-based (smaller image):**

```bash
docker run -d --name vaultwarden \
  -v /vw-data/:/data/ \
  -p 80:80 \
  -e DOMAIN=https://vw.example.com \
  vaultwarden/server:latest-alpine
```

> [!IMPORTANT]
> You **must** mount a persistent volume to `/data/`. Without it, Vaultwarden detects volatile storage and refuses to start. If you intentionally want volatile storage (e.g., for testing), set `I_REALLY_WANT_VOLATILE_STORAGE=true`.

**Docker Compose:**

```yaml
services:
  vaultwarden:
    image: vaultwarden/server:latest
    container_name: vaultwarden
    restart: unless-stopped
    environment:
      DOMAIN: "https://vw.example.com"
    volumes:
      - ./vw-data/:/data/
    ports:
      - 80:80
```

### Source Build

```bash
# Clone the repository
git clone https://github.com/dani-garcia/vaultwarden.git
cd vaultwarden

# Build with SQLite support (default)
cargo build --release --features sqlite

# Build with PostgreSQL support
cargo build --release --features postgresql

# Build with MySQL/MariaDB support
cargo build --release --features mysql
```

> [!WARNING]
> You must also download and extract the Bitwarden web vault into a `web-vault/` directory next to the binary, or set `WEB_VAULT_FOLDER` to its location. Without it, the web interface will not load. See the project wiki for web vault installation instructions.

### Database Backend Selection

| Backend | Feature Flag | `DATABASE_URL` Format |
|---|---|---|
| SQLite | `sqlite` | `data/db.sqlite3` (default) |
| PostgreSQL | `postgresql` | `postgresql://user:pass@host/dbname` |
| MySQL/MariaDB | `mysql` | `mysql://user:pass@host/dbname` |

SQLite is the default and requires no additional setup. For PostgreSQL or MySQL, set the `DATABASE_URL` environment variable to your connection string.

### Post-Install Verification

```bash
curl http://localhost/alive
```

```text
(empty 200 OK response)
```

The `/alive` endpoint confirms the server is running. Open `http://localhost` in a browser to access the web vault.

### Startup Customization

Vaultwarden sources shell scripts at startup before launching the server:

- `/etc/vaultwarden.sh` — single initialization script
- `/etc/vaultwarden.d/*.sh` — directory of initialization scripts (sourced in order)

Use these to set environment variables or perform pre-launch tasks inside Docker containers.

---

## 3. Configuration

Vaultwarden is configured entirely through environment variables. There is no configuration file to edit manually — set variables via your Docker run command, `docker-compose.yml`, or a `.env` file.

### Essential Settings

| Variable | Default | Description |
|---|---|---|
| `DOMAIN` | `http://localhost` | Full URL used to access the server, including protocol and port if non-standard |
| `DATABASE_URL` | `data/db.sqlite3` | Database connection string |
| `DATA_FOLDER` | `data` | Path to the main data directory |
| `ADMIN_TOKEN` | *(unset)* | Argon2id PHC string or plain text token for the admin panel |
| `SIGNUPS_ALLOWED` | `true` | Whether new users can self-register |
| `INVITATIONS_ALLOWED` | `true` | Whether organization admins can invite users |
| `WEB_VAULT_ENABLED` | `true` | Enable the web vault interface |

> [!IMPORTANT]
> The `DOMAIN` variable must include the protocol (`https://`) and must be set correctly for many features to work, including WebAuthn 2FA, email links, and push notifications.

### Generating a Secure Admin Token

Use the built-in `hash` command to generate an Argon2id PHC string:

```bash
# Inside Docker
docker exec -it vaultwarden /vaultwarden hash

# From source build
./vaultwarden hash
```

```text
Generate an Argon2id PHC string using the 'bitwarden' preset:

Password:
Confirm Password:

ADMIN_TOKEN='$argon2id$v=19$m=65540,t=3,p=4$...'
```

Two presets are available:

| Preset | Memory | Iterations | Threads |
|---|---|---|---|
| `bitwarden` (default) | 64 MiB | 3 | 4 |
| `owasp` | 19 MiB | 2 | 1 |

```bash
./vaultwarden hash --preset owasp
```

### Email / SMTP Configuration

To enable email features (invitations, email 2FA, password hints, new device notifications), configure SMTP:

| Variable | Default | Description |
|---|---|---|
| `SMTP_HOST` | *(unset)* | SMTP server hostname |
| `SMTP_FROM` | *(empty)* | Sender email address |
| `SMTP_PORT` | Auto | Port (587 for STARTTLS, 465 for TLS, 25 for plain) |
| `SMTP_SECURITY` | `starttls` | `starttls`, `force_tls`, or `off` |
| `SMTP_USERNAME` | *(unset)* | SMTP authentication username |
| `SMTP_PASSWORD` | *(unset)* | SMTP authentication password |
| `SMTP_FROM_NAME` | `Vaultwarden` | Display name on sent emails |

> [!TIP]
> Alternatively, set `USE_SENDMAIL=true` to use the local `sendmail` command instead of an SMTP server.

### Push Notifications

For real-time sync across devices, enable push notifications:

| Variable | Default | Description |
|---|---|---|
| `PUSH_ENABLED` | `false` | Enable push notifications |
| `PUSH_INSTALLATION_ID` | *(empty)* | Installation ID from `https://bitwarden.com/host` |
| `PUSH_INSTALLATION_KEY` | *(empty)* | Installation key from `https://bitwarden.com/host` |

All three settings must be configured together. Obtain your installation ID and key by registering at the Bitwarden host page.

For the complete configuration reference with all 100+ environment variables, see the Admin Guide.

---

## 4. Core Usage

### Connecting Clients

Vaultwarden works with all official Bitwarden clients. When logging in, set the server URL to your Vaultwarden instance domain before entering credentials.

**Supported clients:**

- Bitwarden browser extensions (Chrome, Firefox, Edge, Safari)
- Bitwarden desktop apps (Windows, macOS, Linux)
- Bitwarden mobile apps (iOS, Android)
- Bitwarden CLI

### Vault Management

Your vault stores four types of items:

| Type | Use For |
|---|---|
| Login | Website credentials, TOTP seeds, URIs |
| Secure Note | Encrypted text notes (up to 10,000 characters; 100,000 if `INCREASE_NOTE_SIZE_LIMIT=true`) |
| Card | Payment card details |
| Identity | Personal information (name, address, contact) |

Organize items into **folders** for personal categorization. Folders are per-user and do not affect sharing.

### Organizations and Collections

Organizations enable credential sharing between users.

**Membership roles:**

| Role | Can Manage Members | Can Create Collections | Can Access All Items |
|---|---|---|---|
| Owner | Yes | Yes | Yes |
| Admin | Yes | Yes | Yes |
| Manager | No | Assigned only | Assigned only |
| User | No | No | Assigned only |

**Collections** are the sharing mechanism within organizations. Assign items to collections, then grant members access to specific collections.

> [!NOTE]
> Organization groups are available as a beta feature. Enable with `ORG_GROUPS_ENABLED=true`. This feature currently has known issues.

> [!WARNING]
> The `ORG_CREATION_USERS` setting controls who can create organizations. Set it to a comma-separated list of emails, `all` (default), or `none`.

### File Attachments

Attach files to vault items for secure storage. Attachments are stored in the `attachments/` subdirectory of your data folder (or S3 if configured).

Storage limits can be configured per-user and per-organization:

| Variable | Description |
|---|---|
| `USER_ATTACHMENT_LIMIT` | Max KB per user (unset = unlimited) |
| `ORG_ATTACHMENT_LIMIT` | Max KB per organization (unset = unlimited) |

### Bitwarden Send

Send allows you to securely share text or files with anyone, even non-Vaultwarden users.

- **Text Sends** — share encrypted text with optional password protection
- **File Sends** — share encrypted files (max 525 MB per file)
- Set expiration dates, access counts, and deletion dates
- Optional password protection for recipients

| Variable | Default | Description |
|---|---|---|
| `SENDS_ALLOWED` | `true` | Enable/disable Sends globally |
| `USER_SEND_LIMIT` | *(unset)* | Max KB of Send storage per user |

> [!NOTE]
> Sends past their deletion date are automatically purged by a scheduled job (default: hourly). See `SEND_PURGE_SCHEDULE` in the Admin Guide.

### Two-Factor Authentication

Vaultwarden supports five 2FA methods, configured per-user through the web vault settings:

| Method | Requirements | Variables |
|---|---|---|
| TOTP (Authenticator) | Any TOTP app | *(none — always available)* |
| WebAuthn/FIDO2 | Hardware security key + HTTPS domain | `DOMAIN` must be set with HTTPS |
| Email | SMTP configured | `SMTP_HOST`, `SMTP_FROM` |
| Duo Security | Duo account | `DUO_IKEY`, `DUO_SKEY`, `DUO_HOST` |
| YubiKey OTP | YubiKey + API credentials | `YUBICO_CLIENT_ID`, `YUBICO_SECRET_KEY` |

> [!CAUTION]
> If you enable a 2FA method and lose access to your second factor, recovery requires the recovery code displayed when 2FA was first enabled. Store this code securely — there is no other way to recover access. Disabling `ADMIN_TOKEN` and using the admin panel to manually intervene is a last resort.

**Incomplete 2FA monitoring:** If a correct master password is entered but the 2FA step is not completed within `INCOMPLETE_2FA_TIME_LIMIT` minutes (default: 3), an email notification is sent to the user. This may indicate a compromised master password.

### Emergency Access

Grant trusted contacts the ability to view or take over your vault in an emergency.

1. Go to **Settings → Emergency Access** in the web vault
2. Invite a trusted contact by email
3. Set a **wait time** (days) — the period between a request and automatic approval
4. Choose access level: **View** (read-only) or **Takeover** (full control)

The trusted contact requests access; you are notified and can approve or deny. If you don't respond within the wait period, access is granted automatically.

| Variable | Default | Description |
|---|---|---|
| `EMERGENCY_ACCESS_ALLOWED` | `true` | Enable/disable emergency access globally |

### Admin Panel

Access the admin panel at `https://your.domain.com/admin`. Authentication requires the `ADMIN_TOKEN` configured at server startup.

From the admin panel you can:

- View and manage registered users
- Manage organizations
- Modify server configuration settings (editable settings only)
- View diagnostic information
- Invite users even when signups are disabled

### SSO / OpenID Connect

Vaultwarden supports SSO login via OpenID Connect, allowing users to authenticate through an identity provider (Keycloak, Authentik, Azure AD, etc.).

| Variable | Description |
|---|---|
| `SSO_ENABLED` | Enable SSO login |
| `SSO_ONLY` | Disable email+master password login entirely |
| `SSO_CLIENT_ID` | OIDC client ID |
| `SSO_CLIENT_SECRET` | OIDC client secret |
| `SSO_AUTHORITY` | OIDC provider base URL (without `/.well-known/openid-configuration`) |

> [!WARNING]
> Setting `SSO_ONLY=true` disables password-based login entirely. Ensure SSO is fully working before enabling this, or you may lock yourself out. The admin panel remains accessible via `ADMIN_TOKEN`.

---

## 5. Common Tasks

### Back Up Your Vault Data

**SQLite (CLI method):**

```bash
# Inside Docker
docker exec -it vaultwarden /vaultwarden backup

# On Unix, send USR1 signal for hot backup
kill -USR1 $(pidof vaultwarden)
```

```text
Backup to 'data/db_YYYYMMDD_HHMMSS.sqlite3' was successful
```

> [!CAUTION]
> The `backup` subcommand and USR1 signal only work with SQLite databases. PostgreSQL and MySQL users must use their database's native backup tools.

**What to back up:**

- `data/db.sqlite3` (or your external database)
- `data/attachments/` — file attachments
- `data/sends/` — Send files
- `data/rsa_key.pem` — RSA signing key
- `data/config.json` — admin panel settings (if modified via admin panel)

### Move from SQLite to PostgreSQL

1. Export data using the Bitwarden client export feature (per-user)
2. Set up a PostgreSQL database
3. Update `DATABASE_URL` to your PostgreSQL connection string
4. Start Vaultwarden — migrations run automatically
5. Have users import their exported data

### Set Up a Reverse Proxy

Vaultwarden expects to sit behind a reverse proxy for HTTPS. Configure your proxy to:

1. Terminate TLS
2. Forward to Vaultwarden on port 80 (default `ROCKET_PORT`)
3. Pass WebSocket connections through (needed for real-time sync)
4. Set `X-Real-IP` header (or configure `IP_HEADER` to match your proxy's header)

### Restrict User Registration

```bash
# Disable all self-registration
SIGNUPS_ALLOWED=false

# Allow only specific email domains
SIGNUPS_DOMAINS_WHITELIST=example.com,company.org

# Require email verification for new signups
SIGNUPS_VERIFY=true
```

The domain whitelist overrides `SIGNUPS_ALLOWED` — users from whitelisted domains can register even when signups are globally disabled.

### Enable Event Logging

For organization audit trails, enable event logging:

```bash
ORG_EVENTS_ENABLED=true
EVENTS_DAYS_RETAIN=90
```

Events older than `EVENTS_DAYS_RETAIN` days are cleaned up by a scheduled job.

### Customize Email Templates

Override default email templates by placing `.hbs` (Handlebars) files in the `data/templates/` directory. Vaultwarden loads user templates on top of built-in defaults, so you only need to provide the templates you want to customize.

---

## 6. Troubleshooting

### Error: "No persistent volume!"

**Cause:** Vaultwarden detected that `/data/` is not a persistent volume when running in a container. This means your data will be lost when the container is recreated.

**Solution:**

1. Add a volume mount: `-v /host/path/:/data/`
2. Or create a named Docker volume: `-v vw-data:/data/`

**Prevention:** Always mount a persistent volume in production.

### Error: "Web vault is not found"

**Cause:** The web vault files are not present at the expected location (`web-vault/` by default).

**Solution:**

1. Download the web vault from the Bitwarden repository
2. Extract to the `web-vault/` directory
3. Or set `WEB_VAULT_FOLDER` to the correct path
4. Or disable with `WEB_VAULT_ENABLED=false` if not needed

### Error: Database connection failures on startup

**Cause:** The database is not reachable when Vaultwarden starts.

**Solution:**

1. Verify `DATABASE_URL` is correct and the database server is running
2. Increase `DB_CONNECTION_RETRIES` (default: 15) if the database takes longer to start
3. Check network connectivity between Vaultwarden and the database

> [!NOTE]
> Vaultwarden retries the database connection up to `DB_CONNECTION_RETRIES` times with 1-second intervals. Set to `0` to retry indefinitely.

### Issue: `DATABASE_URL` silently falls back to SQLite

**Cause:** When the `DATABASE_URL` format is unrecognized or the required database feature is not compiled in, Vaultwarden may silently fall back to SQLite instead of reporting an error. (GitHub issue #7062)

**Solution:**

1. Verify the correct database feature flag was used at compile time (`sqlite`, `postgresql`, or `mysql`)
2. Double-check `DATABASE_URL` format matches your chosen backend
3. Check startup logs for database type confirmation

**Prevention:** Use official Docker images which include all three database backends.

### Issue: WebAuthn login fails on iOS

**Cause:** iOS has known compatibility issues with WebAuthn login in certain configurations. (GitHub issue #7107)

**Solution:**

1. Ensure `DOMAIN` is set to an HTTPS URL
2. Update to the latest Bitwarden iOS client
3. Try using a different 2FA method as fallback

### Issue: SSO login does not auto-register new users

**Cause:** SSO auto-registration may fail when `SIGNUPS_ALLOWED=false` and SSO email matching is not properly configured. (GitHub issue #7086)

**Solution:**

1. Ensure `SSO_SIGNUPS_MATCH_EMAIL=true` is set
2. Check that the SSO provider returns the user's email in the token
3. Verify the OIDC scopes include `email profile`

> [!WARNING]
> Setting `SSO_ALLOW_UNKNOWN_EMAIL_VERIFICATION=true` with `SSO_SIGNUPS_MATCH_EMAIL=true` creates a potential account takeover vector. Only enable if your identity provider guarantees email verification.

### Issue: 2FA recovery codes not working after organization changes

**Cause:** Recovery code handling has edge cases when organization policies interact with user 2FA settings. (GitHub issue #7096)

**Solution:**

1. Log in with the master password (not SSO)
2. Go to Settings → Two-step Login
3. View and save new recovery codes
4. If locked out, an admin can disable 2FA via the admin panel

### Error: `parse_date()` panic

**Cause:** A malformed date value in the database causes a parsing panic. (GitHub issue #7069)

**Solution:**

1. Check database entries for malformed date fields
2. Fix the invalid date values directly in the database
3. Restart Vaultwarden

---

## 7. FAQ

**Q: Which Bitwarden clients work with Vaultwarden?**

All official Bitwarden clients work with Vaultwarden — browser extensions, desktop apps, mobile apps, and the CLI. Set your server URL to your Vaultwarden instance domain before logging in.

**Q: Is Vaultwarden compatible with the latest Bitwarden features?**

Vaultwarden tracks the Bitwarden API and web vault releases. The current web vault version is v2026.2.0. Some newer Bitwarden features may take time to be implemented.

**Q: Can I migrate from the official Bitwarden server to Vaultwarden?**

Yes. Export your vault data from the official Bitwarden server and import it into Vaultwarden. Organization data requires per-organization export/import.

**Q: Does Vaultwarden support multiple databases simultaneously?**

No. Each Vaultwarden instance connects to exactly one database. You can choose between SQLite, PostgreSQL, or MySQL/MariaDB at build time (or use the official Docker images which support all three).

**Q: How do I update Vaultwarden?**

For Docker: pull the latest image and recreate the container. Your data is preserved in the mounted volume.

```bash
docker pull vaultwarden/server:latest
docker stop vaultwarden
docker rm vaultwarden
docker run -d --name vaultwarden -v /vw-data/:/data/ -p 80:80 vaultwarden/server:latest
```

**Q: Can I disable the admin panel entirely?**

Yes. Simply don't set `ADMIN_TOKEN` — the admin panel will not be accessible. If you want the admin panel accessible without a token (e.g., behind your own auth proxy), set `DISABLE_ADMIN_TOKEN=true`.

**Q: What happens when a Send expires?**

Expired Sends are automatically purged by a background job running on the `SEND_PURGE_SCHEDULE` (default: hourly at minute 5). The data is permanently deleted.

**Q: Can I use S3-compatible storage instead of local disk?**

Yes. Set `DATA_FOLDER` to an S3 URL (e.g., `s3://bucket-name/path`). Vaultwarden uses OpenDAL for S3 access with AWS credential chain support. The `s3` feature flag must be enabled at build time (included in official Docker images).

**Q: How do I configure logging?**

Set `LOG_LEVEL` to `trace`, `debug`, `info`, `warn`, `error`, or `off`. For per-module control, use comma-separated overrides:

```bash
LOG_LEVEL=info,vaultwarden::api::icons=debug
```

Set `LOG_FILE` to a path to write logs to a file. On Unix, send SIGHUP to reopen the log file for log rotation.

**Q: Does Vaultwarden support password hints?**

Yes, controlled by `PASSWORD_HINTS_ALLOWED` (default: `true`). If SMTP is not configured, you can show hints directly on the login page with `SHOW_PASSWORD_HINT=true`, but this exposes hints without authentication and is not recommended for public instances.

---

_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. Unofficial; not affiliated with or reviewed by the project._
