SSHでCodeCommitを使いつつ、MFA強制ポリシー適用時にgit操作できなくなる問題を回避したい

2021.04.23

いわさです。

CodeCommitにはいくつか認証方法のオプションがあり、SSHキーでアクセスすることが可能です。
IAMポリシーでMFAを強制する設定を行うことが多いと思いますが、このポリシーをAWSドキュメント記載のまま設定するとSSHキーでのgit操作が出来なくなります。
CodeCommitアクションをポリシーに例外登録することで操作が可能になります。

CodeCommitへSSHアクセス出来るよう構成する

CodeCommitにおける SSH接続のセットアップ手順は以下を参考に実施しました。

IAMからSSHパブリックキーをアップロードし、設定ファイルを作成します。

マネコンIAMからSSHキーIDを取得して、configファイルをローカルに作成します。

iwasa.takahito@hoge ~ % vi ~/.ssh/config
iwasa.takahito@hoge ~ % cat ~/.ssh/config     
Host git-codecommit.*.amazonaws.com
  User AAAAAAAAAAAAAAAAAAAA
  IdentityFile ~/.ssh/codecommit_rsa

ここまでで、一旦SSHでのgit操作が出来る状態となりました。

iwasa.takahito@hoge src % git clone ssh://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/repo_mfa
Cloning into 'repo_mfa'...
remote: Counting objects: 3, done.
Receiving objects: 100% (3/3), 220 bytes | 110.00 KiB/s, done.

MFAポリシーを適用する

以下の手順に従い、MFAを強制するポリシーを適用します。

MFAを使って認証されてない場合、MFA登録操作など以外のアクションはすべて拒否されます。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowListActions",
            "Effect": "Allow",
            "Action": [
                "iam:ListUsers",
                "iam:ListVirtualMFADevices"
            ],
            "Resource": "*"
        },
        {
            "Sid": "AllowIndividualUserToListOnlyTheirOwnMFA",
            "Effect": "Allow",
            "Action": [
                "iam:ListMFADevices"
            ],
            "Resource": [
                "arn:aws:iam::*:mfa/*",
                "arn:aws:iam::*:user/${aws:username}"
            ]
        },
        {
            "Sid": "AllowIndividualUserToManageTheirOwnMFA",
            "Effect": "Allow",
            "Action": [
                "iam:CreateVirtualMFADevice",
                "iam:DeleteVirtualMFADevice",
                "iam:EnableMFADevice",
                "iam:ResyncMFADevice"
            ],
            "Resource": [
                "arn:aws:iam::*:mfa/${aws:username}",
                "arn:aws:iam::*:user/${aws:username}"
            ]
        },
        {
            "Sid": "AllowIndividualUserToDeactivateOnlyTheirOwnMFAOnlyWhenUsingMFA",
            "Effect": "Allow",
            "Action": [
                "iam:DeactivateMFADevice"
            ],
            "Resource": [
                "arn:aws:iam::*:mfa/${aws:username}",
                "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での認証を行います。

AWSマネージメントコンソールからCodeCommitへはアクセス出来る状態です。

ローカル端末からのgit操作が出来なくなりました。

iwasa.takahito@hoge repo_mfa % git pull
Access denied: User: arn:aws:iam::123456789012:user/commit-mfa is not authorized to perform: codecommit:GitPull on resource: arn:aws:codecommit:ap-northeast-1:123456789012:repo_mfa with an explicit deny
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

ポリシー修正

CodeCommit操作をMFA未認証時の例外アクションとして追加します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowListActions",
            "Effect": "Allow",
            "Action": [
                "iam:ListUsers",
                "iam:ListVirtualMFADevices"
            ],
            "Resource": "*"
        },
        {
            "Sid": "AllowIndividualUserToListOnlyTheirOwnMFA",
            "Effect": "Allow",
            "Action": [
                "iam:ListMFADevices"
            ],
            "Resource": [
                "arn:aws:iam::*:mfa/*",
                "arn:aws:iam::*:user/${aws:username}"
            ]
        },
        {
            "Sid": "AllowIndividualUserToManageTheirOwnMFA",
            "Effect": "Allow",
            "Action": [
                "iam:CreateVirtualMFADevice",
                "iam:DeleteVirtualMFADevice",
                "iam:EnableMFADevice",
                "iam:ResyncMFADevice"
            ],
            "Resource": [
                "arn:aws:iam::*:mfa/${aws:username}",
                "arn:aws:iam::*:user/${aws:username}"
            ]
        },
        {
            "Sid": "AllowIndividualUserToDeactivateOnlyTheirOwnMFAOnlyWhenUsingMFA",
            "Effect": "Allow",
            "Action": [
                "iam:DeactivateMFADevice"
            ],
            "Resource": [
                "arn:aws:iam::*:mfa/${aws:username}",
                "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",
                "codecommit:*"
            ],
            "Resource": "*",
            "Condition": {
                "BoolIfExists": {
                    "aws:MultiFactorAuthPresent": "false"
                }
            }
        }
    ]
}

