.env の代わりに aws-vault で安全に環境変数を与える — Claude Code 時代の AWS 認証情報管理
AI エージェントがローカルファイルを直接読み書きする時代、.env に平文で認証情報を置くリスクが顕在化しています。前回の記事では、この問題の背景と複数のシークレット管理ツールを紹介しました。
本記事では、AWS を利用しているチームに向けて、aws-vault を使って .env と ~/.aws/credentials を完全に排除する具体的な手順を解説します。
aws-vault が解決する問題
~/.aws/credentials の平文問題
AWS CLI を使う開発者の多くは、~/.aws/credentials にアクセスキーを平文で保存しています。
# ~/.aws/credentials(平文で保存されている)
[default]
aws_access_key_id = AKIAIOSFODNN7EXAMPLE
aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
このファイルには2つのリスクがあります。
- Claude Code が読み取れる: AI エージェントがファイルシステムを探索する際、
~/.aws/credentialsのアクセスキーが LLM のコンテキストに載る可能性がある - 長期的な認証情報が漏洩する: アクセスキーには有効期限がなく、漏洩した場合は手動でローテーションするまで悪用され続ける
aws-vault のアプローチ
aws-vault は以下の2段階で問題を解決します。
- 暗号化保存: アクセスキーを
~/.aws/credentialsではなく、OS のキーストア(macOS Keychain 等)に暗号化して保存する - 一時認証の生成: AWS STS(Security Token Service)を使って、1時間で失効する一時認証情報を生成し、子プロセスに注入する
[従来]
~/.aws/credentials(平文) → AWS CLI / boto3 が直接読み取り
→ 長期キーがメモリに残る
[aws-vault]
macOS Keychain(暗号化) → aws-vault が STS で一時認証を生成
→ 子プロセスに環境変数として注入
→ 1時間で失効
セットアップ
インストール
# macOS(推奨)
brew install --cask aws-vault
# macOS(Homebrew formula 版)
brew install aws-vault
# Linux
brew install aws-vault
# Windows
choco install aws-vault
# または
scoop install aws-vault
macOS では --cask 版が推奨されています。コード署名されているため、Keychain アクセス時の追加のパスワードプロンプトが少なくなります。
認証情報の登録
# プロファイルを追加(対話的にアクセスキーを入力)
$ aws-vault add my-profile
Enter Access Key ID: AKIAIOSFODNN7EXAMPLE
Enter Secret Access Key: ****
Added credentials to profile "my-profile" in vault
この時点で ~/.aws/credentials にはキーが書き込まれません。Keychain に暗号化保存されます。
登録できたことの確認
$ aws-vault list
Profile Credentials Sessions
======= =========== ========
my-profile my-profile -
~/.aws/credentials を削除
既に ~/.aws/credentials に平文キーがある場合は、aws-vault に移行後に削除します。
# まず aws-vault に登録
$ aws-vault add my-profile
# 動作確認
$ aws-vault exec my-profile -- aws sts get-caller-identity
# 確認できたら平文ファイルを削除
$ rm ~/.aws/credentials
基本的な使い方
コマンド実行
# AWS CLI コマンドを一時認証で実行
$ aws-vault exec my-profile -- aws s3 ls
# Django の開発サーバーを起動(boto3 が AWS にアクセスする場合)
$ aws-vault exec my-profile -- python manage.py runserver
# Terraform を実行
$ aws-vault exec my-profile -- terraform plan
aws-vault exec は内部で以下を行います。
- Keychain からアクセスキーを取得
- STS の
GetSessionTokenAPI を呼び出し、一時認証情報を生成 AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY、AWS_SESSION_TOKENを環境変数として設定- 指定したコマンドを子プロセスとして実行
子プロセスが終了すれば、一時認証情報は環境変数とともに消えます。
サブシェルで作業
コマンドを指定せずに実行すると、認証情報が設定されたサブシェルが起動します。
$ aws-vault exec my-profile
# サブシェル内で自由に作業
$ aws s3 ls
$ aws ec2 describe-instances
$ python manage.py shell
# 作業が終わったらサブシェルを終了
$ exit
複数の AWS コマンドを連続して実行する場合に便利です。
AWS コンソールにブラウザでログイン
$ aws-vault login my-profile
ブラウザが開き、一時認証情報で AWS マネジメントコンソールにログインできます。IAM ユーザーのパスワードを入力する必要がありません。
~/.aws/config の設定
aws-vault は ~/.aws/config(設定ファイル)を読み取ります。認証情報(credentials)ではなく設定(config)であるため、平文のキーは含まれません。
基本設定
# ~/.aws/config
[profile my-profile]
region = ap-northeast-1
output = json
MFA(多要素認証)の設定
IAM ユーザーに MFA を設定している場合、mfa_serial を追加します。
[profile my-profile]
region = ap-northeast-1
mfa_serial = arn:aws:iam::123456789012:mfa/my-user
$ aws-vault exec my-profile -- aws s3 ls
Enter MFA code for arn:aws:iam::123456789012:mfa/my-user: 123456
MFA コードを入力すると、セッションがキャッシュされます。セッションが有効な間(デフォルト1時間)は再入力不要です。
AssumeRole(ロール切り替え)の設定
開発環境と本番環境で異なる IAM ロールを使い分ける場合の設定です。
# ~/.aws/config
# ベースプロファイル
[profile base]
region = ap-northeast-1
mfa_serial = arn:aws:iam::123456789012:mfa/my-user
# 開発環境(base の認証情報で AssumeRole)
[profile dev]
source_profile = base
role_arn = arn:aws:iam::123456789012:role/dev-role
region = ap-northeast-1
# 本番環境(MFA 必須の AssumeRole)
[profile prod]
source_profile = base
role_arn = arn:aws:iam::123456789012:role/prod-role
region = ap-northeast-1
# 開発環境ロールで Terraform を実行
$ aws-vault exec dev -- terraform apply
# 本番環境ロールでデプロイ(MFA が求められる)
$ aws-vault exec prod -- ./deploy.sh
aws-vault が自動的に AssumeRole API を呼び出し、ロール切り替えを行います。
credential_process による AWS CLI との統合
aws-vault exec のラッパーなしで、通常の aws コマンドをそのまま使いたい場合は、credential_process を設定します。
# ~/.aws/config
[profile my-profile]
region = ap-northeast-1
credential_process = aws-vault export --format=json my-profile
# aws-vault exec なしで直接実行できる
$ aws s3 ls --profile my-profile
# boto3 を使うスクリプトもそのまま動く
$ AWS_PROFILE=my-profile python manage.py runserver
この設定により、AWS SDK(boto3 等)が認証情報を必要とする際に aws-vault が自動的に呼び出されます。
macOS では --prompt osascript オプションを追加すると、Keychain のパスワード入力がネイティブダイアログで表示されます。
credential_process = aws-vault export --format=json --prompt=osascript my-profile
Docker コンテナへの認証情報の受け渡し
ローカル開発で Docker コンテナ内のアプリケーションに AWS 認証情報を渡す方法です。
環境変数で渡す
# aws-vault が生成した一時認証情報をコンテナに渡す
$ aws-vault exec my-profile -- env | grep AWS > /tmp/aws-env
$ docker run --env-file /tmp/aws-env my-app
$ rm /tmp/aws-env
ただし、一時ファイルに認証情報が残るため、よりセキュアな方法を推奨します。
ECS ローカルエンドポイントで渡す(推奨)
aws-vault には、ECS コンテナが使う認証エンドポイントをローカルで再現する機能があります。
# ローカルに ECS 互換のメタデータサーバーを起動
$ aws-vault exec my-profile --ecs-server
# 別のターミナルで Docker コンテナを起動
$ docker run \
-e AWS_CONTAINER_CREDENTIALS_FULL_URI=http://host.docker.internal:9099/ecs \
my-app
この方法では、認証情報がファイルにも環境変数にも直接渡されません。コンテナ内の AWS SDK が HTTP 経由で一時認証情報を取得します。
キーローテーション
IAM のベストプラクティスでは、アクセスキーを90日ごとにローテーションすることが推奨されています。aws-vault ならコマンド一つで完了します。
$ aws-vault rotate my-profile
Rotating credentials stored for profile 'my-profile'
Created new access key ****NEWKEY
Deleted old access key ****OLDKEY
内部的には以下が行われます。
- 新しいアクセスキーを IAM に作成
- Keychain のキーを新しいものに更新
- 古いアクセスキーを IAM から削除
アプリケーションのシークレットとの組み合わせ
aws-vault は AWS 認証情報を守るツールです。アプリケーション固有のシークレット(データベースパスワード、API キー等)は、別途 AWS Secrets Manager から取得する構成が推奨されます。
一括注入スクリプト
#!/bin/bash
# scripts/dev-server.sh
# aws-vault + AWS Secrets Manager でシークレットを一括注入
set -euo pipefail
# AWS Secrets Manager からアプリケーションのシークレットを取得
SECRET_JSON=$(aws secretsmanager get-secret-value \
--secret-id "my-app/${ENV:-dev}/config" \
--query SecretString --output text)
# JSON の各キーを環境変数にエクスポート
eval $(echo "$SECRET_JSON" | jq -r 'to_entries[] | "export \(.key)=\(.value)"')
echo "Loaded secrets for environment: ${ENV:-dev}"
# 引数のコマンドを実行
exec "$@"
# 使い方:aws-vault でラップして実行
$ aws-vault exec dev -- ./scripts/dev-server.sh python manage.py runserver
この構成では以下の全てが平文ファイルから排除されます。
| 認証情報 | 保存場所 | 平文ファイル |
|---|---|---|
| AWS アクセスキー | macOS Keychain | なし |
| AWS 一時認証情報 | メモリ上のみ(1時間で失効) | なし |
| DB パスワード | AWS Secrets Manager | なし |
| 外部 API キー | AWS Secrets Manager | なし |
Makefile での統合
チーム全体で同じ方法を使えるよう、Makefile に定義しておくと便利です。
# Makefile
ENV ?= dev
PROFILE ?= $(ENV)
.PHONY: server migrate shell
server:
aws-vault exec $(PROFILE) -- ./scripts/dev-server.sh python manage.py runserver
migrate:
aws-vault exec $(PROFILE) -- ./scripts/dev-server.sh python manage.py migrate
shell:
aws-vault exec $(PROFILE) -- ./scripts/dev-server.sh python manage.py shell
deploy:
aws-vault exec prod -- ./scripts/deploy.sh
# チームメンバーは以下を実行するだけ
$ make server
$ make server ENV=stg
$ make deploy
Claude Code との共存
deny 設定
Claude Code が AWS 関連の認証ファイルを読み取らないよう、プロジェクトの .claude/settings.json に deny ルールを追加します。
{
"permissions": {
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(**/.aws/credentials)",
"Read(**/.aws/sso/cache/**)"
]
}
}
aws-vault 環境で Claude Code を使う
Claude Code 自体も aws-vault の子プロセスとして起動できます。Claude Code が AWS リソースにアクセスする必要がある場合(例: S3 バケットの内容を確認する等)に有効です。
# Claude Code に一時認証情報を渡して起動
$ aws-vault exec dev -- claude
ただし、Claude Code に AWS 認証情報を渡すこと自体がリスクになり得ます。必要な場合のみ使用し、通常は認証情報なしで起動することを推奨します。
トラブルシューティング
Keychain のパスワード入力が頻繁に求められる
macOS Keychain の「aws-vault」キーチェーンのロック時間を調整します。
- 「キーチェーンアクセス.app」を開く
- 左ペインで「aws-vault」キーチェーンを右クリック
- 「“aws-vault” の設定を変更」を選択
- 「操作がない状態が XX 分続いたらロック」の時間を調整
セッション期限切れ
デフォルトのセッション期限は1時間です。長時間の作業では、環境変数でカスタマイズできます。
# セッション時間を8時間に延長
$ AWS_SESSION_TOKEN_TTL=8h aws-vault exec my-profile -- python manage.py runserver
# ~/.zshrc に設定しておくことも可能
export AWS_SESSION_TOKEN_TTL=4h
ただし、セッション時間を長くするほどセキュリティリスクは増加します。
—no-session オプション
一部の IAM 操作(アクセスキーのローテーション等)は一時認証情報では実行できません。その場合は --no-session を使いますが、長期キーがそのまま使われるためセキュリティリスクが高くなります。通常の開発では使用を避けてください。
# 特別な場合のみ使用(長期キーが直接使われる)
$ aws-vault exec my-profile --no-session -- aws iam list-access-keys
まとめ
- ~/.aws/credentials を廃止: aws-vault でアクセスキーを OS Keychain に暗号化保存し、平文ファイルを排除する
- 一時認証情報で作業: STS が生成する1時間で失効する認証情報のみを使い、漏洩リスクを限定する
- credential_process で透過的に統合:
aws-vault execのラッパーなしで、通常の AWS CLI や boto3 をそのまま使える - AssumeRole で環境分離: dev / stg / prod を IAM ロールで切り替え、本番アクセスには MFA を必須にする
- AWS Secrets Manager と組み合わせる: アプリケーションのシークレットは Secrets Manager に集約し、一括注入スクリプトで管理する
- Makefile でチーム標準化:
make server一つで安全にローカル開発サーバーを起動できる環境を整備する - Claude Code の deny 設定:
~/.aws/credentialsと.envへのアクセスを拒否し、多層防御を実現する
参考
- aws-vault - GitHub
- aws-vault Usage Guide
- aws-vaultの使い方 - atsum.in
- aws-vault について - Zenn
- VS Code Remote Containers で aws-vault を使う - dely Tech Blog
- aws-vaultの使い方と仕組み - Qiita
- AWS Vaultで端末内のAWSアクセスキー平文保存をやめてみた - DevelopersIO
- aws-vault のすすめ - sreake.com
- Claude Code 時代の .env 管理(関連 Gist)
- AWS Secrets Manager Documentation
- Using AWS Secrets Manager with ECS