Claude Media
MCPで本番環境に接続する権限設計 — 読み取り専用ロールと承認フロー

MCPで本番環境に接続する権限設計 — 読み取り専用ロールと承認フロー

本番のデータベースやクラウド、IaCにMCPで接続する前提の権限設計を扱います。バックエンド側で読み取り専用ロールをどう作るか、書き込みをどこで人の承認に止めるかを横断でまとめます。

本番のデータベースやAWSアカウント、Kubernetesクラスタ、HCP TerraformにMCPで接続するとき、決めるべきことは2つです。接続する側に何をさせないか(読み取り専用ロールの設計)と、残った操作のうちどこで人の承認を挟むか(承認フローの設計)です。MCPサーバーごとの許可ルールの構文はMCPセキュリティガイドにまとめています。本記事はその手前、バックエンド側でどう読み取り専用を作るか、複数のプロダクトに共通する承認フローの設計原則を扱います。

本番接続の権限設計はallow/denyルールとは別の層

Claude Codeの許可ルール(allow / deny / ask)は、Claude Code自身がどのツール呼び出しを実行するかを制御します。しかしこれは、MCPサーバーの向こう側にあるデータベースやクラウドAPIが実際に何を許可するかとは無関係です。allow ruleで書き込みツールを許可していても、接続先のDBユーザーが読み取り専用なら書き込みは失敗します。逆に接続先の権限が強すぎれば、Claude Code側のルールをどれだけ絞ってもバックエンド側で防御しきれません。本番接続の安全性は、まずバックエンド側の権限をどう絞るかで決まります。

読み取り専用ロールをどう作るか

バックエンドごとに「読み取り専用」の実装方法が違います。

バックエンド読み取り専用の作り方参考
リレーショナルDB読み取り専用の作り方接続文字列に渡すDBユーザー自体をSELECT権限のみで作成する参考MCPでデータベースに接続する
Kubernetes読み取り専用の作り方専用ServiceAccountを読み取り専用RBAC Roleに紐付け、--read-onlyフラグと併用する参考Kubernetes MCPサーバーの権限設計
AWS(CloudFormation診断)読み取り専用の作り方IAMポリシーをDescribe*系アクションとcloudtrail:LookupEventsのみに絞る参考CloudFormation/CDKをMCPで自動検証する
HCP Terraform読み取り専用の作り方registryツールセットのみ有効にし、TFE_TOKEN自体を渡さない参考Terraform MCPサーバーの使い方

共通しているのは、MCPサーバーの設定でなく、接続先の認証情報そのものを読み取り専用にする点です。DBならユーザー、KubernetesならServiceAccountとRole、AWSならIAMポリシー、Terraformならトークンを渡すか渡さないか。MCPサーバー側のフラグは補助に過ぎず、最後の砦は接続情報の権限範囲です。

MCPサーバー側のフラグだけに頼らない理由

MCPサーバーが持つ「読み取り専用モード」のようなフラグは、実装によって有無も効き方も違います。RabbitMQ向けのMCPサーバーには書き込みツールを既定で無効化する--allow-mutative-toolsのようなフラグがある実装もありますが、同じメッセージングブローカーでもNATSやKafka向けの実装には同種のフラグが無く、書き込みの可否はブローカー側の認証情報に委ねられます。個々の実装が持つフラグはREADMEで確認するほかありません。フラグの有無をあてにせず、まず接続情報自体を読み取り専用にする設計が、どのMCPサーバーを使う場合でも通用します。

MCPが持つ3つの承認ゲート

読み取り専用ロールで防げるのは接続先の書き込みだけです。読み取り専用でも実行してよいか判断が要る操作(大量データの一括取得、外部への通知送信、コスト影響のあるクエリ等)には、MCPプロトコル自体の仕組みで人の承認を挟めます。

1つ目はrequiresUserInteractionアノテーションです。MCPサーバー開発者がツールのtools/list応答に_meta["anthropic/requiresUserInteraction"]: trueを含めると、Claude Codeはそのツールの呼び出しごとに確認ダイアログを出します。acceptEditsautobypassPermissionsのどのモードでも省略されず、「次回から確認しない」の選択肢もありません。非対話モードの--permission-prompt-tool経由では自動許可に変換されず拒否扱いになるため、承認が確実に人に届く設計です。同意そのものが目的のツール(アクセス許可の付与等)に向く仕組みです。

2つ目はelicitation(構造化入力の要求)です。MCPサーバーがタスクの途中で追加情報を必要とするとき、フォーム形式かURL形式のダイアログをClaude Codeが自動的に表示します。設定は不要で、サーバー側がリクエストするだけで発動します。認証やスコープ確認をタスクの途中に挟みたい場合に使えます。

3つ目は組織単位のツール制御です。claude.aiコネクタ経由のツールに組織がaskまたはblockedを設定すると、Claude Codeは起動時にこの設定を読み込んでローカルで強制します。askはどの権限モードでも毎回確認を求め、blockedはツールがそもそも渡されません。個人の許可ルールでは上書きできない、組織側からの一元的な制御です。

何を承認必須にすべきか

