Bitwardenからpassword-storeに移行した

Introduction

Bitwardenからpassword-storeに移行したので作業内容をメモしておく。

Basic

  • 普段使うものは可能な限りPlain TextとGitで管理したい
  • EmacsやTerminalから簡単に呼び出したい
  • GnuPGを可能な限り活用したい

Goal

  • Bitwardenに保存されているすべての情報をpassword-storeに移行する
  • EmacsやTerminalから簡単にパスワードを取得できるようにする

Not Goal

  • Bitwardenのアカウントを完全に削除する
    • 数年間使わなくても問題なかったら適切に削除する

技術選定

password-storeを選択した理由は以下。

  • 十分に枯れている
  • Plain TextとGitで管理できる
  • password-storeが挙動しなくなってもGPGさえ動けば良い
    • shell scriptの小さなコードベースで書かれている
    • GPGが動かない時は git commit もできない状態なので根本的に問題
  • 2024年現在所属している会社でpassword-storeを使っている
  • TOTPに対応している
  • Emacs Packageがある

周りのエンジニアに何を使っているのか聞いたところ、1passwordBitwardenを使っている人が大半だった。

作業手順

1. Bitwardenからパスワードを抽出する

bitwarden/clients を手元のPCに入れる。

$ bw --version
2023.12.1

Loginしてセッションを取得。

$ bw login

bw list items コマンドを叩いてパスワードを抽出する。

$ bw list items --session <session_id> \
      | jq '.[] | { folderId: .folderId, name: .name, login: .login }' \
      | jq . > /tmp/bw.json

以下のようなjsonが /tmp/bw.json に出力される。

{
  "folderId": "ad72f121-6385-49ea-8983-xxx",
  "name": "foo",
  "login": {
    "fido2Credentials": [],
    "username": "name",
    "password": "pass",
    "totp": null,
    "passwordRevisionDate": null
  }
}
{
  "folderId": "ad72f121-6385-49ea-8983-yyy",
  "name": "bar",
  "login": {
    "fido2Credentials": [],
    "username": "name",
    "password": "pass",
    "totp": null,
    "passwordRevisionDate": null
  }
}

2. passコマンドをインストールする

私はNixユーザーなのでNix Packageからpassを落としてくる。以下のような設定でhome-manager経由で入れる。

{ pkgs, ... }:

{
  home.packages = with pkgs; [
    (pass.withExtensions (extensions: with extensions; [ pass-otp ]))
  ];
}

3. password-storeのリポジトリを作成する

GitHub Private Repoを作成し、pass - archlinux wikiを参考にpassword-storeを作る。

$ pass init <gpg-id or email>

4. password-storeへパスワードを移行

folder_id の一覧APIはなさそうだったので、Bitwardenの画面と照らし合わせて手動でfolder_idを取得する。

$ cat /tmp/bw.json | jq 'select(.folderId == "<folder_id>")'  | jq . > /tmp/<folder>.json

抽出したものを手動で下記のようなフォーマットに変換した。

P@ssw0rd
url: https://servicename.com/
username: username

5. Fish Shell設定

config.fish に以下の設定を追加する。

if type -q pass
    set -x PASSWORD_STORE_DIR $HOME/ghq/github.com/takeokunn/password-store
    set -x PASSWORD_STORE_ENABLE_EXTENSIONS true
end

Fish Completionはここから落としてくる。

https://github.com/zx2c4/password-store/blob/master/src/completion/pass.fish-completion

6. Emacs Plugin導入

以下のようにNicolasPetton/passを設定する。

(autoload-if-found '(pass pass-view-mode) "pass" nil t)

(add-to-list 'auto-mode-alist (cons (substitute-in-file-name "$HOME/ghq/github.com/takeokunn/password-store/.*\\.gpg") 'pass-view-mode))

(with-eval-after-load 'pass
  (setq pass-suppress-confirmations t))

pass-view-mode 用に以下のようなyasnippetを設定する。

# -*- mode: snippet -*-
# name: template
# key: template
# --
url: $1
username: $2
memo: $0

Result

183個の秘匿情報が入ったgpgファイルを作成した。

$ git -C ~/ghq/github.com/takeokunn/password-store ls-files | grep .gpg | wc -l
183

以下のようなディレクトリ構成を作成した。

~/.ghq/github.com/takeokunn/password-store/
├── README.org
├── .gpg-id
├── private
|   └── life
|       └── 楽天証券.gpg
├── project-A
├── project-B
└── project-C
    └── shopify
        └── aaa.gpg
    └── infra
        └── aws.gpg

NextStep

所感

Bitwardenは使いやすく特に文句がなかったので、理由がない限りはでpassword-storeに移行する必要はないし、これからパスワードマネージャーを入れる人はBitwardenを勧めたい。