複数のCodeCommitリポジトリに、プロファイル毎の認証情報ヘルパーを使用してアクセスする設定

2021.07.01

データアナリティクス事業本部の笠原です。

複数のプロジェクトでCodeCommitを使っていると、AWSアカウントが異なる関係で、各リポジトリで認証情報が異なるケースが出てきます。AWSの認証情報はプロファイル毎に分かれて保存していると思いますが、CodeCommitを利用する際にどのように切り替えていけばいいでしょうか。

ローカルPCからCodeCommitへアクセスする際の認証方法には以下の方法が考えられます。

  1. Git認証情報を使って、HTTPS接続
  2. git-remote-codecommit を導入して、HTTPS接続
  3. AWS CLI認証情報ヘルパーを使って、HTTPS接続
  4. SSH接続

私は git-remote-codecommit を導入してアクセスするのですが、 git-remote-codecommt はpipのライブラリですので、場合によってはPythonが導入できないケースがあるかもしれません。

今回はAWS CLI認証情報ヘルパーを使って、複数のCodeCommitリポジトリへアクセスするケースがあったので、どのように設定すれば良いか調べました。

まとめ

  • gitのglobal configに、以下のコマンドを実行して設定追加
    git config --global "credential.https://git-codecommit.*.amazonaws.com/v1/repos/<リポジトリ名>.helper" '!aws codecommit credential-helper $@ --profile <profile名>'
    git config --global "credential.https://git-codecommit.*.amazonaws.com/v1/repos/<リポジトリ名>.UseHttpPath" true
  • または、設定ファイルに以下を追記
    [credential "https://git-codecommit.*.amazonaws.com/v1/repos/<リポジトリ名>"]
            helper = !aws codecommit credential-helper $@ --profile <profile名>
            UseHttpPath = true
  • git-remote-codecommit が導入できる環境なら、 git-remote-codecommit を使おう

認証情報ヘルパー導入のおさらい

以下の公式ドキュメントにあるセットアップ方法を実行しましょう。

流れをざっと説明するとこんな感じ。

  1. CodeCommitにアクセスするためのIAMユーザを作成し、適切な権限を付与
    • AWSCodeCommitPowerUser など
  2. AWS CLIにIAMユーザの認証情報を登録
    • AWS CLIがなければインストール
  3. gitのconfigに認証情報ヘルパーの設定を追加
    • gitがなければインストール
  4. CodeCommitリポジトリのURLを取得して、git clone

認証情報ヘルパーの設定はこんな感じになります。

git config --global credential.helper "!aws codecommit credential-helper $@"
git config --global credential.UseHttpPath true

上記のコマンドを実行すると、globalのconfigに設定されます。設定ファイルの中身はこんな感じになります。

[credential]
    helper = !aws codecommit credential-helper $@
    UseHttpPath = true

リポジトリ毎にプロファイルを切り替えることができれば、複数リポジトリでも対応できそうです。

Gitのcredential設定を確認

Gitのドキュメントを確認してみます。

Git - gitcredentials Documentation

ドキュメントによるとコマンドはこんな感じに実行できるようです。

git config credential.https://example.com.username myusername
git config credential.helper "$helper $options"

コマンド実行すると、設定ファイルは以下のように保存されます。なお、Bashやzshなどで実行すると "$helper $options" の部分が展開されるので、展開されたくない場合は '$helper $options' とシングルクォートでくくりましょう。

[credential "https://example.com"]
        username = myusername
[credential]
        helper = $helper $options

最初の設定で特定のURLのリポジトリに対して、個別の設定を行うことができます。これを使えば、リポジトリ毎にプロファイルを設定できそうです。

試してみる

CodeCommitのリポジトリを2つ用意し、各リポジトリにアクセスするためのIAMユーザを2つ用意して動作確認してみます。

IAMポリシー設定

IAMユーザは AWSCodeCommitPowerUser ポリシーを付与した上で、他のリポジトリへのアクセスは拒否するようにします。

以下は cm-kasahara-user1 ユーザへ付与するインラインポリシーです。 cm-kasahara-repo2 へのアクセスを拒否してます。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Action": [
                "codecommit:*"
            ],
            "Resource": [
                "arn:aws:codecommit:ap-northeast-1:111122223333:cm-kasahara-repo2"
            ]
        }
    ]
}

同様に、 cm-kasahara-user2 ユーザには、 cm-kasahara-repo1 へのアクセスを拒否しておきます。

CLIでの実行確認

次に、AWS CLIにIAMユーザのクレデンシャルを登録しておき、プロファイルで切り替えられるようにします。試しにCLIでの実行結果を確認しておきます。

aws codecommit list-repositories --profile cm-kasahara-user1
{
    "repositories": [
        {
            "repositoryName": "cm-kasahara-repo1",
            "repositoryId": "12345678-90ab-cdef-1234-567890abcdef"
        },
        {
            "repositoryName": "cm-kasahara-repo2",
            "repositoryId": "23456789-0abc-def1-2345-67890abcdef1"
        }
    ]
}

