[AWS][強制MFA] ログイン時パスワード変更できるポリシー


IAMユーザーに初回ログイン時、パスワードリセットを行い、MFA認証を強制させるためのポリシーです。

強制MFAしてもらおうと、AWS公式の案内されているポリシーを何も考えずに適用すると、
> ユーザーに iam:ChangePassword を実行する権限がないか、入力されたパスワードが管理者によって設定されたアカウントパスワードポリシーに準拠していません

というエラーがログインしてからパスワード変更するときに発生すると思います。今回はこれの躱し方です。

この記事は以下のドキュメントを参考にしています。

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

この方法は **非推奨** です。理由は上記でも案内されているように

> このポリシー例では、ユーザーが初めてサインインするときにパスワードをリセットすることはできません。AWS では、新しいユーザーがサインインするまで、当該ユーザーにアクセス許可を付与しないことを推奨しています。詳細については、「IAM ユーザーを安全に作成するにはど うすればよいですか?」を参照してください。また、これにより、失効したパスワードを持つユーザーは、サインイン前にパスワードをリセット できなくなります。この操作を許可するには、iam:ChangePassword と iam:GetAccountPasswordPolicy をステートメント DenyAllExceptListedIfNoMFA に追加します。ただし、IAM ではこのようなアクセス許可をお勧めしません。ユーザーが MFA なしで自分のパスワードを変更できるようにすると、セキュリティ上のリスクが生じる可能性があります。

です。厳密には確かにそうですが、運用を楽するために、この非推奨を受け入れる場合には、以下のポリシーを参照ください。
以下のポリシーは、
>操作を許可するには、iam:ChangePassword と iam:GetAccountPasswordPolicy をステートメント DenyAllExceptListedIfNoMFA に追加

という設定をしたものです。

```json
{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "AllowViewAccountInfo",
			"Effect": "Allow",
			"Action": [
				"iam:GetAccountPasswordPolicy",
				"iam:ListVirtualMFADevices"
			],
			"Resource": "*"
		},
		{
			"Sid": "AllowManageOwnPasswords",
			"Effect": "Allow",
			"Action": [
				"iam:ChangePassword",
				"iam:GetUser"
			],
			"Resource": "arn:aws:iam::*:user/${aws:username}"
		},
		{
			"Sid": "AllowManageOwnAccessKeys",
			"Effect": "Allow",
			"Action": [
				"iam:CreateAccessKey",
				"iam:DeleteAccessKey",
				"iam:ListAccessKeys",
				"iam:UpdateAccessKey"
			],
			"Resource": "arn:aws:iam::*:user/${aws:username}"
		},
		{
			"Sid": "AllowManageOwnSigningCertificates",
			"Effect": "Allow",
			"Action": [
				"iam:DeleteSigningCertificate",
				"iam:ListSigningCertificates",
				"iam:UpdateSigningCertificate",
				"iam:UploadSigningCertificate"
			],
			"Resource": "arn:aws:iam::*:user/${aws:username}"
		},
		{
			"Sid": "AllowManageOwnSSHPublicKeys",
			"Effect": "Allow",
			"Action": [
				"iam:DeleteSSHPublicKey",
				"iam:GetSSHPublicKey",
				"iam:ListSSHPublicKeys",
				"iam:UpdateSSHPublicKey",
				"iam:UploadSSHPublicKey"
			],
			"Resource": "arn:aws:iam::*:user/${aws:username}"
		},
		{
			"Sid": "AllowManageOwnGitCredentials",
			"Effect": "Allow",
			"Action": [
				"iam:CreateServiceSpecificCredential",
				"iam:DeleteServiceSpecificCredential",
				"iam:ListServiceSpecificCredentials",
				"iam:ResetServiceSpecificCredential",
				"iam:UpdateServiceSpecificCredential"
			],
			"Resource": "arn:aws:iam::*:user/${aws:username}"
		},
		{
			"Sid": "AllowManageOwnVirtualMFADevice",
			"Effect": "Allow",
			"Action": [
				"iam:CreateVirtualMFADevice",
				"iam:DeleteVirtualMFADevice"
			],
			"Resource": "arn:aws:iam::*:mfa/*"
		},
		{
			"Sid": "AllowManageOwnUserMFA",
			"Effect": "Allow",
			"Action": [
				"iam:DeactivateMFADevice",
				"iam:EnableMFADevice",
				"iam:ListMFADevices",
				"iam:ResyncMFADevice"
			],
			"Resource": "arn:aws:iam::*:user/${aws:username}"
		},
		{
			"Sid": "DenyAllExceptListedIfNoMFA",
			"Effect": "Deny",
			"NotAction": [
				"iam:CreateVirtualMFADevice",
				"iam:EnableMFADevice",
				"iam:GetUser",
				"iam:ListMFADevices",
				"iam:ListVirtualMFADevices",
				"iam:ResyncMFADevice",
				"sts:GetSessionToken",
				"iam:ChangePassword",
				"iam:GetAccountPasswordPolicy"
			],
			"Resource": "*",
			"Condition": {
				"BoolIfExists": {
					"aws:MultiFactorAuthPresent": "false"
				}
			}
		}
	]
}
```

以上