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が通常要求する権限です。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 policy | allow policy |
|---|---|---|---|
tool.isReadOnly | 内容呼び出すツールが読み取り専用か | deny policy✓ | allow policy— |
request.auth.oauth.client_id | 内容呼び出し元のOAuthクライアントID | deny 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.jsondeny 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
MCP用ロールの付与
利用者に
roles/mcp.toolUserを付けます。公式のクライアント設定ガイドも、このロールをプロジェクトに付与するよう案内しています。 - 2
プロダクトAPIの有効化
gcloud services enableで対象サービスを有効にします。 - 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で、組織全体に敷くならアタッチ先を組織にします。