タグと拒否ポリシーを使用してリポジトリへのアクセスを制御する

Identity and Access Management(IAM)拒否ポリシーとタグを使用して、Developer Connect 接続の Git リポジトリ リンクに対する特定のオペレーションをブロックできます。

接続にタグを適用し、そのタグに一致する条件を持つ拒否ポリシーを作成します。接続内のすべての Git リポジトリリンクはタグを継承するため、拒否ポリシーは、その接続を介してリンクされているすべてのリポジトリに適用されます。

タグと拒否ポリシーを使用するタイミング

IAM 許可ポリシーは権限を付与します。拒否ポリシーを使用すると、プリンシパルに付与されているロールに関係なく、許可ポリシーよりも優先されるガードレールを設定できます。拒否ポリシーとタグを組み合わせると、プロジェクト内のすべての接続ではなく、選択した接続にこれらのガードレールを適用できます。

たとえば、このアプローチを使用すると、次のことができます。

  • AI エージェントまたは自動化サービス アカウントが Developer Connect を介して commit と pull リクエストを読み取れるようにしますが、本番環境リポジトリで pull リクエストを開いたり、変更したり、コメントしたりできないようにします。
  • 機密性の高いリポジトリにリンクする接続のプリンシパル グループに対して、すべてのリポジトリ オペレーションをブロックします。ただし、同じプロジェクト内の他の接続へのアクセスは維持します。
  • 組織レベルでタグと拒否ポリシーを作成して、複数のプロジェクトに一貫した制限を適用する。

タグが Git リポジトリのリンクに適用される仕組み

Developer Connect では、接続にタグを付けることができますが、Git リポジトリ リンクに直接タグを付けることはできません。

Git リポジトリ リンクは、接続の子リソースです。IAM が Git リポジトリリンクに対するオペレーションの拒否ポリシーを評価するときに、リンクの有効なタグに対して条件が評価されます。有効なタグには、親接続に適用されているタグと、接続のプロジェクト、フォルダ、組織から継承されたタグが含まれます。

Git リポジトリのリンクは接続からタグを継承するため、このドキュメントのコントロールは接続ごとに適用されます。リポジトリごとに異なる制御が必要な場合は、異なる接続を介してそれらのリポジトリをリンクし、各接続に個別にタグを付けます。

始める前に

  • 少なくとも 1 つのリンクされた Git リポジトリとの Developer Connect 接続があることを確認します。
  • 組織 ID と、接続を含むプロジェクトのプロジェクト番号を確認します。
  • このドキュメントのコマンドラインの例を使用するには、Google Cloud CLI をインストールして構成します。

必要なロール

タグの作成、接続へのタグの適用、拒否ポリシーの作成に必要な権限を取得するには、組織に対する次の IAM ロールを付与するよう管理者に依頼してください。

  • タグキーとタグ値を作成して管理する: タグ管理者 (roles/resourcemanager.tagAdmin)
  • タグ値を接続に適用する: タグ値に対するタグユーザー(roles/resourcemanager.tagUser)、接続に対する Developer Connect 管理者(roles/developerconnect.admin)
  • 拒否ポリシーを作成、更新、削除する: 拒否管理者 (roles/iam.denyAdmin)

ロールの付与については、プロジェクト、フォルダ、組織へのアクセス権の管理をご覧ください。

必要な権限は、カスタムロールや他の事前定義ロールから取得することもできます。

拒否できる権限

Git リポジトリのリンクに対して、次の権限を拒否できます。拒否ポリシーでは、developerconnect.googleapis.com/gitRepositoryLinks.PERMISSION 形式を使用します。

リポジトリ データを読み取る

権限 プリンシパルに
developerconnect.googleapis.com/gitRepositoryLinks.fetchCommit commit を取得します。
developerconnect.googleapis.com/gitRepositoryLinks.fetchCommitList commit を一覧表示します。
developerconnect.googleapis.com/gitRepositoryLinks.diffCommit commit 間の差分を取得します。
developerconnect.googleapis.com/gitRepositoryLinks.fetchFileBlame ファイルの blame 情報を取得します。
developerconnect.googleapis.com/gitRepositoryLinks.fetchPullRequest pull リクエストを取得します。
developerconnect.googleapis.com/gitRepositoryLinks.fetchPullRequestList pull リクエストを一覧表示します。
developerconnect.googleapis.com/gitRepositoryLinks.fetchGitRefs ブランチとタグを一覧表示します。

リポジトリ データを変更する