リポジトリの一覧は見えました。試しに cm-kasahara-user1 から cm-kasahara-repo1 にアクセスしてみます。

aws codecommit list-branches --repository-name cm-kasahara-repo1 --profile cm-kasahara-user1
{
    "branches": [
        "feature/update_readme",
        "develop",
        "master",
        "feature/newbranch"
    ]
}

ブランチの一覧が見えました。では、cm-kasahara-user1 から cm-kasahara-repo2 にアクセスしてみます。

aws codecommit list-branches --repository-name cm-kasahara-repo2 --profile cm-kasahara-user1
An error occurred (AccessDeniedException) when calling the ListBranches operation: User: arn:aws:iam::111122223333:user/cm-kasahara-user1 is not authorized to perform: codecommit:ListBranches on resource: arn:aws:codecommit:ap-northeast-1:111122223333:cm-kasahara-repo2 with an explicit deny

アクセスが拒否されました。同様に cm-kasahara-user2cm-kasahara-repo1 がアクセス拒否されます。

Git設定

リポジトリ毎にプロファイル設定できればいいので、以下のコマンドを実行して設定します。

git config --global "credential.https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/cm-kasahara-repo1.helper" '!aws codecommit credential-helper $@ --profile cm-kasahara-user1'
git config --global "credential.https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/cm-kasahara-repo1.UseHttpPath" true
git config --global "credential.https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/cm-kasahara-repo2.helper" '!aws codecommit credential-helper $@ --profile cm-kasahara-user2'
git config --global "credential.https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/cm-kasahara-repo2.UseHttpPath" true

設定の際に credential.<リポジトリURL>.helper のように、リポジトリURLを指定してあげます。また、ヘルパーの記述に各リポジトリに対応したユーザのプロファイルを指定します。

実行後、gitのglobal configは以下のようになります。

[credential "https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/cm-kasahara-repo1"]
        helper = !aws codecommit credential-helper $@ --profile cm-kasahara-user1
        UseHttpPath = true
[credential "https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/cm-kasahara-repo2"]
        helper = !aws codecommit credential-helper $@ --profile cm-kasahara-user2
        UseHttpPath = true

SourceTreeで接続確認

普段はCLIでgit操作するのですが、試しにSourceTreeで接続を確認してみます。Mac版での操作になります。Windows版では確認してませんが、同じように動作すると思われます。

まずはcloneしてみます。SourceTreeを起動し、[新規...] → [URLからクローン]を選択します。

URLにリポジトリのURLを入力しましょう。入力すると、認証のポップアップが出てくる場合がありますが、入力せずキャンセルします。

リポジトリURLの記載やAWS CLIの認証情報ヘルパーの記載が正しければ、「これはGitリポジトリです」と表示されてclone可能になりますが、正しくなければ「有効なソースパス/URLではありません」と表示され、リンク先にエラー内容が表示されます。

私の環境の場合、以下のエラーが出力されました。

abort: HTTP Error 403: 
fatal: not a git repository (or any of the parent directories): .git
aws codecommit credential-helper $@ --profile cm-kasahara-user1 get: aws: command not found
User cancelled password prompt.fatal: unable to access 'https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/cm-kasahara-repo1/': The requested URL returned error: 403

エラーの内容を見ると、SourceTreeがawsコマンドを認識できていないようなので、git config にawsコマンドをフルパスで記述して解消しました。

[credential "https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/cm-kasahara-repo1"]
        helper = !/usr/local/bin/aws codecommit credential-helper $@ --profile cm-kasahara-user1
        UseHttpPath = true
[credential "https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/cm-kasahara-repo2"]
        helper = !/usr/local/bin/aws codecommit credential-helper $@ --profile cm-kasahara-user2
        UseHttpPath = true

Gitリポジトリと認識できたらcloneしてみましょう。無事cloneできたら、成功です。

別のリポジトリもcloneしてみましょう。

無事cloneできました。リポジトリ毎に適切なプロファイルで認証してアクセスできています。

以降、リポジトリのpush、fetchなどの操作時には認証情報入力のポップアップは表示されません。もし、表示される場合は、SourceTree操作中にgitのsystem configに credential.helper の設定が入っている場合が考えられます。その場合、systemのconfigにある credential.helper の設定をコメントアウトしてみる等の対応が必要です。

参考: gitのcredential.helperを理解してCodeCommitの403エラーを回避してみた | DevelopersIO

最後に

いかがでしょうか。認証情報ヘルパーを使用して複数のCodeCommitリポジトリにアクセスすることが確認できました。

ただし、AWSの公式ドキュメントでは認証情報ヘルパーではなく git-remote-credential を使うことが推奨されています。 git-remote-credential を使うことができるのであれば、積極的に git-remote-credential を使っていきましょう。

git-remote-codecommit を使用して AWS CodeCommit への HTTPS 接続をセットアップする手順 - AWS CodeCommit