git操作してみます。

iwasa.takahito@hoge repo_mfa % git pull
Access denied: User is not authorized for the KMS default master key for CodeCommit 'alias/aws/codecommit' in your account
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

CodeCommitアクション許可するだけでは操作出来ません。
CodeCommitレポジトリは、AWSマネージドCMKで暗号化されています。

"kms:ViaService" をポリシーに追加し、サービスのKMS操作は許可します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowListActions",
            "Effect": "Allow",
            "Action": [
                "iam:ListUsers",
                "iam:ListVirtualMFADevices"
            ],
            "Resource": "*"
        },
        {
            "Sid": "AllowIndividualUserToListOnlyTheirOwnMFA",
            "Effect": "Allow",
            "Action": [
                "iam:ListMFADevices"
            ],
            "Resource": [
                "arn:aws:iam::*:mfa/*",
                "arn:aws:iam::*:user/${aws:username}"
            ]
        },
        {
            "Sid": "AllowIndividualUserToManageTheirOwnMFA",
            "Effect": "Allow",
            "Action": [
                "iam:CreateVirtualMFADevice",
                "iam:DeleteVirtualMFADevice",
                "iam:EnableMFADevice",
                "iam:ResyncMFADevice"
            ],
            "Resource": [
                "arn:aws:iam::*:mfa/${aws:username}",
                "arn:aws:iam::*:user/${aws:username}"
            ]
        },
        {
            "Sid": "AllowIndividualUserToDeactivateOnlyTheirOwnMFAOnlyWhenUsingMFA",
            "Effect": "Allow",
            "Action": [
                "iam:DeactivateMFADevice"
            ],
            "Resource": [
                "arn:aws:iam::*:mfa/${aws:username}",
                "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",
                "codecommit:*"
            ],
            "Resource": "*",
            "Condition": {
                "Null": {
                    "kms:ViaService": "true"
                },
                "BoolIfExists": {
                    "aws:MultiFactorAuthPresent": "false"
                }
            }
        }
    ]
}

git操作確認出来ました。

iwasa.takahito@hoge repo_mfa % git pull
Warning: Permanently added the RSA host key for IP address '1.2.3.4' to the list of known hosts.
Already up to date.

iwasa.takahito@hoge repo_mfa % git checkout -b hogehoge
Switched to a new branch 'hogehoge'
iwasa.takahito@hoge repo_mfa % git branch
* hogehoge
  main
iwasa.takahito@hoge repo_mfa % vi hoge.txt          
iwasa.takahito@hoge repo_mfa % git add .
iwasa.takahito@hoge repo_mfa % git commit -m "modify hogehoge"
[hogehoge d20d22c] modify hogehoge
 1 file changed, 1 insertion(+), 1 deletion(-)
iwasa.takahito@hoge repo_mfa % git push --set-upstream origin hogehoge
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Writing objects: 100% (3/3), 257 bytes | 257.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To ssh://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/repo_mfa
 * [new branch]      hogehoge -> hogehoge
Branch 'hogehoge' set up to track remote branch 'hogehoge' from 'origin'.

マネージドコンソールからリモートブランチの反映も確認出来ました。

さいごに

今回はSSHアクセスの設定からポリシーの変更、どういったエラーになるのかなどをご紹介しました。
MFAの拒否設定を緩和している形ですので、別の認証方法を採用する、git-remote-codecommitを導入するなどのそもそもの部分も検討しましょう。