3つのゲートを全ての操作に付けると、確認疲れで承認そのものが形骸化します。承認必須にすべきは取り消せない操作影響範囲が広い操作に絞ります。デプロイ・削除・大量データの外部送信は候補になりますが、単純な一覧取得や単一レコードの参照までゲートする必要はありません。

この絞り込みの手がかりになるのが、IaC系のMCPサーバーに共通する「プレビューしてから適用する」構成です。Pulumi MCPサーバーのpulumi-cli-previewpulumi-cli-upの前に必ず差分を確認する設計で、Terraform MCPサーバーもワークスペースの実行系ツールはRegistry検索用のツールセットとは別に切り出されています。取り消せない操作の手前に、内容を人が見るタイミングを1つ必ず作るという発想は、MCPサーバーの実装が違っても横展開できます。詳しい比較はIaC MCPサーバー比較にまとめています。

MCP仕様自体もこの考え方を前提にしています。仕様書は「ホストはツールを呼び出す前に明示的なユーザーの同意を得なければならない」と定めており、ツールの説明文はサーバー自身の申告に過ぎず信頼できるサーバーから得たものでない限り信用しない、という原則も示しています。承認フローの設計は、Claude Code固有の機能というより、MCPというプロトコルそのものの前提です。

読み取り専用にしても消えないリスク

読み取り専用ロールは書き込みを防ぎますが、読み取った内容が接続先のAIモデル提供元に送られること自体は止めません。DBの読み取り専用ユーザーであっても、SELECTできる列に個人情報や機密情報が含まれていれば、その内容はクエリの応答としてモデル側に渡ります。読み取り専用ロールを作るときは、書き込み権限だけでなく参照できる列・テーブルの範囲も同時に絞り込みます。組織のデータ取り扱い方針に照らして問題がないかは、接続前に確認しておく事項です。読み取り専用ロールを「書き込みを防ぐ設定」としてだけでなく、「何を見せるかを絞る設定」としても設計します。

elicitationのURL形式ダイアログにも実務上の制約があります。Claude CodeはURLをコマンドライン引数としてシステムのURLハンドラに渡すため、渡せる長さに上限があります。エスケープが必要な文字(%&等)は1文字がエスケープ後4文字分としてカウントされ、そうした文字を含まないURLではおよそ8,000文字、3文字に1回%が入るような込み入ったURLではおよそ4,000文字で上限に達します。上限を超えるURLは、承認を求めるダイアログ自体が表示できず、リクエストを拒否するしかありません。OAuth連携のようにURLが長くなりがちな承認フローを組み込むMCPサーバーを選ぶときは、この制約も設計に含めます。

実際に試す

読み取り専用のDBユーザーで接続する例です。接続文字列自体にSELECT権限のみのユーザーを渡します。

claude mcp add --transport stdio db -- npx -y @bytebase/dbhub \
  --dsn "postgresql://readonly:pass@prod.db.com:5432/analytics"

/mcpdbconnectedと表示されれば、書き込みクエリを投げても接続先のDB権限で拒否される状態です。

横断で確認する設計チェックリスト

複数のバックエンドを同時に扱うプロジェクトでは、接続を追加するたびに次の3点を確認します。①接続情報(DBユーザー・トークン・ServiceAccount)自体を読み取り専用で発行できるか ②MCPサーバー側に書き込みを止めるフラグがあるとしても、それを無効にしてもバックエンド側の権限で二重に防げているか ③残った書き込み操作のうち、取り消せないものだけをrequiresUserInteractionやプレビュー確認の対象にできているか。3つとも「はい」で答えられない接続は、本番に向ける前に権限設計を見直す対象です。チェックの順序も重要で、①のバックエンド側の絞り込みを飛ばして③の承認ゲートだけで守ろうとすると、MCPサーバーの実装差にそのまま安全性が左右されます。

よくあるつまずき

MCPサーバーのフラグだけで安全だと判断してしまう。フラグの有無は実装ごとにばらつきます。フラグが無い実装に接続する前提で、まず接続情報自体の権限を絞ります。

承認ゲートを全操作に付けて形骸化させるrequiresUserInteractionを多用しすぎると、確認ダイアログに慣れて内容を読まずに承認する運用になりがちです。取り消せない操作だけに絞ります。

組織のツール制御をローカルの許可ルールで上書きできると思い込むaskblockedが設定されたツールは、個人のallow ruleを書いても毎回確認かブロックのままです。

まとめ

本番環境へのMCP接続で最初に決めるべきは、Claude Code側の許可ルールではなくバックエンド側の権限です。DBユーザー・ServiceAccount・IAMポリシー・APIトークンのいずれも、まず読み取り専用で作れるかを確認します。そのうえで、取り消せない操作だけをrequiresUserInteractionやプレビュー確認のような承認ゲートに絞って残す設計が、MCPサーバーの実装差に左右されない共通のやり方です。Kubernetesクラスタへの具体的な実装手順はKubernetes MCPサーバーの権限設計、MCPサーバーごとの許可ルールの書き方はMCPセキュリティガイドを参照してください。

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