Перейти к содержанию

Покрытие и ограничения

Эта страница честно описывает, что Agate инспектирует сегодня, а что пересылает без инспекции — чтобы вы разворачивали его, не переоценивая защиту. Модель угроз описывает целевую модель безопасности; эта страница — честное текущее состояние. Полный анализ и дорожная карта по закрытию пробелов находятся в репозитории: docs/design/security-coverage-roadmap.md.

Прочитайте это, прежде чем полагаться на Agate как на единственный барьер

Сейчас Agate обеспечивает авторизацию вызовов инструментов (по имени и по правилам запрета аргументов), редакцию секретов в исходящем тексте, результатах инструментов и состоянии, SSRF-скрин на обеих «ногах», валидацию/ограничение RFC 6902-патчей, fail-closed для битых событий, а также опциональную память реплея между прогонами. Это всё ещё один из слоёв защиты, а не полный «межсетевой экран» (не моделируется семантика состояния) — см. дорожную карту.

Что инспектируется

Событие / ввод Что происходит Может ли политика вмешаться?
TOOL_CALL_* (собранный) буферизуется по id вызова в полный вызов инструмента, затем оценивается; аргументы проверяются на SSRF-URL. Удержанные START/ARGS пересылаются только если вызов разрешён, поэтому конкурентные или незакрытые (без TOOL_CALL_END) вызовы не утекут фреймами запрещённого вызова; незакрытый вызов всё равно оценивается в конце прогона Да — разрешить/запретить по имени и по правилам запрета аргументов ([[policy.tools.deny_arguments]]); SSRF-URL в аргументах отбрасывает вызов
TEXT_MESSAGE_CONTENT / TEXT_MESSAGE_CHUNK текст ассистента сканируется на шаблоны секретов и SSRF-URL (обе формы — с конвертом и самодостаточная) Да — редактировать (литерал или regex); SSRF-URL отбрасывает фрагмент
TOOL_CALL_RESULT содержимое результата сканируется на шаблоны секретов и SSRF-URL Да — редактировать (литерал или regex; поверхность косвенной инъекции / эксфильтрации); SSRF-URL отбрасывает результат
STATE_SNAPSHOT / STATE_DELTA бюджет размера; STATE_DELTA валидируется как корректный RFC 6902-патч и ограничивается (число операций, глубина указателя, размер value на операцию); payload сканируется на маркеры секретов Да — битый патч fail-closed, превышение бюджета отклоняется, маркер секрета запрещается (структурный payload нельзя замаскировать)
Жизненный цикл (RUN_*, STEP_*) порядок проверяется конечным автоматом Run только структурно (без вердикта политики)
«Нога» запроса (RunAgentInput) авторизуется tools[*].name; текст user- и system-сообщений, а также JSON context / forwardedProps / входного state проверяется на маркеры секретов и SSRF-URL (доменные хосты резолвятся и перепроверяются, закрывая DNS-rebinding) Да — отклонить до пересылки
Битые известные события распознанный тип с отсутствующим/пустым обязательным полем нельзя инспектировать → обрабатывается по [policy].on_malformed_event (по умолчанию terminate) Да — по умолчанию fail-closed

Что пересылается без инспекции

Событие / ввод Почему это важно
Семантика патча состояния STATE_DELTA валидируется (корректный RFC 6902) и ограничивается, но прокси не моделирует итоговый документ — не может судить, к каким путям операции должны иметь доступ
RAW, CUSTOM, REASONING_ENCRYPTED_VALUE непрозрачные — пересылаются как есть, не инспектируются
Неизвестные / будущие типы событий AG-UI пересылаются сырыми

Операционные ограничения

  • Аутентификация выключена по умолчанию (открытый прокси). Задайте [proxy].api_keys или поставьте перед Agate шлюз. См. Конфигурацию.
  • Бюджеты против DoS сегодня: глобальный лимит конкурентности, лимит размера тела запроса, таймауты подключения/чтения, бюджет ответа на прогон (max_response_events / max_response_bytes), отрезающий зарвавшегося агента, и опциональный rate-лимит по IP клиента (rate_limit_per_second / rate_limit_burst, по умолчанию выключен), отбрасывающий потоки с 429. IP берётся из пира соединения, поэтому он осмыслен только там, где Agate видит реального клиента.
  • Полнота аудита: записи ставятся в очередь ограниченного outbox, чья заполненность экспортируется (agate_audit_outbox_depth / _capacity). При полном outbox политика [audit].outbox_on_full решает: block (по умолчанию — backpressure на прокси, запись не теряется) или shed (отбросить, с громким логом и счётчиком — не молча). Следите за gauge глубины и счётчиком дропов.
  • Память реплея между прогонами: по умолчанию выключена; включите [policy.session_memory], чтобы запрещённый инструмент (по имени) карантинился до конца сессии — агент не сможет повторить его с другими аргументами в следующем прогоне. Она только добавляет отказ поверх stateless-политики. Ledger — в пределах процесса со скользящим TTL по умолчанию, либо Redis (backend = "redis"), общий для реплик и переживающий рестарт; Redis-backend fail-open — недоступный Redis деградирует до «нет памяти», никогда не wrong-allow.
  • TLS терминируется на прокси (необходимо для инспекции открытого текста); по умолчанию выключен, настраивается в секции [tls].

Дорожная карта

Оставшаяся работа — на перспективу: семантический allowlist путей состояния, плагин-движок политик и sub-IP / per-API-key лимиты — упорядочена в security-coverage-roadmap.md. (Fail-closed для битых событий, правила запрета аргументов, редакция секретов в результатах и состоянии, бюджеты ответа на прогон, SSRF-скрин на обеих «ногах» с резолвом DNS против rebinding, валидация/ограничение RFC 6902-патчей, сигнализация backpressure audit-outbox с политикой block/shed, а также память реплея между прогонами — в пределах процесса или на Redis — уже реализованы.)