CLI - move command

tl;dr – using the BitWarden CLI in a bash script, how can one specify the --sessionid for the move command?

It took me a long time to get the BitWarden CLI move command to work via bash script. I finally did but in a way not described in the docs.

Setup:

  • Ubuntu 20.04, using bash.
  • Using BitWarden standalone CLI executable.
  • Using --api=key login method, populating environment variables BW_CLIENTID and BW_CLIENTSECRET and BW_PASSWORD from files readable only to the current user.
  • Using --session $BW_SESSION for commands where available to automate authentication.
  • Utilizing web vault (not self-hosted vault).

Script ultimate goal:

  • Find any Items which are not part of an Organization and move them to the desired Organization as well as a specific pre-determined Collection within that Organization.

What the script does:

  • Login to vault using --apikey (BW_CLIENTID and BW_CLIENTSECRET previously populated).
  • Unlock vault using --passwordenv BW_PASSWORD.
  • List the Organizations in the vault (there is only one Organization).
  • Store Organization ID for that one Organization in env variable bwOrgID
  • List the Collections in the Organization.
  • Store a specific Organization Collection ID for a collection I know the name of in env variable bwSelectedOrgCollectionID (this is the “target Collection”).
  • List out the items which are not part of the Organization (i.e., where --organizationid null)
  • For the items which are not part of the Organization, store the Item IDs for each in an array called bwNonOrgItemsList
  • For each of the Item ID’s in array bwNonOrgItemsList, move those to the Organization and the predetermined target Collection.

Where the challenge was:

I could not figure out how to structure the bw move command to specify the Session ID (–session) within the script. Without being able to do that, as the script ran I was prompted to manually enter the vault password. The docs don’t indicate this, nor do they state explicitly how or if session ID can be used.

To simplify things for myself mentally, I used the following code in a for loop:

      # Note: $line is set for each item traversing through the bwNonOrgItemsList[@] array.
      # In other words, $line contains a specific Item ID.
      encodedJson=$(echo '["'$bwSelectedOrgCollectionID'"]' | ./bw encode)
      ./bw move $line $bwOrgID $encodedJson <<< "$BW_PASSWORD"

The above lines do successfully move the items into the Organization and into the desired target Collection within the Organization.

Questions:

  • Is the above acceptable in that it doesn’t violate any BitWarden best practice or perhaps introduce a vulnerability of some sort, however temporary?
  • Is there a way to use --sessionid with the move command in a script?
  • Is there a better way to specify the master password which seems to be required?
  • Is there a known “correct” way to do what I am looking to do?

P.S The BitWarden CLI is great. Lots of possibilities for useful things to do.

Hi there monitor- is there any chance you could share your script? or a portion of it?

I’m writing my own script for automating password retrieval (should be very simple) by using the login --apikey method. However, even though I’ve populated the BW_CLIENTID and BW_CLIENTSECRET environment variables, it still prompts me to enter them manually.

If I could take a peek at your script I might find some clues to what I’m doing wrong :smiley:

Here is a piece of the script. Some of it altered for this response. The script is almost 400 lines long and you likely don’t need all of it, plus it has some stuff in there which I’d have to redact and all that.

Assumption that you run your script from the same directory as the bw command - the the “./bw” calls. You can change this - just put in the correct path instead of “.”.

#- Summary:
#- I have the BW_CLIENTID, BW_CLIENTSECRET, BW_PASSWORD stored in text files in a
#- closely controlled directory. The directory is $HOME/bwstuff.
#- The snip below exposes the necessary values into the environment
#- by reading the named files in $HOME/bwstuff directory. The login --api-key uses those env variables.
#- The BW_SESSION line gets the session ID from from the bw unlock call.
#- When finished, the vault is locked and it logs out from bitwarden.

#- Import the values from suitably permissioned local files
export BW_CLIENTID=$(cat ~/bwstuff/BW_CLIENTID.txt)
export BW_CLIENTSECRET=$(cat ~/bwstuff/BW_CLIENTSECRET.txt)
export BW_PASSWORD=$(cat ~/bwstuff/BW_PASSWORD.txt)

#######################################################################
echo
echo “Logging in…”
./bw login --apikey

echo “Unlocking vault…”
export BW_SESSION=$(./bw unlock --passwordenv BW_PASSWORD)

#######################################################################

#- DO VARIOUS THINGS IN HERE

#######################################################################

echo
echo “Locking vault…”
./bw lock

echo
echo “Logging out…”
./bw logout

#######################################################################

#- Clear out sensitive environment variables
unset BW_CLIENTID
unset BW_CLIENTSECRET
unset BW_PASSWORD
unset BW_SESSION

1 Like

Thanks for sharing. Turns out I wasn’t using bash variables correctly.

Can you share what you started with and what you corrected?

This is the command i needed:
BW_CLIENTID=$BW_CLIENTID BW_CLIENTSECRET=$BW_CLIENTSECRET bw login --apikey

I was expecting the environment variables to be implicitly passed- but I hadn’t exported them.