Handle multiple servers with Bitwarden CLI

Issue description

I recently ran into a problem with the Bitwarden CLI. We use it in our company but another company that I am doing contract work for also stores secrets in their own Bitwarden instance. Now to my dismay I learned that the bw CLI can only be connected to a single server and to switch servers you have to actively run bw logout.

Constantly running…

bw logout
bw config server https://vault.somedomain.tld
bw login

…is way to cumbersome so I wrote a small helper script to simplify the process.

Solution

Note: this requires fzf and jq.

In your Bitwarden CLI data dir you will find a data.json. That file represents the vault that is encrypted with your master password.

Steps:

  1. In the data dir create a subfolder for each of your Bitwarden servers
  2. Create a config.json in the data dir where the account property matches the respective subfolder name
  3. Move the data.json into the subfolder
    • configure and login next server (that’ll create a new data.json)
  4. Repeat step 3 until all subfolders contain a Bitwarden vault
  5. Save bwctx script

Now every time you run bwctx you can pick which company’s vault you want to work with. Run bwctx list to see which vault is currently active.

Here’s an example

$ bw config server https://vault.example.org/
$ bw login
# now connected to https://vault.example.org/ with 
# an encrypted data.json in the BW data dir
$ cd "$HOME/Library/Application Support/Bitwarden CLI"
$ mkdir eo
$ mv data.json ./eo/
$ bw config server https://vault.contoso.com/
$ bw login --sso # this server uses SSO so use OAUTH2 for the login
$ mkdir cc
$ mv data.json ./cc/
# create config.json and add bwctx to your PATH
$ bwctx
switching to: eo
$ bwctx list
current config: ./eo/data.json

bwctx

Store somewhere in your PATH, typically as /usr/local/bin/bwctx:

#!/bin/bash

# Linux: "$HOME/.config/Bitwarden CLI"
VAULT_PATH="$HOME/Library/Application Support/Bitwarden CLI"
CONF_PATH="${VAULT_PATH}/config.json"
cd "${VAULT_PATH}"

if [ "$#" -ge  "1" ]; then
    echo "current config: $(readlink data.json)"
    exit 0
fi

ACCOUNT=$(cat "${CONF_PATH}" | jq -r '.[].account' | fzf)

if [[ ! -z "${ACCOUNT}" ]]; then
    echo "switching to: ${ACCOUNT}"
    ln -sf "./${ACCOUNT}/data.json" data.json
fi

config.json

[
  {"server": "https://vault.contoso.com/", "account": "cc"},
  {"server": "https://vault.example.org/", "account": "eo"}
]

Directory structure

Library/Application Support/Bitwarden CLI                                                                                                                                                                              
▶ tree  
.
├── config.json
├── data.json -> ./eo/data.json
├── eo
│   └── data.json
└── cc
    └── data.json