[小ネタ] スイッチロールのMFA必須条件にBoolIfExistsを使ってAWS CLIアクセスをストレスフリーにする

こんにちは。サービスグループの武田です。AWS CLIで「MFAが必要」のオプションにチェックを入れたロールを使用する際にMFAの入力を求められるのが煩わしかったりしませんか?少し設定を変更するだけで解決できますのでその方法をお届けします。
2020.05.11

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

こんにちは。サービスグループの武田です。

AWSアカウントを複数人で使用する場合、IAMユーザーやIAMロールを人数分作成しますよね。AWSのベストプラクティスとしてはIAMロールを使用することが推奨されます。さてIAMロールをマネジメントコンソールで作成する際に、次のようなオプションにチェックを入れているでしょうか?

この「MFAが必要」のオプションにチェックを入れることでMFAの設定を強制できよりセキュアになります。ところがスイッチ元のIAMユーザーでアクセスキーを発行し、このIAMロールを使用しようとするとやや面倒なことになります。

testプロファイルとして「MFAが必要」にチェックをしたロールを設定してAWS CLIで適当なAPIをたたくとエラーになります。

$ aws --profile test ec2 describe-regions | head

An error occurred (AccessDenied) when calling the AssumeRole operation: User: arn:aws:iam::123456789012:user/cm-testuser is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::123456789034:role/test

回避方法はいくつか考えられるのですが、今回は信頼関係の条件を変更する方法を紹介します。

BoolIfExists演算子を利用する

まず先に結論ですが、信頼関係のポリシードキュメントを次のように修正するだけです。

$ diff -u assume-role-policy.origin.json assume-role-policy.new.json
--- assume-role-policy.origin.json	2020-05-11 00:00:00.000000000 +0900
+++ assume-role-policy.new.json	2020-05-11 00:00:00.000000000 +0900
@@ -8,7 +8,7 @@
       },
       "Action": "sts:AssumeRole",
       "Condition": {
-        "Bool": {
+        "BoolIfExists": {
           "aws:MultiFactorAuthPresent": "true"
         }
       }

これによってMFAの入力が不要となります。

$ aws --profile test ec2 describe-regions | head
{
    "Regions": [
        {
            "Endpoint": "ec2.eu-north-1.amazonaws.com",
            "RegionName": "eu-north-1",
            "OptInStatus": "opt-in-not-required"
        },
        {
            "Endpoint": "ec2.ap-south-1.amazonaws.com",
            "RegionName": "ap-south-1",

BoolIfExistsについて補足

今回の方法は次のドキュメントに記載されています。

そもそもaws:MultiFactorAuthPresentという条件キーは、リクエストを行ったプリンシパルがMFAを使用したかのチェックをするものです。しかしリクエストコンテキストに必ずこのキーが含まれているかというとそうではなく、アクセスキーを使用したAWS CLI、AWS API、またはAWS SDKリクエストには含まれません。そこでリクエストコンテキストについて キーが存在しかつMFAを使用している または キーが存在しない 場合にスイッチロールを許可できれば、一定のセキュリティを担保しつつ利便性を確保できます。そう、それがまさしく今回紹介した設定なのでした。

{
  ...
      "Effect": "Allow",
      ...
      "Condition": {
        "BoolIfExists": {
        "aws:MultiFactorAuthPresent": "true"
      }
  ...
}

まとめ

AWS CLIでの操作時にMFAを求められるのが煩わしかった方はこの方法も検討してみてください。