AWS CodeCommitリポジトリへのアクセスを除きMFA強制するIAMポリシー
AWSのIAMユーザを払い出した際に、不正アクセスのリスク低減のためMFA(多要素認証)の設定をしてほしいが、設定したかの確認が面倒だし、中々やってくれないといったケースがある。
そのような場合、以下ドキュメントのようにMFAを強制するIAMポリシーを割り当てることが有効。
docs.aws.amazon.com
ただし、このIAMポリシーを使った場合、CodeCommitのリポジトリへのアクセスにもMFAが必要となる。
git-remote-codecommitやAWS CLI 認証情報ヘルパーを使えばMFAを使ってリポジトリへアクセスできるが、環境やアクセス要件によってはこれらが使用できない場合もある。
その場合は、IAMポリシーを変更することでCodeCommitリポジトリへのアクセスのみMFA強制の対象外とすることができる。
その設定をした際のメモを記載する。
実施内容
CodeCommitへのアクセスに必要なアクションを許可する
前述したドキュメントに従ってIAMポリシーを作成すると、DenyAllExceptListedIfNoMFAステートメントのNotActionに「MFA を使用していない場合に許可する操作」が記載されている。
ここに、CodeCommitリポジトリの操作に必要な以下アクションを追加する。
- codecommit:GitPull
- codecommit:GitPush
- kms:Encrypt
- kms:Decrypt
- kms:ReEncrypt
- kms:GenerateDataKey
- kms:GenerateDataKeyWithoutPlaintext
- kms:DescribeKey
※KMS関連アクションも追加しているのは、CodeCommitへのアクセス時にKMSも使用されているため。
エイリアス名「aws/codecommit」のキーに対する上記KMS関連アクションを許可する必要がある。
詳細は以下リンク参照。
docs.aws.amazon.com
編集後のDenyAllExceptListedIfNoMFAステートメントは以下。
{ "Sid": "DenyAllExceptListedIfNoMFA", "Effect": "Deny", "NotAction": [ "iam:CreateVirtualMFADevice", "iam:EnableMFADevice", "iam:GetUser", "iam:ListMFADevices", "iam:ListVirtualMFADevices", "iam:ResyncMFADevice", "sts:GetSessionToken", "codecommit:GitPull", "codecommit:GitPush", "kms:Encrypt", "kms:Decrypt", "kms:ReEncryptFrom", "kms:ReEncryptTo", "kms:GenerateDataKey", "kms:GenerateDataKeyWithoutPlaintext", "kms:DescribeKey" ], "Resource": "*", "Condition": { "BoolIfExists": { "aws:MultiFactorAuthPresent": "false" } } },
KMS関連アクションの許可対象リソースを制限する
編集したDenyAllExceptListedIfNoMFAステートメントはResourceが「*」なので、このままだとKMS関連アクションが全てのキーに対してMFAなしで実行できてしまう。
そのため、 以下のようにaws/codecommit キー以外に対する kms関連アクションの Deny 設定を追加する。
{ "Sid": "DenyKMSExceptListedIfNoMFA", "Effect": "Deny", "Action": [ "kms:Encrypt", "kms:Decrypt", "kms:ReEncryptFrom", "kms:ReEncryptTo", "kms:GenerateDataKey", "kms:GenerateDataKeyWithoutPlaintext", "kms:DescribeKey" ], "Resource": "*", "Condition": { "ForAnyValue:StringNotEquals": { "kms:ResourceAliases": [ "alias/aws/codecommit" ] }, "BoolIfExists": { "aws:MultiFactorAuthPresent": "false" } } }
※エイリアス指定でKMSキーへのアクセスを制御するには「kms:ResourceAliases」を使う。詳細は以下参照。
※ちなみに以下の書き方でもよい。
NotResourceにKMSキーのARNを記載する必要があるのが嫌だったので、今回はエイリアス名の記載だけでよい上記の書き方を採用した。
{ "Sid": "DenyKMSExceptListedIfNoMFA", "Effect": "Deny", "Action": [ "kms:Encrypt", "kms:Decrypt", "kms:ReEncryptFrom", "kms:ReEncryptTo", "kms:GenerateDataKey", "kms:GenerateDataKeyWithoutPlaintext", "kms:DescribeKey" ], "NotResource": [ "arn:aws:kms:*:*:alias/aws/codecommit", "{エイリアス名が「aws/codecommit」なKMSキーのARN}" ], "Condition": { "BoolIfExists": { "aws:MultiFactorAuthPresent": "false" } } }
最終的なIAMポリシー
最終的なIAMポリシーは以下のようになる。
このIAMポリシーをIAMユーザ or IAMユーザが所属するIAMグループに割り当てることで、「MFA設定するまで、MFAの設定とCodeCommitの操作以外できない」という挙動にすることができる。
{ "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/${aws:username}" }, { "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", "codecommit:GitPull", "codecommit:GitPush", "kms:Encrypt", "kms:Decrypt", "kms:ReEncryptFrom", "kms:ReEncryptTo", "kms:GenerateDataKey", "kms:GenerateDataKeyWithoutPlaintext", "kms:DescribeKey" ], "Resource": "*", "Condition": { "BoolIfExists": { "aws:MultiFactorAuthPresent": "false" } } }, { "Sid": "DenyKMSExceptListedIfNoMFA", "Effect": "Deny", "Action": [ "kms:Encrypt", "kms:Decrypt", "kms:ReEncryptFrom", "kms:ReEncryptTo", "kms:GenerateDataKey", "kms:GenerateDataKeyWithoutPlaintext", "kms:DescribeKey" ], "Resource": "*", "Condition": { "ForAnyValue:StringNotEquals": { "kms:ResourceAliases": [ "alias/aws/codecommit" ] }, "BoolIfExists": { "aws:MultiFactorAuthPresent": "false" } } } ] }
補足
CodeCommitへMFAを使ってアクセスする方法
CodeCommitへMFAを使ってアクセスするには、git-remote-codecommitかAWS CLI 認証情報ヘルパーを使う必要がある。 ※このページに「CodeCommit への一時アクセスまたはフェデレーティッドアクセスに対して推奨されるアプローチは git-remote-codecommit を設定すること」とあるので、git-remote-codecommitの方が推奨されている模様。
それぞれの具体的な設定手順は以下を参照。
- git-remote-codecommit
docs.aws.amazon.com
- AWS CLI 認証情報ヘルパー
docs.aws.amazon.com
どちらの接続方式も、get-session-token コマンドを使用してMFA認証して、コマンド結果に含まれる一時的な認証情報を用いて、CodeCommit へアクセスする。
アクセス方法は以下を参照。
aws.amazon.com
IAMユーザー払い出し時の注意点
ユーザ作成時は「パスワードのリセットが必要」にチェックを入れない
IAMユーザ作成時によくやるのが、「パスワードのリセットが必要」にチェックを入れて、初回ログイン時にユーザにパスワードリセットを強制する設定。
しかし、本ページで紹介したIAMポリシーを割り当てたユーザーは、MFA認証でログインしない限りパスワード変更できないため、MFA設定前の初回ログイン時にはパスワードリセットする権限がない。
そのため、初回ログイン時に「パスワードリセットしないと先に進めないのに、リセット権限がない」という状況に陥り、何もできなくなってしまう。
なので、IAMユーザ作成時には「パスワードのリセットが必要」にチェックを入れず、2回目以降のログイン時にパスワードを変更するようユーザに伝える必要がある。
※IAMポリシーを緩めれば初回ログインでパスワードリセットさせることは可能だが、このドキュメントに「IAM ではこのようなアクセス許可をお勧めしません。ユーザーが MFA なしで自分のパスワードを変更できるようにすると、セキュリティ上のリスクが生じる可能性があります。」と記載してあるので、やらない方が良いと思う。
MFA設定画面までの行き方に注意
AWSのMFA有効化手順にはIAMの画面からナビゲーションペインの「ユーザ」をクリックすると記載されている。
しかし、本ページのポリシーを適用しているとMFA認証でログインするまではユーザの一覧画面を開く権限がなく、エラーとなってしまう。
そのため、自分のユーザの画面を開くためには、右上のユーザー名から「セキュリティ認証情報」をクリックする必要がある。
新規ユーザを作成した場合はこの手順についてもユーザに伝える。