はじめに
以前、IAMユーザーにMFA強制させる方法について書きました。
CodeCommitを利用する場合、Git認証はAWS CodeCommit の HTTPS Git 認証情報を利用し、GitクライアントにID/パスワード設定する使い方が多数派ではないかと思います。
※git-remote-codecommit(GRC)を使ったIAM認証はIDEが対応していなかったりするため
ここでMFA強制している問題として、上記のAWS CodeCommit の HTTPS Git 認証情報が拒否されてしまいます。
そのため、今回はIAMユーザーにMFA強制させつつも、Gitクライアントからの操作はMFA対象外にする手順について記載します。
手順
事前準備
前回記事で作成した、IAMポリシーforced-mfa-and-my-sec-creds-self-manage
とIAMユーザーtest
を流用します。
IAMユーザーtest
がCodeCommitの操作が行えるようIAMポリシー(AWS管理)AWSCodeCommitPowerUserを追加します。
CodeCommitにテスト用のリポジトリtest-codecommit
を作成しておきます。
この時点でGitクライアントからgit clone
すると以下のエラー(MFAなし)になります。
$ git clone https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/test-codecommit Cloning into 'test-codecommit'... fatal: unable to access 'https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/test-codecommit/': The requested URL returned error: 403
※Gitクライアントから初回アクセスの場合はクレデンシャルを入力します
以下、CloudTrailのイベント履歴も確認してみるとgit clone
はAWS側ではGitPull
アクションとして失敗しています。
{ "eventVersion": "1.08", "userIdentity": { "type": "IAMUser", "principalId": "hogehoge", "arn": "arn:aws:iam::<AWSアカウントID>:user/test", "accountId": "<AWSアカウントID>", "userName": "test" }, "eventTime": "2023-11-02T04:25:46Z", "eventSource": "codecommit.amazonaws.com", "eventName": "GitPull", "awsRegion": "ap-northeast-1", "sourceIPAddress": "hogehoge", "userAgent": "git/2.41.0.windows.1", "errorCode": "InternalFailure", "requestParameters": null, "responseElements": null, "additionalEventData": { "protocol": "HTTP", "dataTransferred": false, "repositoryName": "test-codecommit" }, "requestID": "hogehoge", "eventID": "hogehoge", "readOnly": true, "resources": [ { "accountId": "<AWSアカウントID>", "type": "AWS::CodeCommit::Repository", "ARN": "arn:aws:codecommit:ap-northeast-1:<AWSアカウントID>:test-codecommit" } ], "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "<AWSアカウントID>", "eventCategory": "Management" }
IAMポリシーの修正
IAMポリシーforced-mfa-and-my-sec-creds-self-manage
を以下のように修正します。
Sid
-DenyAllExceptListedIfNoMFA
のNotAction
にcodecommit:*
、Condition
にkms:ViaService
を追加します。
kms:ViaService
の部分がポイントで、AWSサービスからのKMS操作も、MFA強制から除外しています。
これはAWS Key Management Service と AWS CodeCommit リポジトリの暗号化にも記載がある通り「CodeCommitは、デフォルトのaws/codecommitキーに対して、AWS KMSアクションを実行します」により、CodeCommitの裏側でKMSによる暗号化を行っているためです。
許可が必要なアクションはGit クライアントのコマンドに必要なアクセス許可を参考にします。
今回は記載しませんが、mainブランチへの操作は特定の人だけに制限する等、実運用ポリシーに合わせて設定できます。
{ "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": "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" ], "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", "codecommit:*" ], "Resource": "*", "Condition": { "Null": { "kms:ViaService": "true" }, "BoolIfExists": { "aws:MultiFactorAuthPresent": "false" } } } ] }
動作確認
最後にMFAなしでGitクライアントから利用できることを確認します。
$ git clone https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/test-codecommit Cloning into 'test-codecommit'... warning: You appear to have cloned an empty repository. $ cd test-codecommit/ $ echo test > README.md $ git add README.md warning: in the working copy of 'README.md', LF will be replaced by CRLF the next time Git touches it $ git commit -m "first commit" [master (root-commit) dd6560b] first commit 1 file changed, 1 insertion(+) create mode 100644 README.md $ git push origin master Enumerating objects: 3, done. Counting objects: 100% (3/3), done. Writing objects: 100% (3/3), 221 bytes | 221.00 KiB/s, done. Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 remote: Validating objects: 100% To https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/test-codecommit * [new branch] master -> master
AWSマネジメントコンソール上でもpushしたファイルが確認できます。
おわりに
今回はCodeCommitをMFAの対象外としましたが、他AWSサービスをMFAの対象外とする場合も同様の流れで実現できます。
小ネタでしたが、誰かのお役に立てばと思います。