downscoping-mcp
downscoping-mcp
AIツールで使用するために、ユーザーの認証情報権限を設定可能なサブセットまでダウングレードします。ユーザーには、特定のGCPプロジェクトやAWSアカウントのサービスにマッピングされた、日常業務に必要な権限のサブセットが既に付与されているはずです。ダウンスコーピングとは、企業基準に準拠するためにアクションをさらに制限することを指します。
権限付与は通常「<Action allowed> on <Resource>」という形式です。ダウンスコーピングは、例えば読み取り/書き込みから読み取り専用にするなど、機能を削減することで「<Action allowed>」に影響を与えます。
例
Googleドライブドキュメントの読み取りは許可するが、書き込みは許可しない
GitHubのPR読み取りは許可するが、マージや承認は許可しない
GCPプロジェクトのログ読み取りは許可するが、デプロイは許可しない
問題点
Claude Codeは、環境内に存在する認証情報を使用して実行されます。ファイルを読み取れるモデルは、同じトークンを使用して gh repo delete、gcloud projects delete、または aws iam delete-user を呼び出すこともできます。一度の脱獄(ジェイルブレイク)、プロンプトインジェクション、またはConfused Deputy攻撃で十分な被害が発生します。偶発的なエラーも同様です。Claudeがリリースブランチに直接プッシュすることで、ブランチ保護やGitHub Actionsが正しく設定されていない場合、デプロイパイプラインがトリガーされる可能性があります。
Related MCP server: MCP Airlock
なぜこのアプローチなのか?
明白な代替案は、AI用にチームごと、環境ごとに専用の低権限IAMロールやサービスアカウントを作成することです。これはすぐに厳しい制限に突き当たります。
一般的な ~/.aws/config には、すでに異なるアカウントやロールをカバーする60以上のプロファイルが存在します。これをAI専用のダウンスコープされたプロファイルで倍増させると、120以上のプロファイル、継続的なIaCメンテナンス、そして適切なプロファイルを接続するための .claude/settings.local.json 内のエンジニアごとの設定が必要になります。AWSにはアカウントあたり1,000というデフォルトのIAMロールクォータがあり(上限引き上げには申請が必要)、新しいロールが増えるたびに監査、ローテーション、元のロールとの同期が必要な対象が増えることになります。
このツールは異なるアプローチをとります。IAMに触れることなく、呼び出し時に動的にダウンスコープします。これは aws sts assume-role --policy-arns と同様に機能し、引き受けたロールの有効な権限を、そのロールのポリシーと提供されたポリシーARNの積集合に制限します。ここでは、積集合はIAMポリシー文書ではなく、プロジェクトにチェックインされたYAMLファイルで定義されますが、セマンティクスは同じです。既存の認証情報が使用されますが、定義したルールに従って操作ごとに有効な機能が絞り込まれます。
重要な特性が1つ維持されています。このツールは権限を削減することしかできず、決して増やすことはできません。 IAM設定を変更することなく、AIツールの使用を安全かつ企業ポリシーに準拠させるためのガードレールを設定します。
仕組み
ルールは各コマンドに対して上から順に評価されます。最初に一致したものが適用されます。3つの結果が考えられます。
アクション | 動作 |
| 一致したスロットにスコープされたトークンを注入し、コマンドを実行する |
| コマンドをブロックし、Claudeにユーザーへ手動実行を依頼するよう伝える |
| コマンドをブロックし、ClaudeにAI使用は許可されていないと伝える |
ブロックメッセージにはルール名と一致したパターンが含まれるため、理由は常に明確です。
Tier 1 — 動的ダウンスコーピング(推奨)
ネイティブのクラウドSTSは、呼び出し時に環境認証情報から制限されたトークンを導出します。新しいIAMロールや事前プロビジョニングされたトークンは不要です。
AWS: インラインポリシーを使用した
sts:GetFederationTokenまたはsts:AssumeRole。有効な権限 = IDポリシーとインラインポリシーの積集合。詳細は docs/AWS_DOWNSCOPING.md を参照してください。GCP:
sts.googleapis.comを介したCredential Access Boundary。環境トークンを特定のリソースとロールに制限します。Cloud Storageのみサポート。 その他のGCPサービスについては、OAuthスコープ制限にフォールバックします。詳細は docs/GCP_DOWNSCOPING.md を参照してください。
Tier 2 — トークンスロット(フォールバック)
動的APIが存在しない場合に使用されます。YAMLルールに基づいて、操作ごとに事前プロビジョニングされた狭い範囲のトークンが選択されます。
GitHub: 細粒度PAT(動的ダウンスコーピングAPIは利用不可)。詳細は docs/GITHUB_DOWNSCOPING.md を参照してください。
GCP非GCSサービス:
generateAccessTokenを介したOAuthスコープ制限。APIレベルの粒度のみ。kubectl: 最小限のRBACロールにバインドされたKubernetes ServiceAccountトークン。EKSおよびGKEクラスターは、基盤となるクラウドプロバイダーの動的ダウンスコーピングを使用できます。詳細は docs/KUBECTL_DOWNSCOPING.md を参照してください。
2つの強制モード
モード1 — Bashフック(CLIツール)
PreToolUse フックがすべての Bash ツール呼び出しをインターセプトします。コマンドが既知のサービスバイナリ(gh、gcloud、aws、kubectl)で始まる場合、フックは引数をYAMLルールと照合し、アクションを評価し、スコープされたトークンでコマンドを書き換えるか、ブロックメッセージを出力します。Claudeが書き換えを見ることはありません。
モード2 — MCPプロキシ
MCPプロキシはアップストリームのMCPサーバーをラップします。各ツール呼び出しを転送する前に、同じYAMLルールを適用してその特定のツール用にスコープされたトークンを注入します。現在は github-pr-issue-analyser サーバーをサポートしており、他のサーバーは将来の拡張予定です。
クイックスタート
1. インストール
pip install -e .2. 認証情報の設定
シェルプロファイルまたはCI環境でスコープされたトークンをエクスポートします:
# GitHub (token_slot mode — only option for GitHub)
export GITHUB_TOKEN_READONLY=ghp_... # fine-grained: contents:read, issues:read
export GITHUB_TOKEN_ORG_WRITE=ghp_... # fine-grained: issues:write, pull_requests:write
# GCP (token_slot fallback — preferred is CAB via google.auth.downscoped)
export GCLOUD_TOKEN_VIEWER=ya29....
export GCLOUD_TOKEN_EDITOR=ya29....
# AWS (token_slot fallback — preferred is sts:GetFederationToken)
export AWS_ACCESS_KEY_ID_READONLY=AKIA...3. ポリシーファイルの作成
cp config.example.yaml .claude/downscoping.yaml組織のアクセスモデルに合わせて編集してください。downscope_mode フィールドでサービスごとのメカニズムを選択します:
version: 1
services:
aws:
downscope_mode: sts_policy # Tier 1: derive restricted token from ambient creds
inline_policy:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action: ["s3:GetObject", "s3:ListBucket", "ec2:Describe*"]
Resource: "*"
rules:
- name: "S3 writes require review"
match:
args_pattern: "s3 (cp|mv|rm|sync) .* s3://"
action: review
- name: "IAM mutations denied"
match:
args_pattern: "iam (create|delete|put|attach|detach)"
action: deny
gh:
downscope_mode: token_slot # Tier 2: GitHub has no dynamic API
token_slots:
readonly:
env_var: GITHUB_TOKEN_READONLY
inject_as: GITHUB_TOKEN
org-write:
env_var: GITHUB_TOKEN_ORG_WRITE
inject_as: GITHUB_TOKEN
default_slot: readonly
rules:
- name: "repo deletion denied"
match:
args_pattern: "repo delete|repo rename"
action: deny
- name: "pr merge requires human review"
match:
args_pattern: "pr merge"
action: review
- name: "permitted writes use org-write token"
match:
args_pattern: "pr (create|edit)|issue (create|edit)|push"
action: allow
slot: org-write4. フックの登録
プロジェクトの .claude/settings.json に追加します:
{
"env": {
"CLAUDE_PLUGIN_ROOT": "/path/to/downscoping-mcp"
},
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/pre_tool_use.py",
"timeout": 5
}
]
}
]
}
}5. (オプション) MCPプロキシの有効化
プロジェクトルートの .mcp.json に追加します:
{
"mcpServers": {
"credential-downscope-proxy": {
"command": "python3",
"args": ["-m", "credential_downscope.mcp_proxy"],
"env": {
"PYTHONPATH": "${CLAUDE_PLUGIN_ROOT}/src",
"GITHUB_INTEGRATION_SRC": "/path/to/upstream-mcp-server/src"
}
}
}
}ポリシーファイルリファレンス
ルールアクション
rules:
- name: "human-readable name — appears in block messages"
match:
args_pattern: "<regex matched against CLI args after the binary>"
# OR for MCP tools:
tools: [tool_name_1, tool_name_2]
action: allow # inject scoped token (default if action omitted)
slot: readonly # which token slot to use (action: allow only)
- name: "example deny"
match:
args_pattern: "iam delete"
action: deny # blocked; Claude told it is not permitted for AI use
- name: "example review"
match:
args_pattern: "s3 cp .* s3://"
action: review # blocked; Claude told to ask user to run manuallyルールの順序は重要です — ルールは上から順に評価され、最初に一致したものが適用されます。特定の deny/review ルールは、広範な allow ルールの前に配置してください。
トークン解決順序 (token_slotモード)
現在のプロセス環境から
env_varを読み取る設定されていない場合は、
inject_as変数にフォールバックする(環境認証情報を使用)どちらも設定されていない場合は、コマンドをそのまま通過させる
アーキテクチャ
Claude Code
│
├─ Bash tool call ──► PreToolUse hook (hooks/pre_tool_use.py)
│ │
│ ├─ load .claude/downscoping.yaml
│ ├─ detect service binary
│ ├─ match args against rules → RuleDecision
│ │
│ ├─ action=deny → {"continue": false, "stopReason": "...denied..."}
│ ├─ action=review → {"continue": false, "stopReason": "...run manually..."}
│ └─ action=allow → {"updatedInput": {"command": "TOKEN=value <cmd>"}}
│
└─ MCP tool call ──► credential-downscope-proxy (mcp_proxy.py)
│
├─ match tool name against MCP rules → RuleDecision
├─ inject scoped token into env
└─ forward to upstream MCP serverサポートされているサービス
サービス | バイナリ / インターフェース | ダウンスコープモード | ドキュメント |
GitHub CLI |
| token_slot | |
AWS CLI |
| sts_policy (推奨), token_slot | |
Google Cloud |
| credential_access_boundary (GCS), oauth_scope, token_slot | |
Kubernetes |
| token_slot; EKS/GKE dynamic (将来) | |
MCPサーバー | プロキシ | token_slot |
追加のサービスは config.yaml を拡張することで追加可能です。コードの変更は不要です。
セキュリティ上の注意
トークン値は、細工されたトークン値によるコマンドインジェクションを防ぐため、シェル注入前に
shlex.quoteでエスケープされます。コマンドの前に
TOKEN=valueを付加すると、プロセスリスト (ps aux) でトークンが可視化されます。より高いセキュリティ環境では、ファイル記述子やシークレットマネージャーを介してトークンを注入する認証情報ヘルパーを使用してください。ブロックメッセージには一致したルール名とパターンが含まれるため、理由は常に監査可能です。
環境の
inject_asトークンへのフォールバックは、スコープされたトークンをまだプロビジョニングしていない場合、コマンドが環境認証情報を使用して通過することを意味します。これを強化するにはDOWNSCOPE_REQUIRE_SCOPED=1(将来実装) を設定してください。ローカルパスを含む
.claude/settings.jsonは gitignore に含めるべきです。このリポジトリの.gitignoreを参照してください。
開発
pip install -e .
pytest tests/ライセンス
MIT
This server cannot be deployed
Maintenance
Related MCP Connectors
Security & DLP proxy for MCP: tool-poisoning scans, PII redaction on tool args/results. Beta.
Fail-closed policy guardrails for AI agents running kubectl, terraform, helm, and argocd.
- gatewayOAuthai.sealgate
MCP gateway with runtime security policy, tool-call-level control, and audit of agent actions.
Security firewall for AI agents — scans MCP calls for injection, secrets, and risks.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenancePolicy-enforcing MCP proxy that blocks dangerous tool calls before they execute. Protects credentials, filesystem, shell, and databases across Claude Desktop, Cursor, Windsurf, and OpenClaw.6 npm39Apache 2.0
- AlicenseCqualityDmaintenanceEnables secure, zero-trust access to MCP tools through short-lived, signed capability leases that bind tool execution to specific sessions, intents, and constraints. Prevents prompt injection attacks and privilege escalation with dynamic risk scoring, policy enforcement, and tamper-evident audit logging.41MIT
- AlicenseNot gradedqualityAmaintenanceSecurity gateway for MCP tool calls. Sits between your LLM client and MCP servers, enforcing per-tool policies (allow/block/approve/read-only), logging every call, and pausing dangerous operations for human approval in terminal or Slack.01MIT
- AlicenseNot gradedqualityCmaintenanceRuntime proxy that intercepts and blocks MCP tool calls based on YAML-defined policies, enforcing security rules for AI agents like Claude Code or Cursor.44 npm1Apache 2.0