15
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

KDDIアジャイル開発センター(KAG)Advent Calendar 2023

Day 10

1Password CLIで認証情報をセキュア&便利に使おう!

Last updated at Posted at 2023-12-09

1Passwordとは

1Password はパスワードマネージャーとして有名な製品です。

単にID/PWだけでなく、MFAやパスキーにも対応し、SSHの鍵情報やAPIのアクセスキーも管理できます。

また、これらを開発者がより簡単に利用するための1Password CLIも提供されています。

本記事では 1Password CLI を使うことで、認証情報をセキュアに、かつ便利に扱う方法を紹介します。

お題: APIトークンを挿入する

APIトークンなどの認証情報は流出したら一大事です。
これら認証情報を扱うときはみなさん細心の注意を払っていると思います。

とはいえ人間は完璧ではありません。
どんなに気をつけていても、一瞬の気の緩みから流出事故につながることがあります。

以下はGitHub REST APIでissueを取得して表示するNode.jsのコード例です。
<token> 部分に https://github.com/settings/personal-access-tokens/new で生成できるトークンが入ります。

api-client.js
(async () => {
    // USERはユーザー名、REPOはリポジトリ名
    const response = await fetch("https://api.github.com/repos/USER/REPO/issues",{
        method: "GET",
        headers: {
            "Accept": "application/vnd.github+json",
            "Authorization": "Bearer <token>",
            "X-GitHub-Api-Version": "2022-11-28",
        }
    });
    const data = await response.json();
    console.log(data);
})();

<token> にトークンをベタ書きすればもちろんAPIを叩けますが、実際の開発現場でそのようのことは許されないでしょう。

よく使われる方法

①環境変数からトークンを取得する

以下のようなコードで、実行時に環境変数にトークンを渡します。

api-client.js
(async () => {
    // USERはユーザー名、REPOはリポジトリ名
    const response = await fetch("https://api.github.com/repos/USER/REPO/issues",{
        method: "GET",
        headers: {
            "Accept": "application/vnd.github+json",
            "Authorization": `Bearer ${process.env.GITHUB_ACCESS_TOKEN}`,
            "X-GitHub-Api-Version": "2022-11-28",
        }
    });
    const data = await response.json();
    console.log(data);
})();
# 実行時にセット
GITHUB_ACCESS_TOKEN=github_pat_XXXXXXXXXXXXXXXXXXXXXXXXXX node api-client.js

# またはセッション内で環境変数にセット
export GITHUB_ACCESS_TOKEN=github_pat_XXXXXXXXXXXXXXXXXXXXXXXXXX
node api-client.js

この方法の面倒なところは、実行時 or セッションが変わるたびに毎回トークンの入力が必要なところです。

.env にトークンを記載する

①のデメリットを補う方法として、.env がよく使われると思います。
以下のような .env ファイルを作成し実行時に環境変数にセットすることができます。

ここでは env-cmd を使っています。

.env
GITHUB_ACCESS_TOKEN=github_pat_XXXXXXXXXXXXXXXXXXXXXXXXXX

実行コマンド。api-client.jsの中身は①と同じです。

npx env-cmd -f .env node api-client.js

利便性から、この方法は多くの開発現場で採用されているのではないでしょうか。

しかしこの方法には弱点があります。
それは.envファイルは絶対にコミットしてはいけないことです。

開発者は常に気をつけているはずですが、typoで.gitignoreされてなくてコミットしてしまったなどミスが起こる可能性を常にはらんでいます。

またそもそも、こうしたトークンが各開発者PCで平文で管理されている事自体、流出のリスクを上げています。

最近はGitHub Copilotを導入している現場も増えていると思いますが、平文で管理していると、Copilotが秘密情報を含んだ情報を外部に送信しないような追加の設定も必要になります。
設定する前に.envに秘密情報を記載してしまったら、コミットしなくても外部に送信はされてしまいます。

1Password CLI でトークンを安全に取得する

本題です。1Password CLIを使って、1Passwordの保管庫に保存されたトークンを実行時に環境変数にセットすることができます。

