// DevOps
Bitwarden CLI: Managing passwords from the terminal and automating CI/CD
Published on 2026-09-22
Bitwarden CLI — the official command-line utility bw for working with a Bitwarden vault: find a password in the terminal, get a secret in a script, pass it to a CI/CD pipeline. The code is open-source, the utility is free and works with Bitwarden cloud as well as a self-hosted server, including Vaultwarden.
Below — installation, login, main commands and a ready-made CI template. If you don’t have your own server yet, start with the article Vaultwarden in 30 minutes; about choosing a password manager for a company — in the series “Password Managers”.
1. Installation
According to Bitwarden documentation there are several methods:
# npm (any OS; Bitwarden calls this the easiest way to update)
npm install -g @bitwarden/cli
# Snap (Linux)
sudo snap install bw
# Chocolatey (Windows)
choco install bitwarden-cli
# Homebrew (macOS and Linux)
brew install bitwarden-cliIn addition, bitwarden.com publishes ready binaries for Windows, macOS and Linux (x64). You need to place the file in a directory in your PATH, otherwise you’ll have to run commands from the directory containing it. When installing via npm on Linux you may need the build-essential package.
Check:
bw --version2. Connecting to your server
By default the CLI works with Bitwarden cloud. For a self-hosted server — Vaultwarden or self-hosted Bitwarden — specify the address before login:
bw config server https://vault.example.ruFor Bitwarden European cloud the address is https://vault.bitwarden.eu. If the server services are split across different addresses, the command has separate parameters: --web-vault, --api, --identity and others.
Vaultwarden implements the Bitwarden client API, including a personal API key, so everything described below works with it.
3. Login
Interactive login
bw loginThe utility will ask for an email address, master password and, if enabled, two-factor authentication. For organizations with single sign-on use bw login --sso.
Login with API key
For scripts and CI interactive login is not suitable. The personal API key is taken from the web interface: Settings → Security → Keys. It consists of a client_id like user.xxxx and a client_secret.
export BW_CLIENTID="user.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
export BW_CLIENTSECRET="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
bw login --apikeyImportant: the API key does not replace the master password. It only authorizes on the server; to decrypt the vault you still need bw unlock. If the key is compromised, it can be reissued — the old key and all sessions opened with it will be invalidated.
4. Unlocking and BW_SESSION
After login the vault data is still encrypted. It is decrypted by the command:
bw unlockIt outputs a session key in the form of the command export BW_SESSION="...". While the BW_SESSION variable is set, bw decrypts data without asking the master password again. The key can also be passed to a single command with the --session flag.
In scripts the master password is taken from an environment variable or a file, and the session key is obtained in one line:
# password in an environment variable
export BW_SESSION=$(bw unlock --passwordenv BW_PASSWORD --raw)
# or in a file (first line is read)
export BW_SESSION=$(bw unlock --passwordfile /run/secrets/bw_master --raw)The password file must be accessible only to the user who runs bw unlock. The session key is valid until bw lock or bw logout and is not carried over to a new terminal window.
Check current status — whether you are logged in and the vault is unlocked:
bw status5. Main commands
| Task | Command |
|---|---|
| Download fresh data from the server | bw sync |
| Search for items | bw list items --search "github" |
| Items in a folder, collection, organization | bw list items --folderid <ID> (--collectionid, --organizationid) |
| Password | bw get password "github" |
| Username | bw get username "github" |
| TOTP code | bw get totp "github" |
| Note | bw get notes <ID> |
| Entire item (JSON) | bw get item <ID> |
| Attachment | bw get attachment <filename> --itemid <ID> --output ./ |
| Generate a password | bw generate --length 24 -uln --special |
| End session | bw lock or bw logout |
A few practical notes:
bw synconly downloads data from the server. Changes made via the CLI are sent to the server immediately. If a password was changed in the browser but the script sees the old one — runbw sync.bw getaccepts an ID or a search string. In interactive use a search is convenient, but in scripts IDs are more reliable: the string may match the wrong item or several items at once.- Output is JSON, it’s convenient to parse with
jq:
bw list items --search "github" | jq -r '.[] | "\(.id) \(.name)"'Copy password to clipboard on Linux:
bw get password github | xclip -selection clipboard6. CI/CD script template
It’s better to create a separate account for CI with access only to the needed items, for example to one organization collection. BW_CLIENTID, BW_CLIENTSECRET and BW_PASSWORD are stored in protected CI variables, not in the repository.
#!/usr/bin/env bash
set -euo pipefail
# 1. Server address (before login)
bw config server https://vault.example.ru
# 2. Login with API key: BW_CLIENTID and BW_CLIENTSECRET come from CI variables
bw login --apikey
# 3. Unlock: master password comes from BW_PASSWORD variable
export BW_SESSION=$(bw unlock --passwordenv BW_PASSWORD --raw)
# 4. Secret by item ID (ID obtained in advance: bw list items --search "my-db")
DB_PASS=$(bw get item "8a562df1-443b-4892-baee-b123456789ab" | jq -r '.login.password')
# 5. Use the secret without printing it to the log
./deploy.sh
# 6. End session
bw logoutIn GitHub Actions the value obtained in the step should be masked immediately with the command echo "::add-mask::$DB_PASS" — then it will not appear in the build log even if it ends up in output.
7. Bitwarden Secrets Manager and the bws utility
Bitwarden has a separate product for infrastructure secrets — Secrets Manager with its own CLI bws and its own pricing. In it secrets are grouped into projects, and access is granted to machine accounts by an access token, without a master password:
export BWS_ACCESS_TOKEN="..."
bws secret list
bws secret get <SECRET_ID>
bws run -- ./deploy.sh # run a command with secrets in environment variablesVaultwarden does not list Secrets Manager among its features, so for a self-hosted Vaultwarden server use bw as described above.
Security guidelines
- Do not store
BW_SESSIONon disk and do not print it to logs — keep it only in process memory. - End the session with
bw lockorbw logoutat the end of the script. - Mask secrets in CI and do not pass them as command-line arguments: arguments are visible in the process list.
- Limit access. The CI account should have access only to the secrets required by the pipeline.
How to prevent leaking keys from a repository and what to do if a leak has already occurred — in the Secure Development series article “Secrets in code”.
// Reviews
Related reviews
I came with an expensive request to configure a VPS server, but during the consultation Mikhail suggested a much simpler, more affordable solution. In the end I saved time and money. Mikhail — a true expert who works for the client's result, not for the fee. I recommend him!
I came with an expensive request to configure a VPS server, but during the consultation Mikhail suggested a much simpler and more cost-effective solution. In the end I saved budget and time. Mikhail — a true expert who …
VPS setup, server setup
2026-05-12 · ★ 5/5
Excellent work! Set up the server very quickly, installed the control panel, and configured the IP. Definitely recommend!
Excellent work! Very quickly set up the server, installed the panel, configured the IP I can definitely recommend it!
Everything was excellent; helped promptly and professionally. Thank you — I recommend them to the community.
Everything's great, helped promptly and professionally, thank you, I recommend it to the community
VPS setup, server setup
2026-04-16 · ★ 5/5
There were several issues concerning both the technical side and overall understanding. Mikhail responded quickly, resolved the technical problems, and helped me understand them — many thanks. I'm satisfied with the result.
There were several issues concerning both the technical side and overall understanding. Mikhail responded quickly to the request, helped sort things out and resolved the technical problems and helped clarify …
VPS setup, server setup
2026-02-18 · ★ 5/5
Everything was done quickly and efficiently. I recommend.
Everything was done quickly and efficiently. I recommend.
VPS setup, server setup
2026-01-17 · ★ 5/5
Everything went well; the contractor responded quickly to questions and helped resolve the issue. Thanks!
Everything went well, the contractor responded quickly to questions and helped resolve the issue. Thank you!
VPS setup, server setup
2025-12-16 · ★ 5/5
// Contact
Need help?
Get in touch with me and I'll help solve the problem
I reply within one business day (03:00-13:00 GMT)
Или оставьте заявку здесь:
// Related