[小ネタ] remind101/assume-role の AWS_SECURITY_TOKEN を削除する

ツールに歴史あり
2021.10.04

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

ちゃだいん(@chazuke4649)です。

AWS_SECURITY_TOKEN が何者なのか?を知らなく地味にハマったことがあり、解決したのでブログで紹介します。

背景

AWS CLI や Terraform CLI を使用する際のAWS認証情報の渡し方はいろんな方法がありますが、普段自分はよく remind101/assume-role(以降assume-role) を使っています。

最終更新履歴がだいぶ古いんですが、今のところは問題なく使えています。

問題

一時クレデンシャルは一定時間過ぎると失効するので、一定時間後は再度設定する必要があります。また、もちろん他のAWSアカウントに対して作業したい場合、他のAWSアカウントの一時クレデンシャルを設定し直す必要があります。

これ自体は問題ないのですが、その時さらに assume-role でなく、他の方法で一時クレデンシャルを環境変数に渡した場合(例えば AWS SSO のユーザー画面で表示される環境変数をコピペする等)、エラーが起きました。

% aws sts get-caller-identity

An error occurred (InvalidClientTokenId) when calling the GetCallerIdentity operation: The security token included in the request is invalid.

原因

エラー文には「セキュリティトークンが無効」と書かれています。どういうことかと言うと、環境変数 AWS_SECURITY_TOKEN に古い一時クレデンシャルの情報が残っているためでした。

詳しくは以下ブログでAWS_SECURITY_TOKENとは何なのか?AWS_SESSION_TOKENと何が違うの?も含め、わかりやすく解説されていますのでご一読を。

AssumeRoleで取得した一時クレデンシャルの情報を環境変数にセットしてもAWS認証が通らずハマった話 | DevelopersIO

上記ブログでは aws-vault というツールですがassume-role も同様で、コマンドを実行すると一時クレデンシャルを取得し、見慣れた環境変数 AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY,AWS_SESSION_TOKENの他に、AWS_SECURITY_TOKENへも渡されます。

$ assume-role prod
export AWS_ACCESS_KEY_ID="ASIAI....UOCA"
export AWS_SECRET_ACCESS_KEY="DuH...G1d"
export AWS_SESSION_TOKEN="AQ...1BQ=="
export AWS_SECURITY_TOKEN="AQ...1BQ=="
export ASSUMED_ROLE="prod"

AWS_SECURITY_TOKENAWS_SESSION_TOKENへ一本化することが2014年に決定し、以降AWS_SECURITY_TOKENは基本使用しなくなりました。なので結果最近の手法ではAWS_SECURITY_TOKENを考慮しておらず(それはそれで正しいのですが)、それらで他環境変数を更新できていてもAWS_SECURITY_TOKENだけ古いまま残ってしまっていた、ということでした。

解決

超シンプルですが、reset AWS_SECURITY_TOKENコマンドで古い環境変数を削除するだけです。

実際には、シェルの設定ファイルのaliasで他コマンドと組み合わせているので、zshrcを修正します。(以下例はzshです)

~/.zshrc

alias assume-role='function(){eval $(command assume-role $@) && unset AWS_SECURITY_TOKEN;}'

これにより、assume-roleで渡される環境変数は以下となります。

% env | grep AWS
AWS_ACCESS_KEY_ID=xxxxx
AWS_SECRET_ACCESS_KEY=xxxxx
AWS_SESSION_TOKEN=xxxxx

おまけ

ちなみに、本件とは関係ないですが、普段assume-role実行後は確認としてaws sts get-caller-identityも叩いてるので、それもaliasに含めています。

~/.zshrc

alias assume-role='function(){eval $(command assume-role $@) && unset AWS_SECURITY_TOKEN && aws sts get-caller-identity;}'

参考URL

AssumeRoleで取得した一時クレデンシャルの情報を環境変数にセットしてもAWS認証が通らずハマった話 | DevelopersIO

assume-roleでプロファイルに対応していないツールでもassume roleする | DevelopersIO

【小ネタ】remind101/assume-roleのduration機能について 〜assume-roleツールの比較もあるよ〜 | DevelopersIO

AWS Vaultで端末内のAWSアクセスキー平文保存をやめてみた | DevelopersIO