I have already write a post about bitwarden backup, about this very topic. At first, I thought to just update it as I did with cloudflare backup and later with faktury-online backup. After a bit of changes to that post I have found out that I have made so much changes to the whole idea and the script itself that a new post is worth writing instead.
GitHub Action workflow#
Apart from setting up the secrets, this is the only script that is needed
for me. Works for both personal and org accounts without a problem. Save as
.github/workflows/main.yml
and as always, activate GitHub workflows write
permissions so the commits can me made periodically.
name: Bitwarden.com backup
on:
workflow_dispatch:
schedule:
- cron: "30 0 * * 0"
jobs:
backup:
runs-on: ubuntu-22.04
env:
BW_CLIENTID: ${{ secrets.BW_CLIENTID }}
BW_CLIENTSECRET: ${{ secrets.BW_CLIENTSECRET }}
BW_PASSWORD: ${{ secrets.BW_PASSWORD }}
BW_ORGANIZATION_ID: ${{ secrets.BW_ORGANIZATION_ID }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- run: |
npm install
./node_modules/@bitwarden/cli/build/bw.js login --apikey
./node_modules/@bitwarden/cli/build/bw.js export --format json --session $(./node_modules/@bitwarden/cli/build/bw.js unlock --passwordenv BW_PASSWORD --raw) --raw | openssl aes-256-cbc -a -salt -pbkdf2 -k $BW_PASSWORD -out personal.json.enc
./node_modules/@bitwarden/cli/build/bw.js export --format json --session $(./node_modules/@bitwarden/cli/build/bw.js unlock --passwordenv BW_PASSWORD --raw) --raw --organizationid "$BW_ORGANIZATION_ID" | openssl aes-256-cbc -a -salt -pbkdf2 -k "$BW_PASSWORD" -out organization.json.enc
./node_modules/@bitwarden/cli/build/bw.js lock
./node_modules/@bitwarden/cli/build/bw.js logout
- if: ${{ !env.ACT }}
uses: stefanzweifel/git-auto-commit-action@v5
Running locally#
It is possible to run this locally via act
but the guide is already in
previous posts, so I will just state here what is strictly required:
npm i @bitwarden/cli
npx bw login
Decrypting#
The backup is stored in an encrypted form even in a repository. The password is stored in GitHub secrets and when your account is compromised it of course can be extracted, but hey, you should have your 2FA stored in different location/device anyway. To decrypt the data to actually use it run the following:
openssl aes-256-cbc -d -a -pbkdf2 -in personal.json.enc -out personal.json
openssl aes-256-cbc -d -a -pbkdf2 -in organization.json.enc -out organization.json
Enjoy!