🙌

実は難しい aws-vault (README 副読本) - 導入

2024/10/14に公開

目次

前置き

aws-vault は開発者のローカル環境上で AWS CLI や AWS SDK を扱う際にとても便利な CLI ツールですが、 AWS Security Token Service (STS) 周りの挙動の一部隠蔽していたり、 AWS CLI や AWS SDK だけを利用する場合とは異なる挙動をする部分もあり、 STS 周りの仕様を把握していないと何故そうなるのか理解できない事態に出くわします。

この一連の記事では、 aws-vault の実は難しいポイントをいくつか紹介します。

補足: 想定読者について

aws-vault は README.mdUSAGE.md が充実しているため、直接参照して問題なく理解できる場合はこの一連の記事は不要です。

この一連の記事は、 AWS 自体の仕様についても極力触れることで aws-vault の挙動を理解しやすくなることを意図しています。なので、以下に当てはまる人が README.mdUSAGE.md の副読本として利用することを想定しています。

用語

何度も出てくるので、あらかじめ用語についてまとめておきます。

Principal

AWS 上でアクションを実行する存在のこと。

要は 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

参考:

aws-vault の使い方 (多要素認証)

以下のように ~/.aws/configmfa_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/configcredential_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 を直接利用する場合も、プロファイルを指定して実行できるようにもなります。

main.py
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': {...}}

参考:

aws-vault の簡単な使い方紹介 (aws-vault login)

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