自分でMFAの管理ができるIAMユーザーの作り方

ごきげんよう、@An_nAです！
この記事は[ハンズラボ Advent Calendar 2021](https://qiita.com/advent-calendar/2021/handslab) 6日目の記事です。

突然ですが、AWSをご利用のみなさん、MFA(多要素認証)の設定は行なっていますか？
アカウントの乗っ取りは怖いですからね、不正ログインを防止するためにも未設定の方はぜひこれを機に設定してくださいね。
AWSのユーザーガイド、よろしければどうぞ。
[AWS での多要素認証 (MFA) の使用](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_credentials_mfa.html)

## 自分でMFAの管理ができるようIAMユーザーに権限を付与しよう
さてさて、ここからが本題ですよ。

あるうららかな日、AWSアカウント管理者のところにシステム利用者(そうですね、仮にAさんとしましょう)がやってきて言いました。
「AWSマネジメントコンソールにサインインしてやりたい作業があるの」
「今後、Bさんにも同じ作業をお願いするかもしれないわ」

そこで、AWSアカウント管理者はシステム利用者用のIAMグループを作成しました。
このIAMグループにはAさんがやりたい作業に必要な権限をばっちりつけています。
次に、システム利用者用IAMグループに所属するAさん用のIAMユーザーを作成しました。
そして、Aさんにユーザー名、パスワードといったサインイン情報を伝えました。
MFAを設定してくださいね、とお願いを添えて。
ふぅ、一仕事終えましたね。コーヒーでも飲みましょう。

ところがほどなくして、Aさんからこんな連絡が入ります。
「マネジメントコンソールへはサインインできたわ」
「やりたい作業もできてるの」
「だけど、MFAの設定ができないのよね〜」

なぜでしょう？

タイトルからお察しですね。
そう、システム利用者用IAMグループに、Aさんがやりたい作業に必要な権限はばっちり付与されていたものの、MFA管理に必要な権限がすぽっと抜けていたんです。
というわけで、前置きが長くなりましたがMFA管理に必要な権限たちをご紹介します！

### MFA管理を許可するのに必要な権限たち
以下の権限をAllowしてください。
先程の小芝居の例で言うと、システム利用者用IAMグループにこれらの権限がついていればOKです！

| Action | どんな権限？ | リソース |
|:-----------|:-----------|:-----------|
|iam:ListVirtualMFADevices|仮想MFAデバイスを割り当て状況別に一覧表示|arn:aws:iam::<アカウントID>:mfa/|
|iam:CreateVirtualMFADevice|新しい仮想MFAデバイスの作成|arn:aws:iam::<アカウントID>:mfa/${aws:username}|
|iam:DeleteVirtualMFADevice|仮想MFAデバイスの削除|同上|
|iam:EnableMFADevice|MFAデバイスを有効にし、指定されたIAMユーザーと関連付ける|arn:aws:iam::<アカウントID>:user/${aws:username}|
|iam:DeactivateMFADevice|指定されたMFAデバイスを無効化＆最初に有効化されたIAMユーザーとの関連付けを解除|同上|
|iam:ResyncMFADevice|指定したMFAデバイスとそのIAMエンティティ（ユーザーまたはロール）を同期|同上|
|iam:ListMFADevices|IAMユーザーのMFAデバイスを一覧表示|同上|

### IAMコンソールのユーザーページが表示できないんだけど...
ここまでにご紹介した権限がシステム利用者用IAMグループに付与済みであれば、このグループに所属しているAさんは自ユーザーのMFAの管理ができるようになっています。
が、しかし。
この権限では、AさんはIAMコンソールからユーザーページを表示することはできないんです。
では、AさんはどこからMFAの設定をすれば良いの？

答えは「セキュリティ認証情報」です。
マネジメントコンソールにサインイン後、ユーザー情報が表示されている右上あたりをクリックすると選べますよ。

![image1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624944/a8a4eea9-179d-9cea-d6ed-9c6a18880deb.png)

「セキュリティ認証情報」をクリックすると、以下の画面に遷移します。
「多要素認証(MFA)」にある「MFAデバイスの割り当て」から設定をしてもらいましょう。
![image2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624944/7b80ffda-2401-864e-160b-279988733b3a.png)


もしAさんに「どうしてもIAMコンソールのユーザーページも見たいわ」と言われたら以下の権限もAllowしてあげてくださいね。

| Action | どんな権限？ | リソース |
|:-----------|:-----------|:-----------|
|iam:ListUsers|指定されたパス・プレフィックスを持つIAMユーザーを一覧表示|arn:aws:iam::<アカウントID>:user/|

## (おまけ)Serverless Frameworkで書いてみよう
ここまでにご紹介した権限を持つIAMグループの定義をServerless Frameworkで書くとこんな感じです。グループ名やポリシー名を適切なものに変更して、あとは許可する作業用の権限を足せばOKです。IAMコンソールのユーザーページ表示の権限は付いていないので、必要に応じて追加してくださいね。

あ！ちなみにこちらはServerless Framework 2.50.0以降の記法です。
お使いのバージョンが2.50.0より前な場合は、こちらのブログが参考になるかもしれません。良かったらご覧ください。
[[Tips]Serverless Frameworkでプラグイン「serverless-pseudo-parameters」にさよならバイバイしたお話](https://www.hands-lab.com/tech/t12209/)

!Joinしている理由が気になった方にはこちらがおすすめですよ！
[[Tips]Serverless Frameworkで${aws:username}と書きたいときのお話](https://www.hands-lab.com/tech/t12185/)

```yaml:serverless.yml
ExampleGroup:
    Type: AWS::IAM::Group
    Properties:
        GroupName: ${self:service}-ExampleGroup
        Path: /
        Policies:
        - PolicyName: ${self:service}-ExamplePolicy
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action: iam:ListVirtualMFADevices
                Resource: arn:aws:iam::#{AWS::AccountId}:mfa/
              - Effect: Allow
                Action:
                    - iam:DeleteVirtualMFADevice
                    - iam:CreateVirtualMFADevice
                Resource:
                    - !Join
                    - ''
                    - - 'arn:aws:iam::#{AWS::AccountId}:mfa/'
                        - '$'
                        - '{aws:username}'
              - Effect: Allow
                Action:
                    - iam:EnableMFADevice
                    - iam:DeactivateMFADevice
                    - iam:ResyncMFADevice
                    - iam:ListMFADevices
                Resource:
                    - !Join
                    - ''
                    - - 'arn:aws:iam::#{AWS::AccountId}:user/'
                        - '$'
                        - '{aws:username}'
```

## 参考資料
AWSのユーザーガイドでは、「MFA認証されていない場合に特定の作業を禁止する」ポリシーの例も紹介されています。

* [AWS: MFA で認証された IAM ユーザーが My Security Credentials (マイセキュリティ資格情報) ページで自分の認証情報を管理できるようにする](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_examples_aws_my-sec-creds-self-manage.html)

* [IAM: IAM ユーザーに MFA デバイスの自己管理を許可する](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_examples_iam_mfa-selfmanage.html)


それでは、よいMFAライフを！