AWS CLIは~/.aws/credentials
に平文でクレデンシャルを保存します。簡単にクレデンシャルが確認できてしまうのでコンピューターにロックをかけないまま離席してしまった日には漏れていてもおかしくありません。そこでクレデンシャルを暗号化しシステムのキーストアに保存するAWS Vaultを使ってみます。
AWS Vault
AWS Vaultはシステムのキーストアにクレデンシャルを保存することでセキュリティを担保します。対応しているキーストアは以下から確認できます。
https://github.com/99designs/aws-vault?tab=readme-ov-file#vaulting-backends
個人的にpassに対応してるのが好印象ですね、これを見た時に使うことを決意しました。
使い方
使い方の詳細については公式ドキュメントをご覧ください。コマンドラインオプションや環境変数でも色々できそうです。
AWS Vaultにプロファイルを追加
aws-vault add
コマンドを実行するとキーIDやシークレットを聞かれるので入力します。dummy
という名前でプロファイルを追加してみます。
$ aws-vault add dummy
Enter Access Key ID: ABCDEFGHIJKLMNOP
Enter Secret Access Key: ****************************************
Added credentials to profile "dummy" in vault
初めて使用する場合はパスワードの設定を聞かれるので、キーストアに登録するパスワードを入力します。
もしパスワードがわからなくなってしまった場合は復旧することができない?と思うので、諦めて登録したDBを削除するしかない気がします。macOSの場合は↓です。
rm ~/Library/Keychains/aws-vault.keychain-db
Windowsは使ってないのでわかりません。
登録されているプロファイルを確認
aws-vault list
コマンドで登録されているプロファイルを確認できます。
$ aws-vault list
Profile Credentials Sessions
======= =========== ========
dummy dummy -
プロファイルを使ってコマンドを実行
登録されているプロファイルを使ってコマンドを実行するには
aws-vault exec <profile-name> -- command ...
を実行します。実行するコマンドの前に--
をつけているのは、実行するコマンドのコマンドラインオプションをAWS Vaultに取られないようにするためです。--
をAWS Vaultに渡すことで、あなたのコマンドラインオプションはここまでよっというのを伝えています。
$ aws-vault exec dummy -- aws sts get-caller-identity --output table
-----------------------------------------------------------------------------------
| GetCallerIdentity |
+--------------+----------------------------------------+-------------------------+
| Account | Arn | UserId |
+--------------+----------------------------------------+-------------------------+
| 123456789012| arn:aws:iam::123456789012:user/dummy | ABCDEFGHIJKLMNOPQRSTU |
+--------------+----------------------------------------+-------------------------+
AWS Vaultからクレデンシャルを取得するためにキーチェーンパスワードを求めてきます。パスワードを入力して「常に許可」としておけば次からは聞かれてないと思いますが、ロックをかけないまま離席したいのなら「許可」をポチって一時的に許可するのがいいかもしれません。私は離席するときに必ずロックをかけるので「常に許可」にしてあります。
プロファイルを恒久的に使用する
aws-vault exec
コマンドの引数に実行するコマンドを指定することで一時的に指定のプロファイルのアカウントを使用しました。しかし、すべてのコマンドでaws-vault exec
を先頭につけるのは少々手間です。そこでサブシェルを取得して、シェルを抜けるまでの間、指定のプロファイルでコマンドを実行できるようにします。
$ aws-vault exec dummy
Starting subshell /usr/local/bin/zsh, use `exit` to exit the subshell
$ aws sts get-caller-identity --output table
-----------------------------------------------------------------------------------
| GetCallerIdentity |
+--------------+----------------------------------------+-------------------------+
| Account | Arn | UserId |
+--------------+----------------------------------------+-------------------------+
| 123456789012| arn:aws:iam::123456789012:user/dummy | ABCDEFGHIJKLMNOPQRSTU |
+--------------+----------------------------------------+-------------------------+
サブシェルに入るとAWS_VAULT
という環境変数にプロファイル名が入ります。
exit
コマンドやCtrl-d
を押下するとサブシェル抜けられます。
クレデンシャルをローテートする
AWS Vaultにはクレデンシャルをローテートする機能も付属しています。
$ aws-vault rotate dummy
Rotating credentials stored for profile 'dummy' using master credentials (takes 10-20 seconds)
Creating a new access key
Created new access key ****************WXYZ
Deleted 1 sessions for playground
Deleting old access key ****************RSTU
Deleted old access key ****************RSTU
Finished rotating access key
もし↓のようなエラーが出たらIAMユーザーのMFAが有効になっているのかもしれません。
Rotating credentials stored for profile 'dummy' using a session from profile 'dummy' (takes 10-20 seconds)
Creating a new access key
aws-vault: error: rotate: Error creating a new access key: operation error IAM: CreateAccessKey, https response error
StatusCode: 403, RequestID: 1234abcd-56ef-78gh-9012-123456abcdef, api error InvalidClientTokenId: The security
token included in the request is invalid
--no-session
オプションをつけることでMFAの要求を回避し、ローテーションを実行できます。詳しくはこちら
$ aws-vault rotate --no-session dummy
プロファイルでAWSコンソールにログイン
これは特に説明できることはありません。
aws-vault login
を実行するとデフォルトブラウザが起動してAWSコンソールにログインできます。わざわざログイン画面に色々入力する必要がなくて結構便利です。
aws-vault login dummy
プロファイルを削除
不要になったプロファイルは削除できます。
$ aws-vault remove dummy
Delete credentials for profile "dummy"? (y|N) y
Deleted credentials.
$ aws-vault list
Profile Credentials Sessions
======= =========== ========
dummy - -
スイッチロール
複数のAWSアカウントを行ったり来たりするときにスイッチロールを使用できると便利ですよね。AWSコンソールは別のAWSアカウントにログインするときに今ログインしてるアカウントからログアウトさせられますが、スイッチロールを使用するとログイン、ログアウトが発生しません。
どこか1つのAWSアカウントでIAMユーザーを発行しておき、開発、ステージング、本番のAWSアカウントをスイッチロールできるようにしておくというような使い方も一般的です。AWS CLIもスイッチロールに対応しています。
~/.aws/config
に以下の記述をすることで、スイッチロールが可能です。
[profile dummy] region = ap-northeast-1 [profile switch-role] region = ap-northeast-1 source_profile = dummy role_arn = arn:aws:iam::123456789012:role/<role-name>
source_profile
にはスイッチロール元のプロファイルを、role_arn
にはスイッチロール先で設定されているRole ARNを記述します。しかし、スイッチロール元のアカウントがMFAを必須にするような制限を、スイッチロール先のロールに設定されている場合は↑の例だけではスイッチロールできません。例えば以下のように設定されている場合です。
MFA 保護 API アクセスの設定 - AWS Identity and Access Management
AWS VaultはMFAにも対応しています。
https://github.com/99designs/aws-vault/blob/master/USAGE.md#mfa
先ほどの~/.aws/config
を以下のように修正します。
[profile dummy] region = ap-northeast-1 [profile switch-role] region = ap-northeast-1 source_profile = dummy role_arn = arn:aws:iam::123456789012:role/<role-name> mfa_serial = arn:aws:iam::111111111111:mfa/<mfa-name>
role_arn
にはスイッチ先のロールARNを、mfa_serial
にはスイッチ元のIAMユーザーに登録されているMFAのARNを入力してください。こうすることで、switch-role
プロファイルでコマンドを実行するときにMFAの認証がされるので、スイッチロールが可能になります。
$ aws-vault exec switch-role aws sts get-caller-identity Enter MFA code for arn:aws:iam::111111111111:mfa/<mfa-name>: 123123 { "UserId": "ABCDEFGHIJKLMNOPQRSTU:1234567890123456789", "Account": "123456789012", "Arn": "arn:aws:sts::1234567890:assumed-role/<role-name>/1234567890123456789" }
まとめ
AWS Vaultなかなかいいですね。~/.aws/credentials
がなくなるのもいいですし、サブシェルでプロファイルを恒久的に使用できるのもいいです。なによりバックエンドにpassを指定できるのが、個人的にはベストヒットでした、pass好きなんですよね。
AWS Vaultこれから積極的に使っていこうと思います。