MFA必須化ポリシー実装での学び
今回はAWS IAMのMFA(多要素認証)必須化ポリシーを実装する際に遭遇した課題と、そこから得た学びについて共有したいと思います。
MFA必須化ポリシーの実装と検証
セキュリティ強化のため、以下のIAMポリシーを使ってMFAの必須化を実装することにしました。まずは検証環境で以下を実装しました。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowListActions",
"Effect": "Allow",
"Action": [
"iam:ListUsers",
"iam:ListVirtualMFADevices"
],
"Resource": "*"
},
{
"Sid": "AllowUserToCreateVirtualMFADevice",
"Effect": "Allow",
"Action": [
"iam:CreateVirtualMFADevice"
],
"Resource": "arn:aws:iam::*:mfa/*"
},
{
"Sid": "AllowUserToManageTheirOwnMFA",
"Effect": "Allow",
"Action": [
"iam:EnableMFADevice",
"iam:GetMFADevice",
"iam:ListMFADevices",
"iam:ResyncMFADevice"
],
"Resource": "arn:aws:iam::*:user/${aws:username}"
},
{
"Sid": "AllowUserToDeactivateTheirOwnMFAOnlyWhenUsingMFA",
"Effect": "Allow",
"Action": [
"iam:DeactivateMFADevice"
],
"Resource": [
"arn:aws:iam::*:user/${aws:username}"
],
"Condition": {
"Bool": {
"aws:MultiFactorAuthPresent": "true"
}
}
},
{
"Sid": "BlockMostAccessUnlessSignedInWithMFA",
"Effect": "Deny",
"NotAction": [
"iam:CreateVirtualMFADevice",
"iam:EnableMFADevice",
"iam:ListMFADevices",
"iam:ListUsers",
"iam:ListVirtualMFADevices",
"iam:ResyncMFADevice"
],
"Resource": "*",
"Condition": {
"BoolIfExists": {
"aws:MultiFactorAuthPresent": "false"
}
}
}
]
}
このポリシーは、MFAが設定されていない状態ではMFA設定関連の操作のみ許可し、それ以外の操作をブロックするという設計です。
もとからアカウント内に作成していた自分のユーザーアカウントで検証したところ、問題なくMFAを設定でき、MFA認証後は通常通り操作できることを確認しました。
「これで大丈夫!」と思ったため本番環境に適用する準備を進めていました。
新規ユーザーでの問題発覚
ところが、新規ユーザーアカウントでログインを行ったところ、まったくログインできないという問題が発生しました。
新規ユーザーは初回ログイン時にパスワード変更を求められるのですが、このポリシーではパスワード変更に必要な権限が許可されていなかったのです。
結果として:
- パスワード変更ができない
- パスワード変更なしではMFA設定もできない
- 完全に操作不能な状態に...
自分のアカウントでは既にパスワードを設定済みだったため、この問題に気づくことができませんでした。
修正版ポリシー
この問題を解決するため、NotActionリストにパスワード変更関連のアクションを追加しました:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowListActions",
"Effect": "Allow",
"Action": [
"iam:ListUsers",
"iam:ListVirtualMFADevices"
],
"Resource": "*"
},
{
"Sid": "AllowUserToCreateVirtualMFADevice",
"Effect": "Allow",
"Action": [
"iam:CreateVirtualMFADevice"
],
"Resource": "arn:aws:iam::*:mfa/*"
},
{
"Sid": "AllowUserToManageTheirOwnMFA",
"Effect": "Allow",
"Action": [
"iam:EnableMFADevice",
"iam:GetMFADevice",
"iam:ListMFADevices",
"iam:ResyncMFADevice"
],
"Resource": "arn:aws:iam::*:user/${aws:username}"
},
{
"Sid": "AllowUserToDeactivateTheirOwnMFAOnlyWhenUsingMFA",
"Effect": "Allow",
"Action": [
"iam:DeactivateMFADevice"
],
"Resource": [
"arn:aws:iam::*:user/${aws:username}"
],
"Condition": {
"Bool": {
"aws:MultiFactorAuthPresent": "true"
}
}
},
{
"Sid": "BlockMostAccessUnlessSignedInWithMFA",
"Effect": "Deny",
"NotAction": [
"iam:CreateVirtualMFADevice",
"iam:EnableMFADevice",
"iam:ListMFADevices",
"iam:ListUsers",
"iam:ListVirtualMFADevices",
"iam:ResyncMFADevice",
"iam:ChangePassword", // 追加
"iam:GetAccountPasswordPolicy" // 追加
],
"Resource": "*",
"Condition": {
"BoolIfExists": {
"aws:MultiFactorAuthPresent": "false"
}
}
}
]
}
追加した権限
-
iam:ChangePassword: パスワード変更を許可 -
iam:GetAccountPasswordPolicy: パスワードポリシーの取得を許可(パスワード要件を確認するために必要)
これにより、新規ユーザーでも以下の操作が可能になりました:
- 初回ログイン
- パスワード変更
- MFAデバイスの設定
- MFA認証後の通常操作
学んだこと
MFAの必須化ポリシーを実装するうえで2つのことを学びました
1. 検証方法の不十分さ
自分のアカウント(既存ユーザー)のみで検証したため、新規ユーザーの場合のログインの流れを見落としていました。検証は必ず複数のシナリオで行うべきだと思いました。
2. IAMポリシーへの理解向上
今回使用したNotActionとDenyの組み合わせは「リストに書いていない操作を全て拒否する」という方法でした。
今回の経験で学んだこと:
- ユーザーの操作を最初から最後まで想像する: 新規ユーザーから既存ユーザーまで全ての操作の流れを考える必要がある
- 「禁止」は予想外の場所に影響する: 意図していない操作まで制限してしまう可能性がある
- 公式のサンプルをそのまま使えばいいと思わない: 自分の環境に合わせて調整が必要な場合がある
おわりに
セキュリティポリシーは、想定外の影響が出る場合があることがわかりました。
操作の流れを想像して検証も効果的に行えるよう気を付けなければと思いました!
この記事が同じような実装を検討している方の参考になれば幸いです。
参考リンク:
- [AWS IAM: ユーザーに MFA デバイスの管理を許可する](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_examples_iam_mfa-selfmana…