downscoping-mcp
downscoping-mcp
Понижение привилегий учетных данных пользователя до настраиваемого подмножества для использования инструментами ИИ. Пользователю уже должен быть предоставлен набор разрешений для повседневной работы, который соответствует службам в определенных проектах GCP или учетных записях AWS. Понижение привилегий (downscoping) относится к дальнейшему ограничению действий в соответствии с корпоративными стандартами.
Предоставление разрешений обычно выглядит как <Action allowed> on <Resource>. Понижение привилегий влияет на <Action allowed>, уменьшая возможности, например, с чтения/записи до «только чтение».
Примеры
Разрешить чтение, но не запись документов Google Drive
Разрешить чтение PR в GitHub, но не слияние или утверждение
Разрешить чтение логов, но не развертывание в проекте GCP
Проблема
Claude Code работает с любыми учетными данными, присутствующими в вашей среде. Модель, которая может читать файлы, также может вызвать gh repo delete, gcloud projects delete или aws iam delete-user — используя тот же токен. Одного джейлбрейка, промпт-инъекции или атаки типа «confused-deputy» достаточно, чтобы нанести ущерб. То же самое касается случайных ошибок — если Claude выполнит push напрямую в релизную ветку, это может запустить конвейер развертывания, если защита веток или GitHub Actions настроены неправильно.
Related MCP server: MCP Airlock
Почему такой подход?
Очевидная альтернатива — создание выделенных IAM-ролей или сервисных аккаунтов с низкими привилегиями для использования ИИ — по одному на команду, на среду. Это быстро упирается в жесткие лимиты.
Типичный ~/.aws/config уже содержит более 60 профилей, охватывающих разные учетные записи и роли. Удвоение этого количества за счет специфичных для ИИ аналогов с пониженными привилегиями означает 120+ профилей, постоянное обслуживание IaC и настройку для каждого инженера в .claude/settings.local.json для подключения нужного профиля. В AWS установлена квота по умолчанию в 1000 IAM-ролей на учетную запись (для более высоких лимитов требуется запрос на увеличение квоты), и каждая новая роль — это еще один объект для аудита, ротации и синхронизации с исходной.
Этот инструмент использует другой подход: динамическое понижение привилегий во время вызова, без затрагивания IAM. Это работает аналогично aws sts assume-role --policy-arns, что ограничивает эффективные разрешения принятой роли пересечением политик роли и предоставленных ARN политик. Здесь пересечение определяется в YAML-файле, зафиксированном в вашем проекте, а не в документе политики IAM, но семантика та же. Используются ваши существующие учетные данные; их эффективные возможности сужаются для каждой операции в соответствии с правилами, которые вы определяете.
Сохраняется одно важное свойство: этот инструмент может только уменьшать привилегии, но никогда не увеличивать их. Он устанавливает защитные барьеры, чтобы использование инструментов ИИ было безопасным и соответствовало корпоративной политике, без необходимости внесения каких-либо изменений в вашу настройку IAM.
Как это работает
Правила оцениваются сверху вниз для каждой команды. Первое совпадение побеждает. Возможны три исхода:
Действие | Поведение |
| Внедрить токен с ограниченными правами для соответствующего слота; команда выполняется |
| Заблокировать команду; попросить Claude предложить пользователю выполнить ее вручную |
| Заблокировать команду; сообщить Claude, что она не разрешена для использования ИИ |
Сообщения о блокировке включают имя правила и совпавший шаблон, поэтому причина всегда ясна.
Уровень 1 — Динамическое понижение привилегий (предпочтительно)
Нативный облачный STS получает ограниченный токен из ваших текущих учетных данных во время вызова. Не требуются новые IAM-роли или предварительно подготовленные токены.
AWS:
sts:GetFederationTokenилиsts:AssumeRoleс встроенной политикой. Эффективные разрешения = пересечение ваших политик идентификации и встроенной политики. См. docs/AWS_DOWNSCOPING.md.GCP: Credential Access Boundary через
sts.googleapis.com. Ограничивает текущий токен конкретными ресурсами и ролями. Поддерживается только для Cloud Storage. Для других служб GCP используется откат к ограничению областей OAuth. См. docs/GCP_DOWNSCOPING.md.
Уровень 2 — Слоты токенов (откат)
Используется, когда динамический API отсутствует. Предварительно подготовленные токены с узкими правами выбираются для каждой операции на основе правил YAML.
GitHub: Детализированные PAT (динамический API понижения привилегий отсутствует). См. docs/GITHUB_DOWNSCOPING.md.
Службы GCP, отличные от GCS: Ограничение области OAuth через
generateAccessToken. Только гранулярность на уровне API.kubectl: Токены Kubernetes ServiceAccount, привязанные к минимальным ролям RBAC. Кластеры EKS и GKE могут использовать динамическое понижение привилегий облачного провайдера — см. docs/KUBECTL_DOWNSCOPING.md.
Два режима принудительного применения
Режим 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 динамический (будущее) | |
Серверы 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