Claude Media
Google CloudのMCPサーバーをIAMで権限制御する

Google CloudのMCPサーバーをIAMで権限制御する

Google CloudのMCPサーバーは、mcp.tools.callという専用パーミッションとroles/mcp.toolUserなどのIAMロールでアクセスを統治します。デナイ/アローポリシーの書き方を確認します。

Google CloudのMCPサーバーは、BigQueryやCloud StorageなどのAPIをGoogleがホストしてMCP経由で公開する仕組みです。ツール呼び出しには、通常のリソース権限とは別にmcp.tools.callという専用パーミッションが必要です。IAMのdeny policyとallow policyを組み合わせれば、誰が、どのサービスの、どのツールを呼べるかまで細かく制御できます。

Google CloudのMCPサーバーとは — BigQueryやCloud Storageをホスト型で公開する仕組み

Google CloudのMCPサーバーは、GoogleのインフラでMCPエンドポイントを動かし、HTTPでAIアプリケーションに公開するリモート型のサーバーです。BigQuery・Cloud Storage・Compute Engineなど、プロダクトごとにエンドポイントがあります。たとえばBigQueryはhttps://bigquery.googleapis.com/mcpです。

ローカルで動く「gcloud MCPサーバー」(googleapis/gcloud-mcp)とは別の製品です。そちらの権限モデルはgcloudのMCPサーバーでGoogle Cloudを自然言語操作するで扱っています。ここではGoogleがホストするリモート型を、IAMで制御する話に絞ります。

Claude.ai・Claude Code・Claude Desktopからは、カスタムコネクタとして接続します。Google CloudのIAMで制御できるのはGoogle Cloud側のMCPサーバーだけで、Google Cloud以外のMCPサーバーには効きません。

ツールを呼ぶ前に、対象プロダクトのAPIをプロジェクトで有効化しておきます。必要なのはserviceusage.services.enableを含むService Usage Admin(roles/serviceusage.serviceUsageAdmin)です。

gcloud services enable bigquery.googleapis.com

サービス名はサーバーごとに違い、Compute Engineならcompute.googleapis.comです。有効化していないサービスには、IAMを整えても接続できません。

呼び出しが通るまでに確認される2つの権限

ツールを呼ぶプリンシパル(利用者やエージェント)には、次の2つが両方必要です。

くらべる

MCP呼び出しに必要な2つの権限

プロジェクト単位

MCP側の権限

mcp.tools.callをGoogle Cloudプロジェクトに対して持っていることです。MCPのツール呼び出しという行為そのものを許可する権限で、サービスの種類に関係なく同じ権限が使われます。

API単位

リソース側の権限

呼び出すAPIが通常要求する権限です。BigQueryのデータセットのメタデータを取るならbigquery.datasets.getが要ります。

公式の例では、mcp.tools.callだけ持っていても、bigquery.datasets.getだけ持っていても呼び出しは失敗します。MCP経由のアクセスを止めたいとき、リソース側の権限を外すだけでは足りません。mcp.tools.callを含むロールの付与先も確認対象になります。

定義済みIAMロール — MCP AdminとMCP Tool User

定義済みのロールは2つで、含まれる権限は同じ3つです。

ロール説明含まれる権限
MCP Admin(roles/mcp.admin)説明Google管理のMCPサーバーとやり取りするためのフルアクセス含まれる権限mcp.tools.call / resourcemanager.projects.get / resourcemanager.projects.list
MCP Tool User(roles/mcp.toolUser)説明親プロジェクトで有効化されたMCPサーバーのツールを呼ぶ権限含まれる権限mcp.tools.call / resourcemanager.projects.get / resourcemanager.projects.list

mcp.tools.callは、この2つ以外のロールにも入っています。OwnerとEditor、Gemini Cloud Assistの3ロール、roles/admin、roles/writerが該当します。サービスエージェント用のChronicle Service Agentも含みます。

つまり、すでにOwnerやEditorを持つ人は、roles/mcp.toolUserを付けなくても、mcp.tools.callという権限条件の1つは満たします。「MCP用ロールを誰にも付けていないからMCPは使われない」とは言えません。棚卸しはMCP用ロールの付与先ではなく、mcp.tools.callを含む全ロールの付与先で行います。

deny/allowポリシーで使える4つの属性

IAMの条件式には、MCP呼び出しに固有の属性を使えます。ポリシーの種類によって使える属性が違います。

