🔐

Bitwarden でも .env 管理がしたい 【Mac編】

に公開

本記事は長野高専 Advent Calendar 2025 - 6日目の記事です。他の方の記事もぜひ見てください!

はじめに

最近セキュリティに関する話題をよく耳にします。特に議論が活発だなと感じるのがnpmのサプライチェーン攻撃ですね。postinstall で開発者のPCから任意のファイルを盗むものが出てきているそうです[1]
今回はその中でも狙われやすい、プロジェクトファイルの .env に関する話です。.env ファイルでのシークレット管理は慣習的に使われがちですが、平文のファイルで管理するのはローカルとはいえ危険です。.env の暗号化をしましょう。

.env の暗号化には下記の方法などが使えます。

これらにより .env ファイルを平文で保存することを避け、

  • Gitへの誤ったadd
  • サプライチェーン攻撃などによる .env ファイルの流出

などを防ぐことができます。

ただ、Bitwardenにはこのような機能はありません...ので、こちらでもできるようにしたいというのがモチベーションになります。

TL;DR

今後自分も新しい環境で繰り返しセットアップすることになりそうなので、一通りの流れを先に示します。

Setup[2][3]

  1. 実行

    # Bitwarden CLI インストール、これ以外でも良い
    npm install -g @bitwarden/cli
    
    # keymaster 準備
    cd $(mktemp -d)
    git clone --depth 1 https://github.com/BonyChops/keymaster.git
    cd keymaster
    swiftc keymaster.swift -o keymaster
    mkdir -p ~/.local/bin
    mv keymaster ~/.local/bin
    cd
    
    # もし ~/.local/bin に path が通っていないようならここで通す
    
    # bw.sh, bw-env.shのダウンロード
    mkdir -p ~/scripts
    wget -O ~/scripts/bw.sh https://gist.github.com/BonyChops/fecc50786cb36dc286ebbc3b5c33a3fa/raw/bw.sh
    wget -O ~/scripts/bw-env.sh https://gist.github.com/BonyChops/fecc50786cb36dc286ebbc3b5c33a3fa/raw/bw-env.sh
    
  2. ~/scripts/bw.sh を編集

    nano ~/scripts/bw.sh # などで
    
    ~/scripts/bw.sh
    -export BW_USER='xxx@xxx'
    +export BW_USER='実際のアカウントのメールアドレス'
    
    # Keychain 上のキー名(ユーザーごとに分けたいならここを工夫)
    export BW_KEY_NAME="BW_SESSION_${BW_USER}"
    
    # ...
    
  3. ~/.zshrc に下記を追加

    ~/.zshrc
    +source ~/scripts/bw.sh
    +source ~/scripts/bw-env.sh
    

    そして反映

    source ~/.zshrc
    
  4. bw 準備

    bw --regenerate-session-key
    
  5. 完了

使い方

  1. .env を使用しているディレクトリに cd

  2. bw-env up.env を Bitwarden の Secure Note として追加

    $ bw-env up
    Uploading your .env as 📝 env:git@github.com:BonyChops/foobar.git
    Successfully uploaded your .env as 📝 env:git@github.com:karilab-dev/mushi-auction.git.
    
    Tip: Now you can try run `bw-env show` to test. If it works, you can:
    Tip: rm .env
    
  3. bw-env show で確認

    $ bw-env show
    TEST_SECRET=pass # 想定された内容が見れればok
    
  4. .env からの解放

    rm .env
    
  5. 使う時は bw-env すればOK

    $ bw-env
    Loaded environment variables from 📝 env:git@github.com:BonyChops/foobar.git into current shell.
    
    $ node index.js # Secret が反映される
    
    $ exit # 新しい sh には反映されない (都度 `bw-env` が必要)
    

Bitwarden CLI

Bitwarden を シークレットプロバイダーにするにあたり、ここではBitwarden Password Manager CLI (以降はBitwarden CLI, bw) を使います。

使ったことがなかったため、試しに試してみると...

bash-5.3$ bw login
? Email address: xxx
? Master password: [hidden]
? Two-step login method: xxx
? Two-step login code: xxxxxx
You are logged in!

To unlock your vault, set your session key to the `BW_SESSION` environment variable. ex:
$ export BW_SESSION="xxxxxxxx"
> $env:BW_SESSION="xxxxxxxx"

