実は難しい aws-vault (README 副読本) - 導入
目次
- イマココ ⇒ 実は難しい aws-vault (README 副読本) - 導入
- 🚧 工事中 🚧 実は難しい aws-vault (README 副読本) - credential_process 編
- 🚧 工事中 🚧 実は難しい aws-vault (README 副読本) - 長時間実行編
- 🚧 工事中 🚧 実は難しい aws-vault (README 副読本) - Dev Container 編
- 🚧 工事中 🚧 実は難しい aws-vault (README 副読本) - aws-vault login 編
前置き
aws-vault は開発者のローカル環境上で AWS CLI や AWS SDK を扱う際にとても便利な CLI ツールですが、 AWS Security Token Service (STS) 周りの挙動の一部隠蔽していたり、 AWS CLI や AWS SDK だけを利用する場合とは異なる挙動をする部分もあり、 STS 周りの仕様を把握していないと何故そうなるのか理解できない事態に出くわします。
この一連の記事では、 aws-vault の実は難しいポイントをいくつか紹介します。
補足: 想定読者について
aws-vault は README.md や USAGE.md が充実しているため、直接参照して問題なく理解できる場合はこの一連の記事は不要です。
この一連の記事は、 AWS 自体の仕様についても極力触れることで aws-vault の挙動を理解しやすくなることを意図しています。なので、以下に当てはまる人が README.md や USAGE.md の副読本として利用することを想定しています。
- AWS CLI や AWS SDK を利用している。
- IAM, STS 周りは雰囲気で利用している。
- IAM ユーザ、 IAM ロール、 IAM ポリシーがそれぞれどのような概念かはわかる。
- AssumeRole がどのようなアクションかなんとなく理解しており、利用している。
- 多段 AssumeRole や多要素認証周りは
~/.aws/config
を見様見真似で設定して動いているが、あまり細かいことは理解していない。 - GetSessionToken, GetFederationToken アクションについてよく知らない。
用語
何度も出てくるので、あらかじめ用語についてまとめておきます。
Principal
AWS 上でアクションを実行する存在のこと。
- AssumeRole 後のセッションも Principal の一種。
- 参考: Compare IAM identities and credentials - AWS Identity and Access Management
要は IAM ポリシー上の Principal キーに設定できるものが Principal 。
一時的セキュリティ認証情報
IAM ユーザの長期的な認証情報(要は、アクセスキーIDとシークレットアクセスキーの組)とは異なる、一時的に発行される認証情報。
AssumeRole アクションにより生成される認証情報も、一時的セキュリティ認証情報の一つ。
リクエストコンテキスト
プリンシパルが AWS にリクエストを送る際、 AWS がまとめるリクエストに関する情報のこと。
このリクエストコンテキスト内の各情報に紐づくキーとして、グローバル条件キーなどがある。
前提とする構成・環境
この一連の記事では、以下のような構成を前提に話を進めます。
補足事項
- Jump アカウントを利用したマルチアカウント構成。
- 多要素認証を強制する設定は IAM ユーザのアイデンティティベースポリシーでのみ行っている(なので、 IAM ロールの信頼ポリシー側では
aws:MultiFactorAuthPresent
に関する制限はしていない)。 - 多要素認証のデバイスには、仮想認証アプリケーション (例: Google Authenticator)を利用。
また、ローカル環境としては以下の環境を仮定しています(一連の記事中の AWS SDK を利用するサンプルコードは Python で記述します)。
- aws-cli 2.15.40
- aws-vault v7.2.0
- Python 3.12.2
- boto3 1.34.89
そもそも aws-vault とは?
aws-vault ではアクセスキーを平文ファイル (~/.aws/credentials
) 上ではなく、各 OS のキーストア(例: macOS の場合はキーチェーンアクセス)上で管理することができ、うっかり GitHub リポジトリにアクセスキーを漏洩してしまうといった事故を避けることができます。
その他にも、認証周りで色々便利な機能が存在しています。以下、 aws-vault の使い方についての簡単な紹介になります。
aws-vault の使い方 (基本)
aws-vault は以下のような流れで利用することができます。
# プロファイルに対応するアクセスキーを追加
aws-vault add jump-account
# 指定したプロファイルに対応する認証情報などを環境変数に設定し、サブプロセスとしてコマンド実行
aws-vault exec jump-account -- aws sts get-caller-identity
# 明示的に認証情報を環境変数の形で取得することも可能(以下のような文字列が標準出力に出力される)
# export AWS_ACCESS_KEY_ID=...
# export AWS_SECRET_ACCESS_KEY=...
# ...
aws-vault export --format=export-env jump-account
参考:
- Quick start - aws-vault/README.md at v7.2.0 · 99designs/aws-vault
- How it works - aws-vault/README.md at v7.2.0 · 99designs/aws-vault
aws-vault の使い方 (多要素認証)
以下のように ~/.aws/config
に mfa_serial
の設定を追加することで、 AWS CLI のみを利用するときと似た使用感で、多要素認証に対応することができます。
~/.aws/config
[profile common]
mfa_serial = arn:aws:iam::111111111111:mfa/jonsmith
[profile jump-account]
region = ap-northeast-1
include_profile = common
[profile system-foo]
region = ap-northeast-1
include_profile = common
role_arn = arn:aws:iam::22222222222:role/jonsmith
role_session_name = jonsmith
source_profile = jump-account
[profile system-foo-admin]
region = ap-northeast-1
role_arn = arn:aws:iam::22222222222:role/admin
role_session_name = jonsmith
source_profile = system-foo
$ aws-vault exec system-foo-admin -- aws sts get-caller-identity
Enter MFA code for arn:aws:iam::111111111111:mfa/jonsmith: ******
{
"UserId": "AROAXXXXXXXXXXXXXXX",
"Account": "22222222222",
"Arn": "arn:aws:sts::22222222222:assumed-role/admin/jonsmith"
}
参考:
aws-vault の使い方 (credential_process)
~/.aws/config
に credential_process
の設定を追加することで、 AWS CLI のみを利用するときと同じコマンドで実行できます。
~/.aws/config
[profile common]
mfa_serial = arn:aws:iam::111111111111:mfa/jonsmith
[profile jump-account]
region = ap-northeast-1
include_profile = common
# 以下の設定を追加 (osascript の箇所は OS に合わせて変更すること)
credential_process=aws-vault export --prompt=osascript --format=json jump-account
[profile system-foo]
region = ap-northeast-1
include_profile = common
role_arn = arn:aws:iam::22222222222:role/jonsmith
role_session_name = jonsmith
source_profile = jump-account
[profile system-foo-admin]
region = ap-northeast-1
role_arn = arn:aws:iam::22222222222:role/admin
role_session_name = jonsmith
source_profile = system-foo
$ aws --profile system-foo-admin sts get-caller-identity
{
"UserId": "AROAXXXXXXXXXXXXXXXXX:jonsmith",
"Account": "22222222222",
"Arn": "arn:aws:sts::22222222222:assumed-role/admin/jonsmith"
}
また、 AWS SDK を直接利用する場合も、プロファイルを指定して実行できるようにもなります。
import boto3
session = boto3.Session(profile_name="system-foo-admin")
print(session.client("sts").get_caller_identity())
$ python main.py
{'UserId': 'AROAXXXXXXXXXXXXXXXXX:jonsmith', 'Account': '22222222222', 'Arn': 'arn:aws:sts::22222222222:assumed-role/admin/jonsmith', 'ResponseMetadata': {...}}
参考:
- Using credential_process - aws-vault/USAGE.md at v7.2.0 · 99designs/aws-vault
- Sourcing credentials with an external process in the AWS CLI - AWS Command Line Interface
aws-vault login
)
aws-vault の簡単な使い方紹介 (aws-vault login {プロファイル名}
と実行することで、 AWS マネジメントコンソール上のログイン画面やスイッチロール画面を経由せずに、コマンド一発で AWS マネジメントコンソールにログインすることができる。例えば、 aws-vault login system-foo-admin
を実行することで、ロールセッション arn:aws:sts::22222222222:assumed-role/admin/jonsmith
として AWS マネジメントコンソールにログインすることができる。
AWS マネジメントコンソール上のスイッチロール画面では、 IAM ロールから IAM ロールへの AssumeRole には対応していないので、そのような多段 AssumeRole を要求する IAM ロールを AWS マネジメントコンソール上で扱うにはかなり便利です。
参考:
Discussion