🔐

1Password CLIを利用したセキュアなシークレットの管理

に公開

開発部のねこたんです.ニャア(ΦωΦ).

Shai-HuludやS1ngularityといった,パッケージマネージャを経由したサプライチェーン攻撃が昨今話題になっています.

cf. NPMサプライチェーン攻撃の現状と分析 | トレンドマイクロ (JP)

これらのマルウェアは実行環境にあるシークレットを窃取するため,ローカル開発環境におけるシークレットの取り扱いについて対策が必要だと感じ,1Password CLIを使ったセキュアなシークレット管理を試してみました.

弊社におけるパスワード管理

弊社では1Passwordのライセンスが全社員に標準で付与されており,個人用のvaultやチーム用のvaultなどに分けてシークレットを管理しています.以下のような利点があり,とても便利でセキュアだと感じています.

  • 個別にファイルやGoogle Drive等でシークレットを管理する必要がなく,散在や漏洩のリスクが低い
  • 組織で共有するものは常に最新のものが共有される
  • ブラウザ拡張によって自動でパスワード入力がされる(フィッシングサイト等の異なるドメインに間違って入力されるリスクが低い)

パスワードマネージャは重要な福利厚生ですね!実はプライベートでも10年以上利用しています.

ローカル開発環境におけるシークレット漏洩の懸念

Shai-HuludやS1ngularityといったマルウェアは,実行環境のファイルシステムや環境変数からシークレットの窃取を試みます.よくある.envなどの環境変数ファイルへシークレットが直接記述されている場合や,export API_KEY=hogeのように広い範囲で参照可能な環境変数があると,これらのマルウェアによりシークレットが窃取されてしまうリスクが高まります.

「ローカル環境だから大丈夫」とファイルにGitHubやAWS等のAPIトークンを直接記述していて,開発で必要になったライブラリをyarn installした瞬間にシークレットが窃取され,GitHubリポジトリが改変・全消去され,AWSに大量のマイニング用インスタンスが立てられて多額の請求が来る,S3にある重要な顧客情報が漏洩する・・・考えただけで恐ろしいですね.

1Password CLI

1PasswordはWebブラウザ上やアプリで使用するのが一般的ですが,CLIで利用するためのコマンドも提供されています.

cf. 1Password CLI | 1Password Developer

インストール

Macの場合はbrew install 1password-cliでインストール可能です.
その他のOSはGet started ページを参照してください.

CLIからシークレットの取得(op read)

例えば1Passwordで以下のようなアイテムを作ってあるとします.

このアイテムのpasswordの値を次のようなコマンドで取得することができます.(ここではvault名がmyvaultであるとします.)

$ op read "op://myvault/sample item/password"
# -> mypAssw0rd

なお,アイテム名に(などが含まている場合は名称でop://のURLを指定してもうまくいかなかったので,そういった場合はアプリからユニークなURLを取得して利用できます.

$ op read "op://myvault/sample item (hoge)/password"
# -> [ERROR] 2025/10/17 15:40:50 could not read secret 'op://myvault/sample item (hoge)/password': invalid secret reference 'op://myvault/sample item (hoge)/password': invalid character in secret reference: '('
$ op read "op://myvault/thisisnotvalidurlhnrb22im/password"
# -> mypAssw0rd

環境変数にシークレットをセットしてコマンド実行(op run)

アプリケーションが環境変数からシークレットを読む場合はop runコマンドを利用できます.

$ PASSWORD="op://myvault/thisisnotvalidurlhnrb22im/password" op run -- bash -c 'echo password is $PASSWORD'
# -> password is <concealed by 1Password>
$ PASSWORD="op://myvault/thisisnotvalidurlhnrb22im/password" op run --no-masking -- bash -c 'echo password is $PASSWORD'
# -> password is mypAssw0rd

出力先がコンソールの場合は--no-maskingを付けないと隠されるようになっています.セキュアな作りですね.

このop runは,環境設定ファイルを読み込むことができるので,従来.envファイルなどの中に直接書いてしまっていたシークレットを置き換えることができます.

.env
PASSWORD="op://myvault/thisisnotvalidurlhnrb22im/password"
op run --env-file=".env" -- bash -c 'echo password is $PASSWORD'
# -> password is mypAssw0rd

設定ファイルに注入する(op inject)

アプリケーションが設定ファイルからシークレットを読む場合はop injectコマンドを利用できます.

env.yml.template
api:
    token: op://myvault/thisisnotvalidurlhnrb22im/password
$ op inject --in-file env.yml.template -o env.yml
env.yml
api:
  token: mypAssw0rd

ただし,この方法はファイルにシークレットが書かれてしまうので,リスクが高くなります.
アプリケーションの実行が終わったら削除されるようにするなど,なんらかのリスク軽減策もあわせて検討したほうがよいでしょう.

課題

ファイルシステムにシークレットを直接残さないようにしたり,環境変数のライフタイムを短くすることで,冒頭のようなサプライチェーン攻撃に対するリスクを緩和することができます.しかし,これらの攻撃はローカルで任意のコマンドが実行される仕組みを利用したものであることから,DDoSボット化やマイニングなど,他のセキュリティ影響も考えられます.これだけで十分と考えず,例えばコンテナなどを利用して隔離された環境で開発を行う,などの対策も考えていく必要があるかもしれません.

このあたりの話はmozaic.fm ep185でも触れらていたので,よかったら参考にしてください.

https://mozaic.fm/episodes/185/monthly-ecosystem-202509.html

まとめ

1Password CLIを利用することで,ファイルシステムに永続的にシークレットを残さず,アプリケーションが実行時にのみシークレットを参照できるようにリスク緩和が図れます.また,1Password自体の利点も享受できます.(例えば,共有パスワードなどが常に同期されているので,漏洩時などを想定したローテーションが行いやすいなど.)

環境変数ファイルなどにシークレットを直接記述している現場は多いと思うので,この機会にパスワードマネージャの導入やCLIからの実行時参照を検討してはいかがでしょうか.

Milabo Engineers Blog

Discussion