AWS
IAM

[AWS] IAMユーザーにMFA(多要素認証)を強要するポリシー

目的

IAMのベストプラクティス にもある通り、IAMユーザーのMFA有効化はセキュリティ強化に有効です。
なので必ず有効化するようにしたいところですが、ルール化しても面倒だと思ってやらなかったり、新しいユーザーが増えると伝え漏れたりしがち。

徹底するにはルールよりも仕組み。
MFA有効化しないとAWSを使えないようにしてみます。

方法

AWSマネジメントコンソールの仕様上、MFAを有効化していないユーザーをログインではじくということはできません。
ですので「MFAで認証していない場合に全権限を禁止」という方法を取ります。そういうポリシーをユーザーに付与します。

ポリシー例

MFAなしのときは、全てを禁止する

下記ポリシーを付与すると、MFAなしでログインしたときに何もできなくなります。

policy
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Deny",
      "Action": [
        "*"
      ],
      "Resource": "*",
      "Condition": {
        "BoolIfExists": {
          "aws:MultiFactorAuthPresent": "false"
        }
      }
    }
  ]
}

Conditionaws:MultiFactorAuthPresent: false で、MFAされたかどうかを判断します。簡単だね!

…と言いたいところですが、このポリシーだとMFAの初回設定もできませんし、初回ログイン時のパスワード変更もできません。
パスワード・MFAを設定してから、このMFA必須ポリシーと本来必要な権限を付与する という手順を踏む必要があります。

MFAなしのときは、MFA設定とパスワード変更のみ許可

先の問題を解消するためのポリシーです。
下記のような権限構成となります。

  • 自分自身のMFA設定とパスワード変更のみ常に許可。
  • それ以外の操作は、MFA認証していないときは禁止。
    MFA認証されたときの権限は任意(この他に設定されているポリシーによる)
policy
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "iam:ListUsers",
        "iam:ListVirtualMFADevices",
        "iam:ListMFADevices"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "iam:EnableMFADevice",
        "iam:ResyncMFADevice",
        "iam:DeleteVirtualMFADevice",
        "iam:CreateVirtualMFADevice",
        "iam:DeactivateMFADevice",
        "iam:ChangePassword",
        "iam:CreateLoginProfile",
        "iam:DeleteLoginProfile",
        "iam:GetLoginProfile",
        "iam:UpdateLoginProfile"
      ],
      "Resource": [
        "arn:aws:iam::*:mfa/${aws:username}",
        "arn:aws:iam::*:user/${aws:username}"
      ]
    },
    {
      "Effect": "Deny",
      "NotAction": [
        "iam:ListUsers",
        "iam:ListVirtualMFADevices",
        "iam:ListMFADevices",
        "iam:EnableMFADevice",
        "iam:ResyncMFADevice",
        "iam:DeleteVirtualMFADevice",
        "iam:CreateVirtualMFADevice",
        "iam:DeactivateMFADevice",
        "iam:ChangePassword",
        "iam:CreateLoginProfile",
        "iam:DeleteLoginProfile",
        "iam:GetLoginProfile",
        "iam:UpdateLoginProfile"
      ],
      "Resource": "*",
      "Condition": {
        "BoolIfExists": {
          "aws:MultiFactorAuthPresent": "false"
        }
      }
    },
    {
      "Effect": "Deny",
      "Action": [
        "iam:EnableMFADevice",
        "iam:ResyncMFADevice",
        "iam:DeleteVirtualMFADevice",
        "iam:CreateVirtualMFADevice",
        "iam:DeactivateMFADevice",
        "iam:ChangePassword",
        "iam:CreateLoginProfile",
        "iam:DeleteLoginProfile",
        "iam:GetLoginProfile",
        "iam:UpdateLoginProfile"
      ],
      "NotResource": [
        "arn:aws:iam::*:mfa/${aws:username}",
        "arn:aws:iam::*:user/${aws:username}"
      ],
      "Condition": {
        "BoolIfExists": {
            "aws:MultiFactorAuthPresent": "false"
        }
      }
    }
  ]
}

なお、 Conditionaws:MultiFactorAuthPresent はログイン時にMFAが行われたかどうかを判断する条件です。
MFAを有効化しても即時で"可"にはなりません。
本来の権限を有効にするには、MFA初回設定のあとにログインしなおす必要があります。

備考(注意事項)

この記事のポリシーは仮想MFAでのみ検証しています。
物理デバイスは持っていないので未検証。