ちょっと話題の記事

IAMユーザ本人にMFAを管理してもらうためのIAMポリシー

2015.08.17

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

はじめに

こんにちは、虎塚です。

組織でAWSアカウントを利用する際には、担当者ごとにIAMユーザを払い出し、各ユーザが自分でMFA (Multi-Factor Authentication) を有効にすることが推奨されています。クラスメソッドでも、お客様の環境ごとにIAMユーザを作成し、MFAを設定していただくようにお願いしています。

ここで問題になるのが、IAMのポリシーです。IAMユーザ本人に自分自身のMFAを管理できるようにするには、どんなポリシーが適切なのでしょうか? このテーマは、当ブログの過去記事でも何度か登場していますね。

2015年8月現在、上記で紹介されたポリシーでは正常に動かなかったため、ここで改めてご紹介します。

結論

次のポリシーを適用することで、IAMユーザは自分自身のMFAを管理できます。

  • 012345678901は、12桁のAWSアカウントIDに読み替えてください
  • ${aws:username}は、APIを発行したIAMユーザのユーザ名を参照するための記述です(そのままでOK)
  • 利用目的に合った権限を、別途IAMポリシーで与えているものとします
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iam:ListUsers"
            ],
            "Resource": [
                "arn:aws:iam::012345678901:user/"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iam:ListVirtualMFADevices"
            ],
            "Resource": [
                "arn:aws:iam::012345678901:mfa/"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iam:EnableMFADevice",
                "iam:DeactivateMFADevice",
                "iam:ResyncMFADevice",
                "iam:ListMFADevices"
            ],
            "Resource": [
                "arn:aws:iam::012345678901:user/${aws:username}"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iam:DeleteVirtualMFADevice",
                "iam:CreateVirtualMFADevice"
            ],
            "Resource": [
                "arn:aws:iam::012345678901:mfa/${aws:username}"
            ]
        }
    ]
}

上記で用は足りるとおもいますが、IAMの話が好きな方は続きもお読みいただければ幸いです。

解説

前提: APIの種別

MFA関連のAPIには、ユーザを対象とするものと、MFAを対象とするものとがあります。実験をすれば詳細が分かりますが、IAMのAPIリファレンスを一瞥しただけでは、指定対象として適切なリソースを特定しづらいかもしれません。

また、さらにくわしく見ると、指定対象には「(アカウントに紐づく)すべてのIAMユーザ」と「IAMユーザ本人」、または「(アカウントに紐づく)すべてのMFA」と「IAMユーザ本人のMFA」の選択があります。

指定対象のリソースとIAMポリシーの記述方法を、次の表に示します。

指定対象リソース IAMポリシーの記述
すべてのIAMユーザ arn:aws:iam::012345678901:user/
IAMユーザ本人 arn:aws:iam::012345678901:user/${aws:username}
すべてのMFA arn:aws:iam::012345678901:mfa/
IAMユーザ本人のMFA arn:aws:iam::012345678901:mfa/${aws:username}

IAMユーザを対象とするAPI

次のAPIは、操作対象のリソースとしてIAMユーザ本人を指定します。

  • ResyncMFADevice
  • DeactivateMFADevice
  • EnableMFADevice

上記のAPIは、すべてのIAMユーザをリソースに指定しても動作します。ただし、なにか意図がない限り、IAMユーザ本人を指定したほうがよいでしょう。特にDeactivateMFADeviceは、後述するDeleteVirtualMFADeviceの操作権限がなくても実行できるため、他のIAMユーザのMFAを削除できてしまいます

次のAPIは、操作対象のリソースとしてIAMユーザ本人もしくは、すべてのIAMユーザを指定します。

  • ListMFADevices

このAPIは、Management ConsoleのIAMユーザ詳細画面で、MFAの情報を表示するために必要です。IAMユーザ本人を指定すると、本人の情報だけが表示されます。すべてのIAMユーザを対象にすると、他のIAMユーザの詳細画面でもMFA情報が表示されます。

なお、MFAを有効化してからListMFADevicesの許可を削除してしまうと、「Management Console上ではMFAが関連づけられていないように見えるが、じつは関連づけられている」という最高の状態になってハマりますので、注意してください。「MFADevice entity at the same path and name already exists.」というエラーが表示されたら、その状況に陥っていないか確認してください。

