AWS CLI で MFA 必須のスイッチロールで一度 MFA 認証を完了すると、 2 回目以降のコマンド実行では MFA コードの入力を求めらません。 なぜでしょうか。

この記事はアノテーション株式会社 AWS Technical Support Advent Calendar 2021のカレンダー | Advent Calendar 2021 - Qiita 13日目の記事です。

困っていた内容

AWS CLI で MFA 必須 の スイッチロールのアクセス制御を設定後、AWS S3 ls のコマンドを実行すると MFAコードの入力を求められました。
一度 MFA 認証を済ませると、 2 回目以降のコマンド実行では MFAコードの入力を求めらません。
なぜでしょうか。

どう対応すればいいの?

2 回目以降のコマンド実行では MFAコードの入力を求められないのは、一度 MFA 認証を完了すると、一時的な認証情報はキャッシュされ、一時的な認証情報の有効期限が切れるまで、AWS CLI はキャッシュされた一時的な認証情報を使用するからです。
キャッシュされた一時的な認証情報は ~/.aws/cli/cache に保存されます。

ロールを使用する際、AWS CLI は、有効期限が切れるまで一時的な認証情報をキャッシュします。次回この一時的な認証情報を使用しようとすると、AWS CLI はユーザーに代わってこの情報の更新を試みます。
ロールの一時的な認証情報が取り消された場合、それらは自動的には更新されず、使用しようとすると失敗します。ただし、キャッシュを削除して、AWS CLI で新しい認証情報を取得するように強制することができます。

AWS CLI 経由でスイッチロールした際、キャッシュされた一時的な認証情報のデフォルトの有効期限は 1 時間です。
2回目以降、MFA コードの入力を求められるようにするには、キャッシュされた一時的な認証情報を以下のコマンドでクリアするか有効期限が切れるまで待つ必要がございます。

Linux または macOS

$ rm -r ~/.aws/cli/cache

Windows

C:\> del /s /q %UserProfile%\.aws\cli\cache

やってみた

IAM ロールを MFA 必須でのアクセス制御を設定するには、以下の設定ファイルを記載します。

config ファイル

[profile user1]
region = ap-northeast-1
role_arn = arn:aws:iam::XXXXXXXXXXXX:role/test-user1 #スイッチロール先の IAM ロールの ARN を指定
source_profile = testuser
mfa_serial = arn:aws:iam::XXXXXXXXXXXX:mfa/test-user #スイッチ元の IAM ユーザーの MFA デバイスの ARN を指定

credentials ファイル

[testuser]
aws_access_key_id = <アクセスキー>
aws_secret_access_key = <シークレットアクセスキー>

その後、AWS S3 ls コマンドを実行します。

$ aws s3 ls --profile user1
Enter MFA code for arn:aws:iam::XXXXXXXXXXXX:role/test-user1: <MFA コードを入力>

2021-12-05 15:40:24 s3-bucket-test-user
2021-12-03 18:05:05 s3-bucket-test-user2

キャッシュされた一時的な認証情報を確認します。
有効期限が 1 時間と確認できます。(Expiration - date

$ date -u
Sun 11 Dec 2021 17:08:50 UTC 2021
$ cat ~/.aws/cli/cache/* | jq
{
    "Credentials": {
        "AccessKeyId": "ASIAxxx...",
        "SecretAccessKey": "Tqotaxxx...",
        "SessionToken": "Fogwxxx...",
        "Expiration": "2021-12-11T18:08:27Z" #一時的な認証情報の有効期限
    },
    "AssumedRoleUser": {
        "AssumedRoleId": "AROAYTKWZGUSS6HLXBT4P:botocore-session-123456789",
        "Arn": "arn:aws:sts::XXXXXXXXXXXX:assumed-role/test-user1/botocore-session-123456789"
    },
    "ResponseMetadata": {
        "RequestId": "2c90axxx...",
        "HTTPStatusCode": 200,
        "HTTPHeaders": {
            "x-amzn-requestid": "2c90axxx...",
            "content-type": "text/xml",
            "content-length": "1095",
            "date": "Sun, 11 Dec 2021 17:08:26 GMT" #認証された時間
        },
        "RetryAttempts": 0
    }
}

2回目の AWS S3 ls コマンドを実行します。 MFA コード入力なしで S3 ファイルを参照できます。

$ aws s3 ls --profile user1
2021-12-05 15:40:24 s3-bucket-test-user
2021-12-03 18:05:05 s3-bucket-test-user2

キャッシュをクリアして、AWS S3 ls コマンドを実行します。
一時的な認証情報は削除されているため、認証するために MFA コードの入力が求められます。

$ rm -r ~/.aws/cli/cache
$ aws s3 ls --profile user1
Enter MFA code for arn:aws:iam::XXXXXXXXXXXX:role/test-user1: <MFA コードを入力>

参考情報