ベースは env-cmd と同じですが、.envファイルに記載する内容と実行時のコマンドが変わります。

まずは結論

.env
# 1Passwordに保存したアイテムの秘密参照を記載する
GITHUB_ACCESS_TOKEN="op://Personal/GitHub Access Token/credential"

実行コマンド

op run --env-file=".env" -- node api-client.js

以下が env-cmd との差分です。

  • .envにトークンをベタ書き
    1Passwordに保存したアイテムの秘密参照
  • npx env-cmd -f .env
    op run --env-file=".env" --

以下で方法を詳しく説明します。

トークンを1Passwordアイテムとして保存する

「新規アイテム」から「API認証情報」を選択、「認証情報」の欄にトークンを入れて保存します。
image.png
image.png

アイテムの秘密参照をコピーする

先程作成したアイテムを開き、右の三角記号から「秘密参照をコピーする」を選択して秘密参照をコピーします。
image.png

.env ファイルに秘密参照を貼り付ける

コピーした秘密参照を .env ファイルに貼り付けます。

.env
# 1Passwordに保存したアイテムの秘密参照を記載する
GITHUB_ACCESS_TOKEN="op://Personal/GitHub Access Token/credential"

実行する

op run --env-file=".env" -- node api-client.js

1Password CLIを使うと何が嬉しいか

env-cmd と比較して 1Password CLI が嬉しい点は以下です。

  • env-cmdと遜色ない利便性を保てる
  • トークンをセキュアに管理できる
  • 各開発者の実行前の.envセットアップが不要になる

それぞれ詳しく見ていきます。

env-cmdと遜色ない利便性を保てる

比較のため2つの方法を並べると、記載内容やコマンドが異なるだけで、実行時の利便性はほとんど変わらないことがわかります。

.env
# 1Password
GITHUB_ACCESS_TOKEN="op://Personal/GitHub Access Token/credential"
# env-cmd
GITHUB_ACCESS_TOKEN=github_pat_XXXXXXXXXXXXXXXXXXXXXXXXXX

実行コマンド

# 1Password
op run --env-file=".env" -- node api-client.js
# env-cmd
npx env-cmd -f .env node api-client.js

トークンをセキュアに管理できる

.envにトークンを直接記載する方法だと以下のリスクがあります。

  • 設定ミスや作業ミスなどで誤って.envをコミットしてプッシュしてしまう
  • 設定ミスにより GitHub Copilot などが .env の中身を外部に送信してしまう
  • 各開発者がそれぞれトークンを管理することになるため、開発者が多くなるほど流出リスクが増大する
  • トークンが1つしかない場合の共有方法がグレー

4つ目について、使用したいトークンが一つしか用意されず、各開発者でトークンを共有して使用する必要がある場合、そのトークンはどのように共有するのでしょうか。
おそらくチームメンバーしか閲覧することのできないページなどに記載しておくか、チャットアプリのDMでやりとりするなどの方法が取られると思います。
しかしそれはセキュリティ的な観点からすればかなりグレーな方法だと思います。

1Password CLIを使うことで上記のリスクを回避できます。

  • .envに記載するものは参照パスであり、コミットして問題ない
  • トークンは1Passwordの保管庫で管理されているので安全
  • 共有するトークンは共有保管庫に保存すれば開発者間で利用可能

各開発者の実行前の.envのセットアップが不要になる

env-cmdの場合、.envはコミットされていないため、中身は各開発者がそれぞれ作成する必要があります。

しかし1Password CLIの場合は、.envに記載するものは参照パスであり、コミットして問題ありません。
つまり、アイテムが共有保管庫に保存されている場合、秘密参照が記載された.envをコミットしておけば、クローンしてきたら認証情報のセットアップすることなく、即座に実行可能です。

まとめ

本記事では 1Password CLI を利用することで、扱いに気を使う秘密情報をセキュアにそして便利に扱う方法を紹介しました。

開発中の秘密情報の扱いは開発者が常に神経を使う部分です。
1Password CLIを利用すれば秘密情報を格段に安全に扱えるだけでなく、開発者体験も向上して開発スピードが上がることも期待できます。

15
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?