
credential_processと1Password CLIでawsumeと共存できるセキュアな認証環境を作る
はじめに
こんにちは、アノテーション株式会社 LINE/アプリDevOpsチームの草竹です。
普段、AWS CLIを利用する際、~/.aws/credentials にアクセスキーやシークレットアクセスキーを保存している方は多いと思います。しかし、重要な認証情報をローカルディスクに平文で保存しておくのは、セキュリティ的に少し不安に思ったことはないでしょうか?
この解決策として 1Password の公式AWSプラグイン が提供されています。公式から提供された素晴らしいツールであり、とても便利なのですが、これは aws コマンドをラップ(エイリアス化)する仕組みのため、 AWSume などのサードパーティ製スイッチロールツールと相性が悪い課題がありました。
私は AWSume の入力補完や使い勝手が手放せなかったので、「AWSume を使い続けつつ、認証情報は1Passwordの中にだけ保存する(ローカルには平文で置かない)」 方法を模索しました。
今回は、AWS CLI標準の credential_process 機能と 1Password CLI (op) を組み合わせ、それを実現する自作スクリプトを紹介します。
実現したこと
- セキュア: ローカルの
~/.aws/credentialsにアクセスキー(平文)を一切保存しない。 - 共存: 公式プラグインを使わないため、awsume がそのまま動く(補完も効く)。
- 快適: MFA認証を通した後、セッションを1Password上にキャッシュし、有効期限内ならMFA入力をスキップする。
前提条件
環境
| 項目 | 値 |
|---|---|
| OS | macOS 15.7.2 |
| シェル | zsh |
コマンド
| 項目 | バージョン | 補足 |
|---|---|---|
op (1Password CLI) |
2.32.0 | |
jq |
jq-1.7.1-apple | |
aws-cli (AWS CLI v2) |
2.32.17 | |
awsume |
4.5.4 | ※任意ですが、この記事のモチベーションです |
仕組みの概要
credential_process は、AWS CLIが認証情報を必要とした際に外部プロセスを実行し、その標準出力(JSON)を受け取って認証に利用する機能です。これは awsume 等のツールからも透過的に利用されます。
今回は以下のフローで動作するスクリプトを作成しました。
- キャッシュ確認: 1Password上の独自フィールドに有効な一時クレデンシャルが保存されているか確認。
- (キャッシュ有効時): そのままJSONとして出力して終了。
- (キャッシュ無効時):
- 1PasswordからアクセスキーとMFAデバイスARNを取得。
op item get --otpでMFAコードを取得(またはユーザー入力)。aws sts get-session-tokenを実行。- 取得した一時クレデンシャルを1Passwordに書き込んでキャッシュ化。
- JSONとして出力。
実践:設定手順
1. 1Password にアイテムを作成
まず、1PasswordにAWS認証情報用のアイテムを作成します。