You can also pass the session key to any command with the `--session` option. ex:
$ bw list items --session xxxxxxxx

どうやら session キーを自分で持っていないといけないみたいですね。試しに bw list items あたりを試してみると...

bash-5.3$ bw list items
? Master password: [input is hidden] 
^C
bash-5.3$ bw list items --session xxxxxxxxxx
[{"passwordHistory":[],"revisionDate":"xxx","creationDate":"2xxx","object":"item", # ...

このように、 session がないと再度ログインを要求されます。プロジェクト実行毎にこれを要求されるのはつらいので、この辺りも管理されるようにします。

session の管理

すでにこの課題は他の人も感じていたようで、Bitwardenのフォーラムに次のようなものがありました。

https://community.bitwarden.com/t/biometric-unlock-for-bitwarden-cli/35543/2

毎度 session を打つのは辛いので、 Mac の Touch ID 要求などのプロンプトにできないかと言った内容です。
ここの Reply では次の2つの提案がありました。

  1. sudo でアクセスできるファイルに session を格納し、bw 実行毎にそれにアクセスするように設定する[2:1] (sudoでTouch ID認証が使えるようになっている前提[4])
  2. macOS keychain で session を管理する[3:1] (ただしデフォルトのプロンプトはTouch ID不可[5])

個人的には、OS の標準機能である keychain を使いつつ、 Touch ID が使えたら最高だと思います。そこで見つけたのが以下です。

https://github.com/johnthethird/keymaster

先ほどの 2. [3:2] では security コマンドを使用していましたが、 keymaster では Mac の keychain アクセス用 API を直接叩く際、Touch ID によるプロンプトを促します。

ただ、上記では Touch ID に非対応だったのと、パスワードへの fallback がなかったのでそれに対応した fork を作りました。

https://github.com/BonyChops/keymaster

先ほどの提案[2:2][3:3]を参考にしつつ、 keymaster を使う仕様にした bw を定義してあげれば良さそうです。

~/.zshrc
+source ~/scripts/bw.sh

https://gist.github.com/BonyChops/fecc50786cb36dc286ebbc3b5c33a3fa#file-bw-sh

読み込む Note の管理

あとは eval "$(bw get notes $NOTE_ID)" で良さそうですが、$NOTE_IDの管理やbw get (略)を実行をもう少し楽にやりたいです。
やるための関数を定義しておきます。

https://gist.github.com/BonyChops/fecc50786cb36dc286ebbc3b5c33a3fa#file-bw-sh

~/.zshrc
+source ~/scripts/bw-env.sh

下記のいずれかで Note 名を判定するようにしました。いずれかが満たされていることを確認してください。

  • .bw-env を作成し、Note名を記載
  • 対象プロジェクトが Git で管理されており、'origin' リモートの URL が1つ設定されている

次に、.env ファイルを記載します。ここでは以下の .env を例として使います

.env
TEST_SECRET=pass

bw-env up を実行、すると Bitwarden の Note として .env が登録されます。

$ bw-env up
Uploading your .env as 📝 env:git@github.com:BonyChops/foobar.git
Successfully uploaded your .env as 📝 env:git@github.com:karilab-dev/mushi-auction.git.

Tip: Now you can try run `bw-env show` to test. If it works, you can:
Tip: rm .env

あとは bw-env showを実行して、.env ファイルなしで secret が降ってくることを確認してください。

$ bw-env show
TEST_SECRET=pass # 想定された内容が見れればok

$ rm .env # .envからの解放

使う時は bw-env すればOKです。

$ bw-env
Loaded environment variables from 📝 env:git@github.com:BonyChops/foobar.git into current shell.

$ node index.js # Secret が反映される

$ exit # 新しい sh には反映されない (都度 `bw-env` が必要)
脚注
  1. NPMサプライチェーン攻撃の現状と分析 | トレンドマイクロ (JP) ↩︎

  2. How to use use Bitwarden CLI with macOS Touch ID ↩︎ ↩︎ ↩︎

  3. Biometric unlock for Bitwarden CLI - Feature Requests / Password Manager - Bitwarden Community Forums ↩︎ ↩︎ ↩︎ ↩︎

  4. Configure Touch ID for the sudo command - How to use use Bitwarden CLI with macOS Touch ID ↩︎

  5. 本当に謎、デフォルトであって欲しい ↩︎

Discussion