bitwarden
Install and configure Bitwarden CLI tools on Ubuntu/Debian systems.
Description
Section titled “Description”This role automates the installation and configuration of:
- Bitwarden CLI (bw) - Official Bitwarden command-line interface for vault management
- Bitwarden Secrets CLI (bws) - Specialized CLI for secrets management
- Bitwarden Configuration - Server URL and API endpoint configuration
Features
Section titled “Features”- Downloads official binaries directly from GitHub releases
- Supports version pinning with override capability
- Automatic architecture detection (x86_64/amd64, aarch64/arm64)
- Idempotent installation (skips if already installed)
- Configurable Bitwarden server URL (supports self-hosted instances)
- Custom API endpoint configuration
- Comprehensive verification and status reporting
Requirements
Section titled “Requirements”- Ubuntu/Debian-based system
- Internet connection for downloading binaries
- Root/sudo privileges for system-wide installation
Role Variables
Section titled “Role Variables”Installation Control
Section titled “Installation Control”| Variable | Default | Description |
|---|---|---|
bitwarden_install_bw | true | Install Bitwarden CLI (bw) |
bitwarden_install_bws | true | Install Bitwarden Secrets CLI (bws) |
bitwarden_configure | true | Configure Bitwarden settings |
bitwarden_install_path | /usr/local/bin | Installation directory for binaries |
Version Management
Section titled “Version Management”| Variable | Default | Description |
|---|---|---|
bitwarden_bw_version | 2026.7.0 | Bitwarden CLI version (bump to upgrade) |
bitwarden_bws_version | 2.1.0 | Bitwarden Secrets CLI version (bump to upgrade) |
Server Configuration (bw CLI)
Section titled “Server Configuration (bw CLI)”| Variable | Default | Description |
|---|---|---|
bitwarden_server_url | https://vault.bitwarden.eu | Bitwarden server URL |
Server Configuration (bws CLI)
Section titled “Server Configuration (bws CLI)”| Variable | Default | Description |
|---|---|---|
bitwarden_bws_server_api | https://api.bitwarden.eu | API server URL for bws config |
bitwarden_bws_server_identity | https://identity.bitwarden.eu | Identity server URL for bws config |
bitwarden_bws_config_path | ~/.config/bws | Directory for bws config file |
Note: The bws CLI uses a TOML configuration file at ~/.config/bws/config. This role defaults to the European endpoints; for the US region set bitwarden_bws_server_api: 'https://api.bitwarden.com' and bitwarden_bws_server_identity: 'https://identity.bitwarden.com'.
Host Token Distribution
Section titled “Host Token Distribution”Installs a dedicated BWS machine-account token on the host so bws works with no
per-user setup, for root and for members of the bws group.
These tasks live in tasks/distribute_token.yml and are not part of the
role’s default flow — main.yml does not include them, so setup_new_machine.yml
installs the CLIs without touching the token. Distribution has its own playbook,
so rotating the token never requires a full provisioning run.
| Variable | Default | Description |
|---|---|---|
bitwarden_bws_token_env_var | BWS_HOST_ACCESS_TOKEN | Controller env var holding the token |
bitwarden_bws_token_required | false | Fail instead of skip when the env var is unset |
bitwarden_bws_token_file | /etc/bws/token | On-host token path (root:bws, 0640) |
bitwarden_bws_token_group | bws | Group granted read access to the token |
bitwarden_bws_token_users | ['{{ ansible_user_id }}'] | Accounts added to the bws group |
bitwarden_bws_system_config_file | /etc/bws/config | System-wide bws config (exported as BWS_CONFIG_FILE) |
bitwarden_bws_write_root_config | true | Also write /root/.config/bws/config |
bitwarden_bws_write_user_config | true | Write the per-user ~/.config/bws/config |
Set the token on the controller before running:
BWS_HOST_ACCESS_TOKEN=0.<uuid>.<key>Use a separate, read-only machine account scoped to only the projects the
hosts need. Do not reuse BWS_ACCESS_TOKEN — that token stays on the controller
for restart-docker-stacks.yml, and reusing it would place a broad credential on
every container.
Then run the dedicated playbook:
# Whole fleetansible-playbook -i inventory/proxmox.proxmox.yml playbooks/distribute-bws-token.yml
# One host (recommended for the first run)ansible-playbook -i inventory/proxmox.proxmox.yml playbooks/distribute-bws-token.yml --limit arcaneThat playbook sets bitwarden_bws_token_required: true, so a missing env var is
an error rather than a silent skip. The role default is false: if you include
distribute_token.yml from somewhere else and the token is absent, the group,
config and shell snippets still converge and any existing token file is left
untouched.
What lands on the host
Section titled “What lands on the host”| Path | Owner:Group | Mode | Contents |
|---|---|---|---|
/etc/bws/token | root:bws | 0640 | The access token |
/etc/bws/config | root:root | 0644 | TOML with the region endpoints |
/etc/profile.d/bws.sh | root:root | 0644 | Exports both, if readable |
/etc/fish/conf.d/bws.fish | root:root | 0644 | Same, written only where fish exists |
/root/.config/bws/config | root:root | 0644 | Region endpoints for root |
Limitations
Section titled “Limitations”- Group changes need a re-login. An account newly added to
bwsmust log out and back in (or runnewgrp bws) before$BWS_ACCESS_TOKENappears. Existing SSH sessions keep their old group set. - Only login shells get the export.
/etc/profile.dis not read byssh host '<cmd>', cron, systemd units, or Ansible’s ownshell/commandtasks. Usebash -lc '...', or read/etc/bws/tokendirectly. Fish is unaffected —conf.dis sourced by every fish shell. sudostrips the variable (env_resetis the default). Usesudo -i, orsudo BWS_ACCESS_TOKEN="$(cat /etc/bws/token)" bws .... Do not add anenv_keepsudoers rule — that widens exposure to everysudocall.- Do not put the token in
/etc/environment. It is world-readable and read bypam_envfor every session, which would defeat the0640design. - Rotation rewrites the file on the next run, but open sessions keep the old value until re-login, and the old token must be revoked in the web vault separately — the playbook cannot do that.
Advanced Configuration
Section titled “Advanced Configuration”| Variable | Default | Description |
|---|---|---|
bitwarden_bw_github_repo | bitwarden/clients | GitHub repository for bw CLI |
bitwarden_bws_github_repo | bitwarden/sdk-sm | GitHub repository for bws CLI |
bitwarden_temp_dir | /tmp/bitwarden-install | Temporary download directory |
See defaults/main.yml for all available variables.
Dependencies
Section titled “Dependencies”None.
Example Playbook
Section titled “Example Playbook”Basic Installation (Default)
Section titled “Basic Installation (Default)”Install both CLI tools with default versions and configuration:
---- hosts: all roles: - role: bitwardenSelf-Hosted Bitwarden Server
Section titled “Self-Hosted Bitwarden Server”Configure for a self-hosted Bitwarden instance:
---- hosts: all roles: - role: bitwarden bitwarden_server_url: 'https://vault.example.com'European Bitwarden Server
Section titled “European Bitwarden Server”Configure for Bitwarden’s European region:
---- hosts: all roles: - role: bitwarden bitwarden_server_url: 'https://vault.bitwarden.eu' bitwarden_bws_server_api: 'https://api.bitwarden.eu' bitwarden_bws_server_identity: 'https://identity.bitwarden.eu'This will create ~/.config/bws/config with:
[profiles.default]server_api = "https://api.bitwarden.eu"server_identity = "https://identity.bitwarden.eu"Install Only bw CLI
Section titled “Install Only bw CLI”Install only the Bitwarden CLI, skip bws and configuration:
---- hosts: all roles: - role: bitwarden bitwarden_install_bw: true bitwarden_install_bws: false bitwarden_configure: falseInstall Only bws CLI
Section titled “Install Only bws CLI”Install only the Bitwarden Secrets CLI:
---- hosts: all roles: - role: bitwarden bitwarden_install_bw: false bitwarden_install_bws: true bitwarden_configure: falseCustom Version and Configuration
Section titled “Custom Version and Configuration”Pin specific versions and configure custom server:
---- hosts: all roles: - role: bitwarden bitwarden_bw_version: '2024.8.0' bitwarden_bws_version: '0.9.0' bitwarden_server_url: 'https://vault.example.com' bitwarden_bws_server_api: 'https://api.example.com' bitwarden_bws_server_identity: 'https://identity.example.com'Use with Tags
Section titled “Use with Tags”Control role execution with Ansible tags:
---- hosts: all roles: - role: bitwarden tags: - bitwarden - security - cli-toolsRun only specific tasks:
# Install only bwansible-playbook playbook.yml --tags bitwarden
# Skip bitwarden roleansible-playbook playbook.yml --skip-tags bitwardenPost-Installation
Section titled “Post-Installation”After the role completes, the CLI tools are ready to use:
Bitwarden CLI (bw)
Section titled “Bitwarden CLI (bw)”# Verify installationbw --version
# Login to Bitwardenbw login
# Or login with API keybw login --apikey
# Configure server (if not done by role)bw config server https://vault.example.com
# Sync vaultbw sync
# List vault itemsbw list items
# Get a specific itembw get item <item-id>
# Unlock vault and store sessionexport BW_SESSION="$(bw unlock --raw)"
# Search for itemsbw list items --search "github"Bitwarden Secrets CLI (bws)
Section titled “Bitwarden Secrets CLI (bws)”# Verify installationbws --version
# View configurationcat ~/.config/bws/config
# View helpbws --help
# Use with access tokenexport BWS_ACCESS_TOKEN="your-access-token"bws secret list
# Get a specific secretbws secret get <secret-id>The role automatically creates ~/.config/bws/config with the appropriate server URLs based on your bitwarden_server_url setting:
[profiles.default]server_api = "https://api.bitwarden.eu"server_identity = "https://identity.bitwarden.eu"Architecture Support
Section titled “Architecture Support”- bw CLI: Generic Linux build (works on all architectures)
- bws CLI: Architecture-specific builds
- x86_64 (amd64) - Most common desktop/server architecture
- aarch64 (arm64) - ARM-based systems (Raspberry Pi 4+, AWS Graviton, etc.)
The role automatically detects the system architecture for bws and downloads the appropriate binary.
Troubleshooting
Section titled “Troubleshooting”Binary Download Fails
Section titled “Binary Download Fails”If the download fails, check:
- GitHub releases exist for the specified version
- Network connectivity to GitHub
- Correct version format (e.g.,
2024.9.0, notv2024.9.0)
Command Not Found After Installation
Section titled “Command Not Found After Installation”If installed binaries are not found:
# Check installation pathls -la /usr/local/bin/bw /usr/local/bin/bws
# Verify PATH includes installation directoryecho $PATH
# Add to PATH if neededexport PATH="/usr/local/bin:$PATH"Configuration Not Applied
Section titled “Configuration Not Applied”Ensure the role is run with configuration enabled:
bitwarden_configure: trueAnd that bw CLI is installed:
bitwarden_install_bw: trueVersion Information
Section titled “Version Information”- Bitwarden CLI (bw): Default version
2026.7.0 - Bitwarden Secrets CLI (bws): Default version
2.1.0
Both repositories are monorepos that tag several products, so /releases/latest
does not return the CLI — it is usually a web, desktop, rust or python release.
Filter the release list by tag prefix instead:
# Check bw releases (cli-v tags)curl -s 'https://api.github.com/repos/bitwarden/clients/releases?per_page=100' \ | grep '"tag_name"' | grep cli-v | head -5
# Check bws releases (bws-v tags)curl -s 'https://api.github.com/repos/bitwarden/sdk-sm/releases?per_page=100' \ | grep '"tag_name"' | grep bws-v | head -5License
Section titled “License”MIT
Author Information
Section titled “Author Information”Created for ubuntu-server-config repository.
Contributing
Section titled “Contributing”To contribute improvements:
- Test changes thoroughly
- Update documentation
- Follow existing code style
- Ensure idempotency
- Verify on multiple architectures if possible