アイテム基本項目
| 項目 | 例 | 補足 |
|---|---|---|
| カテゴリ | API認証情報 | どのカテゴリを選択するは任意です |
| アイテム名 | AWS Access Key | アイテム名は任意です |
フィールド
1Passwordアイテムに登録するフィールドの項目名は自由ですが、1Passwordの公式AWSプラグイン はAccess Key ID, Secret Access Key, mfa serial として設定項目を期待しているため、以下項目名で登録していると、1Password公式プラグインに流用しやすく便利だと思います。
| 項目 | 例 | 補足 |
|---|---|---|
Access Key ID |
AKIAIOSFODNN7EXAMPLE | AWS のアクセスキーです。 |
Secret Access Key |
wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY | AWSのシークレットアクセスキーです。 |
mfa serial |
arn:aws:iam::123456789012:role/your-name | MFAシリアルのARNです。 |
one-time password |
******************** | MFAシリアルと対応するワンタイムパスワードを生成するための文字列です |
session_cache |
空で作成。ここにスクリプトがキャッシュを書き込みます。 |
2. 認証スクリプトの作成
~/.aws/get-1password-creds.sh を作成し、実行権限を付与します。
下記項目にセットする値(1Passwordアイテムに設定しているフィールド名)はご自身の環境に合わせて変更してください。
- OP_ITEM
- OP_ITEM_LABEL_CACHE
- OP_ITEM_LABEL_ACCESS_KEY
- OP_ITEM_LABEL_SECRET_KEY
- OP_ITEM_LABEL_MFA_SERIAL
#!/bin/bash
set -e
# --- 設定 ---
# 1Password のアイテム名
OP_ITEM="AWS Access Key"
# キャッシュを保存するフィールドラベル
OP_ITEM_LABEL_CACHE="session_cache"
OP_ITEM_LABEL_ACCESS_KEY="Access Key ID"
OP_ITEM_LABEL_SECRET_KEY="Secret Access Key"
OP_ITEM_LABEL_MFA_SERIAL="mfa serial"
# --- 0. 環境変数を完全にクリア ---
# 親プロセス等の環境変数が邪魔をしないようクリアします
unset AWS_ACCESS_KEY_ID
unset AWS_SECRET_ACCESS_KEY
unset AWS_SESSION_TOKEN
unset AWS_SECURITY_TOKEN
unset AWS_PROFILE
# --- 1. 1Password からアイテム情報を一括取得 ---
# キャッシュもクレデンシャルも同じアイテムにあるので、最初に1回取得するだけで済む
OP_JSON=$(op item get "$OP_ITEM" --format json)
# --- 2. キャッシュの確認 ---
# 指定フィールドの値を取得(なければ空)
ENCODED_CACHE=$(echo "$OP_JSON" | jq -r --arg label "$OP_ITEM_LABEL_CACHE" '.fields[] | select(.label==$label).value // empty')
if [ -n "$ENCODED_CACHE" ]; then
# Base64デコード
DECODED_CACHE=$(echo "$ENCODED_CACHE" | base64 -d 2>/dev/null || echo "")
if [ -n "$DECODED_CACHE" ]; then
CURRENT_TIME=$(date +%s)
# 有効期限チェック (+00:00 -> Z 置換含む)
IS_VALID=$(echo "$DECODED_CACHE" | jq -r --argjson now "$CURRENT_TIME" '
if .Credentials.Expiration then
(.Credentials.Expiration | sub("\\+00:00$"; "Z") | sub("\\.[0-9]+Z$"; "Z") | fromdateiso8601) > ($now + 30)
else
false
end
')
if [ "$IS_VALID" = "true" ]; then
# キャッシュ有効 -> そのまま出力して終了
echo "$DECODED_CACHE" | jq '{Version: 1, AccessKeyId: .Credentials.AccessKeyId, SecretAccessKey: .Credentials.SecretAccessKey, SessionToken: .Credentials.SessionToken, Expiration: .Credentials.Expiration}'
exit 0
fi
fi
fi
# --- 3. キャッシュがない/切れそうな場合は新規取得 ---
# (キャッシュ切れ時の処理)
ACCESS_KEY=$(echo "$OP_JSON" | jq -r --arg label "$OP_ITEM_LABEL_ACCESS_KEY" '.fields[] | select(.label==$label).value')
SECRET_KEY=$(echo "$OP_JSON" | jq -r --arg label "$OP_ITEM_LABEL_SECRET_KEY" '.fields[] | select(.label==$label).value')
MFA_SERIAL=$(echo "$OP_JSON" | jq -r --arg label "$OP_ITEM_LABEL_MFA_SERIAL" '.fields[] | select(.label==$label).value')
# MFAコード取得
MFA_CODE=$(op item get "$OP_ITEM" --otp)
if [ -z "$ACCESS_KEY" ] || [ -z "$SECRET_KEY" ] || [ -z "$MFA_CODE" ]; then
echo "Error: Failed to retrieve credentials from 1Password." >&2
exit 1
fi
# --- 4. AWS STS 実行 ---
export AWS_ACCESS_KEY_ID="$ACCESS_KEY"
export AWS_SECRET_ACCESS_KEY="$SECRET_KEY"
OUTPUT=$(aws sts get-session-token \
--serial-number "$MFA_SERIAL" \
--token-code "$MFA_CODE" \
--output json 2>&1)
STATUS=$?
if [ $STATUS -ne 0 ]; then
echo "Error calling aws sts get-session-token:" >&2
echo "$OUTPUT" >&2
exit 1
fi
# --- 5. 1Password にキャッシュを保存 (書き込み) ---
# JSONをBase64エンコード
ENCODED_OUTPUT=$(echo "$OUTPUT" | base64)
# op item edit でフィールドを更新 (タイプは 'password' にしてUI上は隠す)
op item edit "$OP_ITEM" "$OP_ITEM_LABEL_CACHE[password]=$ENCODED_OUTPUT" >/dev/null 2>&1
# credential_process 用に出力
echo "$OUTPUT" | jq '{Version: 1, AccessKeyId: .Credentials.AccessKeyId, SecretAccessKey: .Credentials.SecretAccessKey, SessionToken: .Credentials.SessionToken, Expiration: .Credentials.Expiration}'
3. ~/.aws/config の設定
~/.aws/credentials にある固定のアクセスキー定義は削除し、~/.aws/config に credential_process を記述します。
credentials ファイル自体を空にできるため、誤って平文キーが漏洩するリスクをゼロにできます。
[default]
region = ap-northeast-1
credential_process = /Users/your-name/.aws/get-1password-creds.sh
[profile project-a-role]
role_arn = arn:aws:iam::999999999999:role/ProjectARole
source_profile = default
# defaultプロファイル側でMFA済みのため、ここには mfa_serial を書かないのがポイントです!
4. 競合する設定の解除
1Password公式プラグインなどが有効になっていると競合するため、無効化しておきます。
op plugin clear aws
.zshrc などにある source .../plugins.sh もコメントアウト or 削除します。
# source /Users/your-name/.config/op/plugins.sh
検証:awsume でスイッチしてみる
設定が完了したので、awsume を使ってロールスイッチしてみます。
awsume project-a-role

初回実行時:
1Passwordへのアクセス許可(指紋認証など)が求められ、その後バックグラウンドで sts get-session-token が走ります。
2回目以降(キャッシュ有効期間内):
awsume を実行すると、即座にスイッチが完了します! sts APIを叩かないため非常に高速です。
「認証情報の管理は1Passwordに任せたいけど、CLIの操作感は変えたくない」という私のニーズにハマりました。
まとめ
credential_process を活用することで、認証情報の保存場所を1Passwordに一本化しつつ、awsume 等のツールとも共存できる環境が作れました。
- メリット
- セキュリティ向上: 平文のアクセスキーがローカルディスクに一切残らない。
- ツール互換性: AWS CLI標準の仕組みを使うため、
awsumeなど既存のエコシステムを壊さない。
- 注意点:
op item editでのキャッシュ書き込み時に若干の待ち時間が発生する。
公式プラグインの競合に悩んでいた方は、ぜひ試してみてください!
最後までご覧いただき、ありがとうございました!
参考
- Use 1Password to authenticate the AWS CLI with biometrics | 1Password Developer
- Use 1Password as an authenticator for sites with two-factor authentication | 1Password Support
- Get started with 1Password CLI | 1Password Developer
- AWSume: AWS Assume Made Awesome! | AWSume
- プロセス認証情報プロバイダー - AWS SDK とツール
アノテーション株式会社について
アノテーション株式会社はクラスメソッドグループのオペレーション専門特化企業です。
サポート・運用・開発保守・情シス・バックオフィスの専門チームが、最新 IT テクノロジー、高い技術力、蓄積されたノウハウをフル活用し、お客様の課題解決を行っています。
当社は様々な職種でメンバーを募集しています。
「オペレーション・エクセレンス」と「らしく働く、らしく生きる」を共に実現するカルチャー・しくみ・働き方にご興味がある方は、アノテーション株式会社 採用サイト をぜひご覧ください。







