🔒

Bitwardenとchezmoiを使って複数のデバイス間で機密情報を共有する

2023/07/30に公開

最近dotfilesの管理にzxを使用した自作スクリプトを使うのをやめて、chezmoiに変更したのですが、chezmoiの特徴的な機能の一つにパスワードマネージャーを使って機密情報を複数のデバイス間で共有できるというものがあるので、パスワードマネージャーにBitwardenを使用した場合どうするのかを記事にしたものになります。

例として~/.ssh/id_ed25519が機密情報であることを前提に、デバイス間で共有できるようにしていきましょう。

必要なもの

https://www.chezmoi.io/install/
https://bitwarden.com/help/cli/#download-and-install

Bitwarden

このセクションではBitwardenにid_ed25519の内容をセキュアノートに保存していきます。

そしてBitwarden側に作成したアイテム(この場合セキュアノート)のIDがchezmoiで必要になるので、Bitwarden CLIを使った操作が必要になります。

ログイン

既にログインしている場合は不要です。

nushell
bw login

一時的なセッションを作成

nushell
$env.BW_SESSION = (bw unlock --raw)

ローカルにある機密情報をBitwardenに移す

セキュアノートにファイルの内容を保存していきます。

bw create itemの引数に渡すデータを作成する

面倒くさいことにbw create itemを使ってBitwardenにセキュアノートを作るにはJSONをBase64でエンコードしたものを引数に渡す必要があるため、まずはそれを作成します。

bw get template itembw create itemに必要なデータのテンプレートが手に入るため、それを編集してbw encodeでBase64にエンコードしたものをBW_ENCODED_JSONという名前でも付けて変数に格納しておきます。

nushell
let BW_ENCODED_JSON = (
  | bw get template item
  | from json
  | update secureNote { type: 0 } # セキュアノートを作る場合に必要
  | update type 2 # セキュアノートの場合は"type"に2を指定
  | update name private_key # セキュアノートに付ける名前
  | update notes (open ~/.ssh/id_ed25519) # セキュアノートの内容(ファイル内容)
  | to json
  | bw encode
)

セキュアノートを作成

bw create itemと先ほど作成したデータ($BW_ENCODED_JSON)を使ってセキュアノートを作成します。

成功すればアイテムの情報が入ったJSONが出力されるので、取り出してBW_ITEM_IDという名前の変数でも作って保持しておきます。(次のセクションで使います)

nushell
let BW_ITEM_ID = (bw create item $BW_ENCODED_JSON | from json | get id)

以上でBitwarden側での作業は終了になります。

参考

https://bitwarden.com/ja-JP/help/cli/#create

chezmoi

chezmoi initを実行したときに~/.local/share/chezmoiにできるローカルリポジトリが存在していることが前提で話をしていきます。

機密として管理するファイルを追加する

nushell
chezmoi add -T ~/.ssh/id_ed25519

Bitwardenから機密情報を取り出すのにテンプレート関数を使用するので、必ずchezmoi addを使用するときは -T (--template) オプションを加えます。

そうすると、~/.local/share/chezmoi/dot_ssh/id_ed25519.tmplというファイルが作成されるはずです。

参考

https://www.chezmoi.io/reference/commands/add/

テンプレートファイルを編集

Bitwardenセクションで作成した変数$BW_ITEM_IDが必要になります。

このままの状態で~/.local/share/chezmoi/dot_ssh/id_ed25519.tmplをコミットしてプッシュまでしてしまうと機密情報ダダ漏れでご愁傷さまコースなので、bitwardenというテンプレート関数を使って、機密情報をchezmoi applyを実行したら~/.ssh/id_ed25519の内容はBitwardenにあるものに置き換えて、~/.local/share/chezmoi/dot_ssh/id_ed25519.tmplには機密情報を載せないようにしていきます。

nushell
$"{{ \(bitwarden "item" "($BW_ITEM_ID)").notes }}" | save -f ~/.local/share/chezmoi/dot_ssh/id_ed25519.tmpl

bitwarden関数の返り値はbw get item $BW_ITEM_IDで確認することができます。
セキュアノートの場合はnotesキーの中に機密情報が格納されているので、{{ (bitwarden "item" "itemId").notes }}という形になります。

参考

https://www.chezmoi.io/reference/templates/bitwarden-functions/bitwarden/

変更を適用する

以上でchezmoi側での作業が終了になるため、gitを使って変更をリモートリポジトリに反映しましょう。

その後作業を行ったマシンでchezmoi applyを実行し、別のデバイスではchezmoi updateを実行すると見事~/.ssh/id_ed25519にBitwardenに保存した内容が反映されているはずです。

Bitwardenを使って管理する機密情報が増えてきたら、Bitwardenのセクションで記載した通り$env.BW_SESSION = (bw unlock --raw)を実行してからchezmoi updatechezmoi applyを行うようにすることをオススメします。

終わり

書いてから思ったけど、セキュアノートではなくユーザーネームとパスワードが設定されていないログインアイテムを作ってから添付ファイルに機密ファイルを設定してbitwardenAttachmentを使うのがより適切なのではなかろうか?

それと最近Fishやめて、Nushellにしたのでこの記事のコマンドサンプルはゴリゴリにNushellを使用したものにしてみました。

UNIX-likeなコマンドサンプルを期待していた方はごめんなさい、Nushell始めてください!

Discussion