--- tags: - ai-agents - security - guardrails - mcp - policy-engine title: Gatekeeper Architecture for Agent Tool Calls date: '2026-09-29' status: complete --- # Привратник для агентских инструментов: контроль tool calls отдельным слоем (2025–2026) > Исследование: как в агентских системах проверяют и одобряют **каждый tool call** отдельным слоем (policy engine / interception / MCP proxy), а не самим агентом. > Дата: 2026-09-29. Все ссылки проверены. ## Общий вывод Единого стандарта «привратника» в 2025–2026 нет. Сложилось **4 архитектурных уровня**, где может сидеть контроль: 1. **In-harness hooks** (Claude Code PreToolUse, ADK callbacks, LangChain middleware) — контроль внутри runtime агента, ближе к самому агенту. 2. **Policy engines вне агента** (OPA/Rego, Cedar/AVP) — решения принимаются детерминированным внешним движком. 3. **MCP proxy / gateway** — сетевой слой-посредник, фильтрует трафик tool calls в обе стороны. 4. **Guardrail/scan слои** (Invariant, LlamaFirewall, NeMo, Lasso) — ML-классификаторы + правила поверх трафика. Ключевой консенсус: **детерминированные проверки — policy engine; семантические («токсично/инъекция») — ML-классификатор, а не policy**. И любое решение должно быть **explainable + логируемым** (для апелляций и итерации правил). --- ## Подход 1. Claude Code: permissions + PreToolUse hooks **Зрелость: ВЫСОКАЯ (production, v2.x, ноябрь 2025+)** - Трёхуровневая система правил `allow` / `ask` / `deny` с порядком вычисления **deny → ask → allow** (первое совпадение побеждает; специфичность не влияет). - **PreToolUse hook** срабатывает *перед* permission-промптом на **каждый** tool call (кроме `EndConversation`); hook возвращает JSON `{permissionDecision: "deny"|"ask"|"allow", permissionDecisionReason}` и может заблокировать/форсировать промпт/пропустить его. - Hooks — это shell-команды, HTTP-endpoint, MCP tool calls, LLM-промпты или subagents; три уровня конфигурации: event → matcher → handler. - Важно: правила **enforced by Claude Code, not by the model** — инструкции в CLAUDE.md/prompt *не* меняют то, что разрешено. - Deny с bare tool name удаляет инструмент из контекста модели; scoped deny (`Bash(rm *)`) оставляет инструмент, но блокирует вызов. - Источник: https://code.claude.com/docs/en/permissions , https://code.claude.com/docs/en/hooks ## Подход 2. MCP Authorization Spec (OAuth 2.1) + Security Best Practices **Зрелость: СРЕДНЕ-ВЫСОКАЯ (спек в draft/2025-06-18, OPTIONAL, ломающие ревизии)** - Спецификация описывает **transport-level authorization** на основе OAuth 2.1 (RFC6750, RFC8414, RFC7591, RFC8707, RFC9728) только для HTTP-транспорта; STDIO — берёт креды из env, спек не применяет. - Роли: MCP server = OAuth resource server, MCP client = OAuth client, плюс authorization server. Принцип least privilege через `scope` в `WWW-Authenticate`, поддерживается step-up authorization. - Dynamic Client Registration **deprecated** (оставлен для обратной совместимости); вместо него Client ID Metadata Documents. - Отдельный документ **Security Best Practices** покрывает confused deputy, token passthrough, per-client consent, обязательный валидатор `state`, `__Host-` cookies, точный redirect_uri match. - Важное ограничение: авторизация **OPTIONAL** и НЕ покрывает *per-tool-call* политику (какие конкретно инструменты можно звать) — это оставляют приложениям/proxy. - Источник: https://modelcontextprotocol.io/specification/draft/basic/authorization , https://modelcontextprotocol.io/specification/draft/basic/security_best_practices ## Подход 3. OPA (Open Policy Agent) как policy engine для tool calls **Зрелость: ВЫСОКАЯ (CNCF graduated, но agent-интеграции — 2025+, молодые)** - OPA развязывает **policy decision от enforcement**: клиент шлёт JSON input → OPA (Rego + data) → решение. `deny`/`allow`/`requires-approval`/`not-applicable`. - Экспрессивность Rego (Datalog, Тьюринг-полный) позволяет multi-hop решения («может ли агент читать данные проекта из того же отдела»); p99 латентность < 1 ms in-process. - Прямая agent-интеграция: **`@ai-sdk/policy-opa`** (Vercel AI SDK) через `toolApproval` callback — правила вынесены в `.rego`, тестируются `opa test` в CI, меняются без деплоя. Policy `input` несёт `messages` (история tool calls) → правила вида «approval после N записей», «deny второго необратимого действия», бюджет/токен-квоты. - Эмпирическое правило вендора: если можно указать поле в `input` и написать точную проверку — это правильный инструмент; семантику («no toxic content») сюда класть нельзя. - OPA MCP (npm `@orygn/opa-mcp`) даёт агенту 50+ инструментов для authoring/debug Rego. - Источник: https://www.openpolicyagent.org/docs/latest/ , https://ai-sdk.dev/docs/agents/policy-tool-approvals , https://inferensys.com/differences/mcp-security-gateways-and-agent-tool-sandboxes/policy-as-code-engines-for-agents/open-policy-agent-opa-vs-cedar-agent-tool-authorization ## Подход 4. Cedar (AWS) как policy language **Зрелость: СРЕДНЕ-ВЫСОКАЯ (Apache 2.0, AWS Verified Permissions; agent-специфика ранняя)** - Purpose-built язык авторизации: четыре элемента — **principal / action / resource / context** + schema. Схема используется *только* для валидации политик, не при evaluation. - Ключевое преимущество: **ограниченная выразительность намеренно** — делает автоматический анализ политик вычислимо возможным (напр. доказать, что политика никогда не даёт публичный доступ). Это критично для security-аудита. - Интеграция с AWS IAM / Amazon Verified Permissions / Verified Access; p99 < 2 ms (managed). Практический предел ~1000 правил против 10000+ у OPA. - Trade-off: менее выразителен, чем Rego (нет графовых обходов), AWS-центричен; standalone engine требует кастомной интеграции. - MCP-нативной интеграции нет ни у OPA, ни у Cedar — нужен «custom adapter» (отсюда и весь рынок MCP gateway/proxy). - Источник: https://docs.cedarpolicy.com/ , https://inferensys.com/differences/... ## Подход 5. MCP proxy / security gateway (сетевой привратник) **Зрелость: ВЫСОКАЯ популярность, СРЕДНЯЯ зрелость (Invariant acquired by Snyk 2025; Lasso open-source)** - **Invariant Labs: MCP-scan** — два режима: пассивный `scan` (статически ищет tool poisoning / prompt injection в описаниях инструментов) и активный `mcp-scan proxy` (фоновый динамический слой, мониторит и логирует весь MCP-трафик). Guardrails покрывают tool calls/responses, PII/secrets detection, tool restrictions, custom policies. **Tool Pinning** (хэширование) ловит rug-pull атаки; cross-origin escalation → tool shadowing. - **Invariant Guardrails** работает **out-of-band**: ingests execution traces + MCP server definitions → static information-flow analysis над ними, поднимает policy violations (unsafe tool-call sequences). Т.е. контроль отдельным слоем над трейсом, а не в loop. - **Lasso MCP Gateway** (MIT, open source, апр 2025): proxy-and-orchestrator между LLM и другими MCP; перехватывает request/response, mask secrets/PII, блокирует prompt injection и command injection/RCE. Плагины: `basic` (secrets masking), `presidio` (PII), `lasso` (custom policy + injection + harmful content). Унифицированный интерфейс `get_metadata` / `run_tool`. - Паттерн де-факто: **MCP gateway = привратник на сетевом слое**, независимый от агента, применяет фильтры к обеим сторонам трафика. - Источник: https://invariantlabs-ai.github.io/docs/mcp-scan/ , https://www.agentpatternscatalog.org/landing/compositions/invariant-labs/ , https://github.com/lasso-security/mcp-gateway ## Подход 6. Guardrail-фреймворки (ML-слой поверх tool calls) **Зрелость: ВЫСОКАЯ (Meta/Microsoft/NVIDIA — production, но акцент на content/инъекции, не на per-tool authz)** - **LlamaFirewall (Meta)** — «policy engine», оркеструет сканеры: PromptGuard 2 (BERT-классификатор prompt injection), **AlignmentCheck** (аудит chain-of-thought рассуждений агента в реальном времени — ловит goal hijacking / indirect injection), CodeShield (статический анализ LLM-кода, 8 языков), regex/custom. Возвращает `ScanResult {decision, reason, score}`. Поддерживает `scan_replay` по трассам. Реально open source (4.4k★). - **NeMo Guardrails (NVIDIA)** — rails (input/retrieval/dialog/execution/output), Colang flows, YAML. Явно есть **agentic security**: tool call validation (валидирует входы/выходы инструмента до/после вызова), интеграция с LangGraph. Библиотека+микросервис, конфиг переносим. - **Guardrails AI** — validation-фреймворк (Hub валидаторов); в 2026 команда ушла в Harvey (сайт-леденящий), самостоятельный продукт фактически заморожен. - **Prompt Security** — теперь часть **SentinelOne**; предлагает AI Gateway + open-source (ClawSec — integrity/drift detection skills, ps-fuzz — fuzzing промптов). Это скорее enterprise AI gateway, чем tool-level привратник. - Граница: guardrail-фреймворки сильны на *semantic* рисках (инъекции, токсичность, PII), но они **не заменяют** детерминированную авторизацию tool calls. - Источник: https://github.com/meta-llama/PurpleLlama/tree/main/LlamaFirewall , https://docs.nvidia.com/nemo/guardrails/ , https://www.prompt.security/ ## Подход 7. Interception в агентских фреймворках (callbacks / middleware) **Зрелость: ВЫСОКАЯ (first-class API в трёх крупных SDK)** - **OpenAI Agents SDK**: tool guardrails выполняются на **каждой** guarded function-tool invocation (input до, output после), включая локальные MCP-инструменты. Tripwire-механизм: `.tripwire_triggered` → `Input/OutputGuardrailTripwireTriggered`. Есть `run_in_parallel` (быстро, но агент может успеть выполнить tool до отмены) vs blocking (расход до tool execution). Отдельно — sanitized placeholder `"Output withheld by an output guardrail."`. - **Google ADK**: 6 типов callbacks, включая **Before Tool / After Tool**. Return `None` = продолжать, return объект = **override и skip** дефолтного поведения (жёсткий interception). Важный совет вендора: для security guardrails использовать **ADK Plugins**, а не callbacks (модульность). - **LangChain**: `HumanInTheLoopMiddleware` — интерцепт tool calls через `after_model` hook + LangGraph `interrupt()`. Pause-Decide-Resume; решения `approve` / `edit` / `reject` / `respond`; настраивается `interrupt_on` (True/False/config) и **`when` predicate** (условный interrupt, напр. только записи вне `/workspace/`). Требует checkpointer (Postgres/Mongo в проде). - Все три — это «in-harness» привратник: контрольный слой в самом рантайме агента, а не внешний сервис. - Источник: https://openai.github.io/openai-agents-python/guardrails/ , https://google.github.io/adk-docs/callbacks/ , https://docs.langchain.com/oss/python/langchain/human-in-the-loop ## Подход 8. Jev / TypeSafe System One — typed evaluation как гейт **Зрелость: НИЗКО-СРЕДНЯЯ (нишевый, молодой; community-репо 9–18★; сайты-спутники — community)** - **Jev — это НЕ LLM и НЕ drop-in замена модели агента.** «System One model»: принимает `state` + набор **typed questions**, возвращает структурированные ответы — `choice` (с вероятностями по опциям), `score` (по рубрике), `noul` (0–1 для true/false утверждения). Не генерирует текст и не вызывает инструменты. - Паттерн tool-approval: между *намерением* агента и *side effect*. Вопросы: `risk` (score 0–3), `injection` (noul), `exfiltration` (noul). Затем **порог и действие — в ВАШЕМ коде**: `if (risk.score >= 1.5 || injection.noul >= 0.8) deny(); if (risk.score >= 0.5 || exfiltration >= 0.5) askUser(); return allow();` - Ключевая идея: судить **действие, а не payload** — JSON schema валидирует форму (`send_email` с валидным списком адресов), а Jev судит intent/scope/proportionality («уместны ли 214 получателей для этой задачи»). Порог варьируют по «blast radius» (read_only / single_target / external_many). - Позиционирование: «strict-typed decisions by construction», замена хрупкому «верни JSON» промпту. Латентность — сотни миллисекунд на каждый tool call (предупреждают о накоплении). Вендор говорит: **один слой defense-in-depth**, не замена sandboxing/least privilege. - Community-реализации: `leepokai/jev-guard` (18★, deny/ask/allow на каждый tool call + injection flagging), `win4r/jev-security-scan` (ревью skills/MCP кода), `jev-mcp` / `typesafe-mcp`. - Источник: https://typesafe-jev.com/en/use-cases/tool-approval/ , https://jevmodel.org/use-cases/tool-call-guardrails/ , https://docs.typesafe.ai/introduction/coding-agents --- ## Итоговая карта: кто что даёт | Слой | Примеры | Сильная сторона | Слабость | |---|---|---|---| | In-harness hooks/callbacks | Claude Code PreToolUse, ADK, LangChain HITL, OpenAI SDK | Глубокая интеграция, доступ к полному контексту | Привязан к рантайму; «сам агент» часто и решает | | Policy engine | OPA/Rego, Cedar/AVP | Детерминизм, аудируемость, CI-тесты, развязка policy/code | Не понимает семантику; нужен адаптер под MCP | | MCP proxy/gateway | Invariant MCP-scan, Lasso Gateway | Независим от агента, перехват трафика в обе стороны | Доп. hop; статически не видит намерение | | Guardrail/scan | LlamaFirewall, NeMo, Prompt Security | Ловит инъекции/утечки/токсичность | ML-вероятностность; не замена авторизации | | Typed evaluation | Jev / TypeSafe | Судит intent и blast radius, калиброванные вероятности | Молодой, нишевый, добавляет латентность на каждый вызов | **Рекомендуемая композиция «привратника»:** deterministic policy engine (OPA для гибкости / Cedar для аудируемости) на сетевом MCP-proxy слое, дополненный ML-сканером для семантических рисков и typed-оценкой (Jev-подобной) для intent/blast-radius — с логированием каждого решения (probabilities + triggering rule) для апелляций и итерации правил.