ListMFADevicesのエラー

MFAを対象とするAPI

次のAPIは、操作対象のリソースとしてIAMユーザ本人のMFAを指定します。

  • CreateVirtualMFADevice
  • DeleteVirtualMFADevice

これらをMFAに対して許可していないと、たとえEnableMFADevice/DeactiveMFADeviceをユーザに対して許可していても、MFAの有効化/無効化に失敗します。

上記のAPIは、すべてのMFAをリソースに指定しても動作します。MFAを有効化/無効化できるかどうかは、IAMユーザに対してEnableMFADevice/DeactivateMFADeviceの操作を許可しているかに依存するので、すべてのMFAをリソースに指定することのデメリットは特にないと思います。が、やはり特別な意図がない限り、本人に対してのみ許可しましょう。

次のAPIは、操作対象のリソースとしてすべてのMFAを指定します。

  • ListVirtualMFADevices

IAMユーザ本人のMFAだけを指定すると、MFAの作成ができません(MFAの同期や削除はできます)。QRコードの画面にたどり着く前に、「User: arn:aws:iam::012345678901:user/iam-user-name is not authorized to perform: iam:ListVirtualMFADevices on resource: arn:aws:iam::012345678901:mfa/」というエラーになります。

ListVirtualMFADevicesのエラー

推測ですが、MFAの作成時には、エンティティの重複が起きないように、内部的に既存のMFAをチェックする必要があるからではないかと思います。MFAの同期や削除は、本人のMFAのARNさえ取得できれば実行できそうです。

設定ミスによる様々なエラー

上記を守らなかった場合、様々なエラーに遭遇できます。

EnableMFADeviceが許可されていない場合は、QRコードが表示される画面で認証コードを入れた後、次へ進もうとすると「User: arn:aws:iam::012345678901:user/iam-user-name is not authorized to perform: iam:EnableMFADevice on resource: user iam-user-name」というエラーになります。エラーメッセージから、IAMユーザ本人をリソースに指定するべきだと分かります。

EnableMFADeviceのエラー

DeleteVirtualMFADeviceの許可はあるが、DeactiveMFADeviceの許可がないと、「User: arn:aws:iam::012345678901:user/iam-user-name is not authorized to perform: iam:DeactiveMFADevice on resource: user iam-user-name」というエラーになります。こちらも、エラーメッセージから、IAMユーザ本人をリソースに指定するべきだと分かります。

DeactiveMFADeviceのエラー

上のほうで述べたことの繰り返しになりますが、逆の場合、つまりDeactiveMFADeviceの許可はあるが、DeleteVirtualMFADeviceの許可がない場合は、MFAを無効化できてしまうので注意してください。

しかしながら、EnableMFADeviceの許可があっても、CreateVirtualMFADeviceとDeleteVirtualMFADeviceの許可がないと、MFAを有効化できません。「User: arn:aws:iam::012345678901:user/iam-user-name is not authorized to perform: iam:DeleteVirtualMFADevice on resource: arn:aws:iam::012345678901:mfa/iam-user-name」というエラーになります。エラーメッセージから、IAMユーザ本人のMFAをリソースに指定するべきだと分かります。

DeleteVirtualMFADeviceのエラー

まとめ

解説した内容を次の表にまとめます。

API 指定する対象リソース
ResyncMFADevice IAMユーザ本人
DeactivateMFADevice IAMユーザ本人(すべてのIAMユーザ指定はNG
EnableMFADevice IAMユーザ本人
ListMFADevices IAMユーザ本人(もしくは、すべてのIAMユーザでもよい)
CreateVirtualMFADevice IAMユーザ本人のMFA
DeleteVirtualMFADevice IAMユーザ本人のMFA
ListVirtualMFADevices すべてのMFA(IAMユーザ本人のMFA指定はNG

一見複雑ですが、エラーメッセージを確認すればどんな設定が不足しているか分かりますので、安心してください。

おわりに

MFAをムファッといい感じに設定して、アカウントのセキュリティを維持しましょう!

それでは、また。