属性内容deny policyallow policy
tool.isReadOnly内容呼び出すツールが読み取り専用かdeny policy✓allow policy—
request.auth.oauth.client_id内容呼び出し元のOAuthクライアントIDdeny policy✓allow policy—
resource.service内容対象サービス名(例: bigquery.googleapis.com)deny policy✓allow policy✓
tool.name内容MCPツール名(例: list_agents)deny policy✓allow policy✓

request.auth.oauth.client_idはdeny policy専用です。Claude向けに発行したOAuthクライアントIDを条件に置けば、特定のクライアント経由の呼び出しだけを止められます。

全ユーザーのMCPツール利用を禁止するdeny policy

もっとも単純な例は、プロジェクト内のすべてのユーザーに対してMCPツールの利用自体を禁止するポリシーです。

{
  "displayName": "Deny access to MCP tools for all users",
  "rules": [
    {
      "denyRule": {
        "deniedPrincipals": ["principalSet://goog/public:all"],
        "deniedPermissions": ["mcp.googleapis.com/tools.call"]
      }
    }
  ]
}

このポリシーを適用すると、クライアントがtools/callを呼んだ際にHTTPエラーが返るようになります。

書き込み系ツールだけを禁止するdeny policy

読み取り専用でないツール、つまり作成・変更・削除を伴うツールの呼び出しだけを止めたい場合は、tool.isReadOnly属性を条件に使います。

{
  "rules": [
    {
      "denyRule": {
        "deniedPrincipals": ["principalSet://goog/public:all"],
        "deniedPermissions": ["mcp.googleapis.com/tools.call"],
        "denialCondition": {
          "title": "Deny read-write tools",
          "expression": "api.getAttribute('mcp.googleapis.com/tool.isReadOnly', false) == false"
        }
      }
    }
  ]
}

作成したポリシーはpolicy.jsonとして保存し、次のコマンドでプロジェクトに適用します。

gcloud iam policies create mcp-deny-policy \
  --attachment-point=cloudresourcemanager.googleapis.com/projects/PROJECT_ID \
  --kind=denypolicies \
  --policy-file=policy.json

deny policyは組織やフォルダにも付けられ、配下のプロジェクトに継承されます。組織に付けるなら、アタッチ先を--attachment-point=cloudresourcemanager.googleapis.com/organizations/ORG_IDにします。フォルダはfolders/FOLDER_IDです。

否定条件のdeny policyで「許可リスト」を作る

公式は、deny policyで「指定したもの以外すべて拒否」する書き方も示しています。許可の側に回すわけではなく、条件式を否定にして、例外だけを拒否の対象から外します。

くらべる

サービスの絞り込み方は2通りある

プリンシパルに付与

allow policy

roles/mcp.toolUserのバインディングに条件式を付け、特定のユーザーへ特定のサービスだけを許可します。付与先は個別に指定します。

全員から拒否

否定条件のdeny policy

全プリンシパルを対象に、条件式を!(resource.service == 'compute.googleapis.com')のように否定にします。Compute Engine以外のMCP呼び出しが全員分止まります。

否定の!を外してresource.service == 'bigquery.googleapis.com'とすれば、そのサービスだけを全員分止められます。クライアントIDでも同じ型を使えます。!(request.auth.oauth.client_id == 'CLIENT_ID')とすれば、そのクライアント以外からの呼び出しが拒否されます。クライアントIDはGoogle Cloudコンソールの「Google Auth Platform > Clients」で確認します。この属性はallow policyでは使えないので、クライアント単位の制御はdeny policyでしか書けません。

特定サービスだけをMCP経由で許可するallowポリシー

allow policyでは、roles/mcp.toolUserのようなIAMロールに条件式を組み合わせて、プリンシパルがMCP経由でアクセスできるサービスを絞り込めます。次の例はuser@example.comにBigQueryとCloud StorageのMCPサーバーだけを許可する設定です。

{
  "bindings": [
    {
      "role": "roles/mcp.toolUser",
      "members": ["user:user@example.com"],
      "condition": {
        "title": "Allow MCP calls for BigQuery and Cloud Storage MCP servers",
        "expression": "resource.service == 'bigquery.googleapis.com' || resource.service == 'storage.googleapis.com'"
      }
    }
  ]
}

tool.name属性を条件に加えれば、サービス単位ではなく個別ツール単位での許可もできます。Compute Engineのlist_instancesツールだけを許可するなら、条件を2つ用意します。

  • resource.service == 'compute.googleapis.com'
  • api.getAttribute('mcp.googleapis.com/tool.name', '') == 'list_instances'

この2つを&&でつなぎます。

制限事項