権限 プリンシパルに
developerconnect.googleapis.com/gitRepositoryLinks.openPullRequest pull リクエストを開きます。
developerconnect.googleapis.com/gitRepositoryLinks.modifyPullRequest pull リクエスト(タイトル、説明、状態など)を変更する。
developerconnect.googleapis.com/gitRepositoryLinks.addPullRequestComment pull リクエストにコメントを追加します。
developerconnect.googleapis.com/gitRepositoryLinks.addPullRequestReviewComment pull リクエストにレビュー コメントを追加する。

アクセス トークンと Git プロキシ

権限 プリンシパルに
developerconnect.googleapis.com/gitRepositoryLinks.fetchReadToken リポジトリの読み取り専用アクセス トークンを取得します。
developerconnect.googleapis.com/gitRepositoryLinks.fetchReadWriteToken リポジトリの読み取り / 書き込みアクセス トークンを取得します。
developerconnect.googleapis.com/gitRepositoryLinks.gitProxyRead Developer Connect プロキシを介してリポジトリから読み取る。
developerconnect.googleapis.com/gitRepositoryLinks.gitProxyWrite Developer Connect プロキシを介してリポジトリに書き込みます。

拒否ポリシーでサポートされている権限の一覧については、拒否ポリシーでサポートされている権限をご覧ください。

タグを作成して接続に適用する

この例では、read-only という名前のタグ値を持つ scm-agent-access という名前のタグキーを作成し、そのタグ値を接続に適用します。

  1. タグキーを作成します。次のコマンドは、組織にタグキーを作成します。これにより、任意のプロジェクトの接続でタグキーを使用できます。

    gcloud resource-manager tags keys create scm-agent-access \
        --parent=organizations/ORGANIZATION_ID \
        --description="Controls agent access to Developer Connect repositories"

    ORGANIZATION_ID は、実際の組織 ID に置き換えます。

    --parent を projects/PROJECT_ID に設定して、プロジェクトにタグキーを作成することもできます。プロジェクト レベルのタグキーは、そのプロジェクト内のリソースにのみ適用できます。

  2. タグ値を作成します。

    gcloud resource-manager tags values create read-only \
        --parent=ORGANIZATION_ID/scm-agent-access
  3. タグ値を接続に適用します。

    gcloud resource-manager tags bindings create \
        --tag-value=ORGANIZATION_ID/scm-agent-access/read-only \
        --parent=//developerconnect.googleapis.com/projects/PROJECT_NUMBER/locations/LOCATION/connections/CONNECTION_ID \
        --location=LOCATION

    次のように置き換えます。

    • PROJECT_NUMBER: 接続を含むプロジェクトのプロジェクト番号。
    • LOCATION: 接続のリージョン(例: us-central1)。
    • CONNECTION_ID: 接続の ID。
  4. タグが接続に適用されていることを確認します。

    gcloud resource-manager tags bindings list \
        --parent=//developerconnect.googleapis.com/projects/PROJECT_NUMBER/locations/LOCATION/connections/CONNECTION_ID \
        --location=LOCATION

タグの作成と適用については、タグの作成と管理をご覧ください。

拒否ポリシーを作成する

次の拒否ポリシーは、接続に scm-agent-access タグが read-only に設定されている Git リポジトリ リンクで、サービス アカウントが pull リクエストを開く、変更する、コメントする、読み取り / 書き込みトークンを取得する、Developer Connect プロキシを介して書き込むことを防止します。許可ポリシーでこれらの権限が付与されている場合、サービス アカウントは引き続き commit と pull リクエストを読み取ることができます。

  1. 次の内容で policy.json という名前のファイルを作成します。

    {
      "displayName": "Read-only Developer Connect access for agents",
      "rules": [
        {
          "denyRule": {
            "deniedPrincipals": [
              "principal://iam.googleapis.com/projects/-/serviceAccounts/SERVICE_ACCOUNT_EMAIL"
            ],
            "deniedPermissions": [
              "developerconnect.googleapis.com/gitRepositoryLinks.openPullRequest",
              "developerconnect.googleapis.com/gitRepositoryLinks.modifyPullRequest",
              "developerconnect.googleapis.com/gitRepositoryLinks.addPullRequestComment",
              "developerconnect.googleapis.com/gitRepositoryLinks.addPullRequestReviewComment",
              "developerconnect.googleapis.com/gitRepositoryLinks.fetchReadWriteToken",
              "developerconnect.googleapis.com/gitRepositoryLinks.gitProxyWrite"
            ],
            "denialCondition": {
              "title": "Connection is tagged scm-agent-access=read-only",
              "expression": "resource.matchTag('ORGANIZATION_ID/scm-agent-access', 'read-only')"
            }
          }
        }
      ]
    }

    SERVICE_ACCOUNT_EMAIL は、制限するサービス アカウントのメールアドレスに置き換えます。ユーザーやグループなど、他のタイプのプリンシパルを制限するには、プリンシパル ID をご覧ください。

  2. 拒否ポリシーを作成して組織に適用します。

    gcloud iam policies create scm-agent-read-only \
        --attachment-point=cloudresourcemanager.googleapis.com/organizations/ORGANIZATION_ID \
        --kind=denypolicies \
        --policy-file=policy.json

    拒否ポリシーをフォルダまたはプロジェクトに適用することもできます。拒否ポリシーは、アタッチメント ポイントの下にあるすべてのリソースに適用されます。

