Files
obsidian-vault/Research/Gatekeeper Architecture for Agent Tool Calls.md
T

121 lines
18 KiB
Markdown
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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) для апелляций и итерации правил.