Touch ID 付きでローカルにシークレットを保管できるコマンドラインツール「cubby」の紹介
Touch ID 付きでローカルにシークレットを保管できるコマンドラインツール「cubby」を作りました。mac 専用です。
- シークレットを保存しておきたい
- でもクラウドで管理するほどのものではないのでローカルに置いておきたい
- でも平文では置いておきたくない
というときにサクッと使えるものがほしいなと思って作りました。
この記事では cubby のインストール方法から基本的な使い方についてまとめます。
インストール
Homebrew でインストールできます。
$ brew install koki-develop/tap/cubby
使い方
$ cubby --help
OVERVIEW: Secret store gated by Touch ID.
USAGE: cubby <subcommand>
OPTIONS:
--version Show the version.
-h, --help Show help information.
SUBCOMMANDS:
init Create the store.
set Save a secret.
get Print a secret.
rm Delete a secret.
list List the names of the stored secrets.
See 'cubby help <subcommand>' for detailed help.
ストアを作成する
まずは cubby init でシークレットを保存するためのストアを作成します。
$ cubby init
Created a store at ~/.cubby
ストアはデフォルトで ~/.cubby に作成されますが、CUBBY_HOME 環境変数で場所を変えることもできます。
$ export CUBBY_HOME=/path/to/store
$ cubby init
シークレットを保存する
cubby set <任意の名前> でシークレットを保存できます。
# 値を対話的に入力
$ cubby set my-secret
Value:
# 標準入力から値を渡すこともできる
$ echo -n 'P@ssw0rd' | cubby set my-secret --from-stdin
# 同じ名前のシークレットを上書きしたい場合は `--force` を指定する
$ cubby set my-secret --force
実行すると Touch ID を求められます。

認証に成功すると保存が完了します。
Saved "my-secret"
シークレットを一覧する
cubby list で保存しているシークレットの名前を一覧できます。
$ cubby list
my-secret
openai-api-key
super-secret
シークレットを取得する
cubby get <名前> でシークレットを取得できます。set と同じく Touch ID を求められます。
$ cubby get my-secret

取得した値は標準出力に出力されます。
P@ssw0rd
シークレットを削除する
cubby rm <名前> でシークレットを削除できます。
$ cubby rm my-secret
Deleted "my-secret"
仕組み
cubby は Secure Enclave と Touch ID を使ってシークレットを保護しています。
Secure Enclave は Apple のチップに組み込まれている専用のセキュリティサブシステムです。
メインプロセッサから分離されていて、たとえ OS のカーネルが乗っ取られたとしても中のデータが漏れないように設計されています。Touch ID の指紋データなどもここで保護されています。
cubby init を実行すると、この Secure Enclave の中に「Touch ID に成功したときだけ使える」鍵が生成されます。
生成された鍵は Secure Enclave によってラップされた状態で $CUBBY_HOME/key.blob に保存されます。これをそのまま鍵として使うことはできず、元の鍵に戻せるのは生成した Secure Enclave だけです。
シークレットはこの鍵で 1 つずつ暗号化されて $CUBBY_HOME/secrets/ に保存され、取得するときも同じ鍵で復号します。
そのため、保存時と取得時に毎回 Touch ID が求められます。
$CUBBY_HOME/
├── key.blob # Secure Enclave の鍵 (ラップ済み)
└── secrets/
└── <hex>.bin # 暗号化されたシークレット (1 つにつき 1 ファイル)
シークレットの復号に必要な秘密鍵は Secure Enclave の外に出ることはありません。
なので、仮にストアごとファイルを盗まれたとしても、別の Mac では中身を読み取れませんし、同じ Mac 上であっても Touch ID を通さない限り復号はできません。
まとめ
サクッと使えて便利。
Discussion