拒否ポリシーの作成の詳細については、リソースへのアクセスを拒否するをご覧ください。

拒否ポリシーを確認する

タグと拒否ポリシーの変更は結果整合性になります。新しいタグ バインディングまたは拒否ポリシーが有効になるまでに数分かかることがあります。詳細については、タグ変更の影響とアクセス権の変更の伝播をご覧ください。

変更が反映されると、タグ付けされた接続の Git リポジトリ リンクに対する拒否された権限を拒否されたプリンシパルがリクエストすると、HTTP 403 PERMISSION_DENIED エラーで失敗します。エラー メッセージには、権限と Git リポジトリのリンクが記載され、IAM 拒否ポリシーによってアクセスが拒否されたことが示されます。次に例を示します。

Permission 'developerconnect.gitRepositoryLinks.openPullRequest' denied on resource '//developerconnect.googleapis.com/projects/my-project/locations/us-central1/connections/my-connection/gitRepositoryLinks/my-repo' due to an IAM deny policy.

ポリシーで拒否されていない権限のリクエストと、タグのない接続の Git リポジトリ リンクのリクエストは、拒否ポリシーの影響を受けません。

拒否ポリシーがプリンシパルと Git リポジトリリンクに適用されるかどうかを確認するには、Policy Troubleshooter を使用します。

gcloud policy-intelligence troubleshoot-policy iam \
    //developerconnect.googleapis.com/projects/PROJECT_ID/locations/LOCATION/connections/CONNECTION_ID/gitRepositoryLinks/GIT_REPOSITORY_LINK_ID \
    --principal-email=SERVICE_ACCOUNT_EMAIL \
    --permission=developerconnect.googleapis.com/gitRepositoryLinks.openPullRequest

制限を解除する

1 つの接続から制限を削除するには、接続からタグ バインディングを削除します。

gcloud resource-manager tags bindings delete \
    --tag-value=ORGANIZATION_ID/scm-agent-access/read-only \
    --parent=//developerconnect.googleapis.com/projects/PROJECT_NUMBER/locations/LOCATION/connections/CONNECTION_ID \
    --location=LOCATION

すべての接続から制限を削除するには、拒否ポリシーを削除します。

gcloud iam policies delete scm-agent-read-only \
    --attachment-point=cloudresourcemanager.googleapis.com/organizations/ORGANIZATION_ID \
    --kind=denypolicies

制限事項

  • タグは接続ごとに付加されます。タグは接続に適用できますが、Git リポジトリのリンクには適用できません。接続内のすべての Git リポジトリ リンクは、接続のタグを共有します。
  • 拒否条件はタグのみをサポートします。拒否ルールの条件では、resource.matchTag() や resource.hasTagKey() などのタグ関数のみを使用できます。リポジトリ名やその他のリソース属性に基づいて拒否条件を記述することはできません。詳細については、拒否条件をご覧ください。
  • タグキーには名前空間が必要です。resource.matchTag() では、タグキーを略称ではなく、ORGANIZATION_ID/scm-agent-access や PROJECT_ID/scm-agent-access などの名前空間付きの名前で識別します。
  • 変更が反映されるまでに時間がかかる。新しいタグ バインディング、変更されたタグ値、拒否ポリシーはすぐには有効になりません。また、タグを削除してもアクセスはすぐには復元されません。変更のたびに数分かかるため、構成をテストしてから使用してください。
  • 有効なタグが接続に一覧表示されます。Git リポジトリリンクに適用されるタグを表示するには、親接続の有効なタグを一覧表示します。

次のステップ