IAMによるMCP制御には、次の制限があります。

  • request.auth.oauth.client_idはdeny policyでのみ使えます
  • これらの属性はmcp.tools.callに対してのみ検証され、deny policy内で他のパーミッションと組み合わせられません
  • タグはresource.serviceやMCP属性と同じ条件式に混ぜられません
  • resource.serviceとtool.nameはGoogle Cloudコンソールでは扱えず、gcloud CLIでの管理が前提です
  • mcp.tools.callはプロジェクト単位で検査されるため、Resource Manager MCPサーバーのようにプロジェクトに紐づかないAPIには、MCP属性での制御が効きません

適用後の確認 — 監査ログとtools/listの見え方

ポリシーを入れたあと、ログで効き方を確かめられます。MCPサーバーの監査ログはサービスごとに出るので、次のフィルターで絞ります。

protoPayload.serviceName="bigquery.googleapis.com/mcp"

注意点は、MCPのData Accessログが既定で無効なことです。ログが大きくなりやすいため、書き出すには明示的な有効化が必要で、Cloud Loggingの利用料が追加で発生することがあります。MCPだけに絞るなら、サービス「Google Cloud MCP servers」のDATA_READタイプを有効にします。

もう1つ、deny policyを入れてもtools/listは成功し、読み書き両方のツールを含む全ツールの一覧が返ります。一覧に出ることと呼べることは別なので、エージェントのツール一覧に書き込み系が見えても、拒否はtools/callの時点で起きます。

Claude Code・Claude.aiから接続するときの設定

3つのクライアントとも、Web applicationタイプのOAuthクライアントを作ります。リダイレクトURIはhttps://claude.ai/api/mcp/auth_callbackです。違いは1点で、Claude.aiの手順だけ「承認済みのJavaScript生成元」にhttps://claude.aiを追加します。Claude CodeとClaude Desktopの手順にはこの項目がありません。作成後に表示されるシークレットは一度しかコピーできません。

手順

接続前に確認する順序

  1. 1

    MCP用ロールの付与

    利用者にroles/mcp.toolUserを付けます。公式のクライアント設定ガイドも、このロールをプロジェクトに付与するよう案内しています。

  2. 2

    プロダクトAPIの有効化

    gcloud services enableで対象サービスを有効にします。

  3. 3

    カスタムコネクタの登録

    OAuthのクライアントIDとシークレットを、コネクタの詳細設定に入力します。サーバーURLとトランスポート(Streamable HTTP)も入力します。スコープは各サーバーのドキュメントに従い、BigQueryならhttps://www.googleapis.com/auth/bigqueryの形式です。

接続後にできる操作は、IAMのポリシーと、認可したアカウントのロールで決まります。自分のユーザー認証でつなぐと、MCPクライアントは本人と同じ権限を持ち、操作も本人の名義で記録されます。本番用途では、本人とは別のエージェントIDやワークロードIDを作る方法が案内されています。権限を絞れ、ログでMCP経由の操作を見分けられるためです。スコープは接続時のOAuth設定で指定し、IAMの許可はツールを呼ぶたびに評価されます。

コネクタの作り方はCoworkカスタムコネクタ自作ガイドにあります。Google Cloud上でのチーム展開はClaude Code Vertex AI IAM設定とチーム展開ガイドにあります。

ツール数が多いときはツールセットで絞る

1つのMCPサーバーにツールが60個以上ある例が公式にあります。そのままつなぐとエージェントの文脈を圧迫するため、一部のサーバーは「ツールセット」を用意しています。ツールセットは専用のエンドポイントを持つツールの部分集合で、エージェントからは別のMCPサーバーに見えます。同じサーバーから15個だけ使う例が挙がっています。使えるかどうかはサーバーごとのリファレンスで決まります。

IAMのポリシーが「呼べるか」を絞るのに対し、ツールセットは「見えるか」を絞ります。ツールセットで候補を減らしたうえで、書き込みはdeny policyで止める、という重ね方もできます。

既知の問題として、Compute Engineのlist_imagesツールはfedora-cloudのような公開イメージを引くと権限エラーで失敗します。IAMを疑う前に、このツール固有の問題でないかを確認する価値があります。

まとめ

止めたい範囲によって、使うポリシーの型が変わります。全面停止なら全員を対象にしたdeny、書き込みだけならtool.isReadOnly条件のdenyです。特定サービスだけ止めるならresource.service条件のdeny、指定サービス以外を止めるなら否定条件のdenyを使います。特定クライアント以外を止めるときも否定条件のdenyで、組織全体に敷くならアタッチ先を組織にします。

この記事を共有:XはてブLinkedIn