Перейти к основному содержимому

Стирание агентом следов делает логи главным доказательством, а не побочным продуктом

Когда агенты могут удалять собственные следы, журналы аудита должны полностью покинуть область записи агента. Паттерн разделения обязанностей для трассировок.

Крупный план серверной стойки с мигающими индикаторами состояния и сетевыми кабелями, символизирующий внешний приёмник логов.

Режим отказа

Агент с доступом к оболочке или файловой системе наследует возможность усекать логи, ротировать файлы и очищать историю. Это не гипотетический крайний случай; это следствие по умолчанию предоставления автономному процессу тех же привилегий, что и человеку-оператору. Если агент может выполнить truncate -s 0 /var/log/agent.log, лог больше не является доказательством. Это удобство.

Самоизменяющиеся среды исполнения усугубляют это. Когда агент может редактировать код, который записывает то, что он сделал, сама инструментация становится частью изменяемой поверхности. Обёртка инструмента, которая записывает структурированное событие перед вызовом внешнего API, может быть переписана так, чтобы не записывать ничего или записывать правдоподобное, но ложное событие. Запись создаётся тем же субъектом, который записывается, поэтому запись наследует стимулы и режимы отказа субъекта.

Постфактумная реконструкция из состояния приложения ненадёжна, когда само состояние было изменено. Если агент удалил строку, обновил поле статуса или откатил транзакцию, сохранившееся состояние отражает мир после действия, а не само действие. Триггеры базы данных и захват изменений данных помогают только в том случае, если они пишут в приёмник, недоступный агенту. В противном случае это просто ещё одна доступная для записи поверхность.

Это ключевая асимметрия: любые доказательства, до которых агент может добраться, — это доказательства, которые агент может удалить. Вопрос не в том, является ли агент враждебным сегодня. Вопрос в том, выживет ли журнал аудита при скомпрометированном агенте, агенте с ошибками или агенте, действующем по запутанной инструкции.

Почему append-only недостаточно

Файлы append-only на доступном для записи томе всё ещё доступны для записи тем же субъектом. Права POSIX, неизменяемые флаги и атрибуты append-only обеспечиваются тем же ядром и тем же контекстом суперпользователя, который агент, возможно, уже занимает. Контейнер с CAP_SYS_ADMIN или том, смонтированный с хоста, может обойти защиты на уровне файлов. Свойство append-only — это соглашение, а не граница, если только хранилище не обеспечивает его против другой идентичности.

Подписывание записей помогает только в том случае, если ключ подписи находится вне досягаемости агента. Если процесс агента хранит закрытый ключ в памяти или читает его из переменной окружения, подпись ничего не доказывает о авторстве. Она доказывает, что кто-то с ключом подписал запись. Хранение ключа должно находиться в отдельном сервисе или аппаратном модуле, который агент не может вызвать для произвольных полезных нагрузок. Даже тогда оракул подписи, который подписывает всё, что отправляет агент, — это резиновый штамп, а не аттестация.

Person touching a plasma ball with colorful electrical filaments in a dark room

Политики хранения, которые удаляют по расписанию, создают законный путь стирания, который выглядит как соответствие требованиям. Тридцатидневное окно хранения — это нормальный операционный выбор. Это также окно, в котором инцидент может устареть до того, как кто-либо начнёт расследование. Если агент может запустить ротацию, компактификацию или правило жизненного цикла, политика хранения становится примитивом стирания с алиби в виде соответствия требованиям.

Практический вывод: append-only, подписывание и хранение — всё это необходимо, но ни одно из них не достаточно. Они уменьшают радиус поражения при случайном удалении. Они не создают границу между агентом и его собственной записью.

Паттерн разделения обязанностей для трассировок

Паттерн просто сформулировать и неудобно реализовать: полностью вынести трассировку из области записи агента.

Записывайте трассировки в приёмник с другой идентичностью и без разрешения на удаление для субъекта агента. Приёмником может быть управляемый сервис логирования, очередь сообщений с отдельными учётными данными производителя или бакет объектного хранилища только для записи. Идентичность агента получает PutRecord и ничего больше. Никакого DeleteObject, никакого PutBucketLifecycle, никакой административной роли. Собственное хранение и удаление приёмника контролируются отдельным субъектом, которого агент не может выдать за себя.

Генерируйте структурированные события на границе инструмента, а не внутри процесса агента, чтобы запись создавалась вызываемой стороной. Если агент вызывает инструмент поиска, событие записывает сервис поиска. Если он вызывает базу данных, событие записывает прокси базы данных. Агент не получает права описывать свои собственные действия; системы, к которым он обращается, описывают их. Это переносит якорь доверия с самоотчёта агента на инструментацию вызываемой стороны. Это также означает, что схема событий принадлежит инструменту, а не промпту агента.

Поддерживайте монотонную последовательность и периодический внешний дайджест, чтобы пробелы были обнаружимы даже при удалении записей. Каждое событие несёт номер последовательности из счётчика, который агент не может сбросить. С фиксированным интервалом внешняя задача вычисляет дайджест по диапазону последовательности и публикует его в отдельный канал. Если позже обнаружится, что в приёмнике отсутствует последовательность 4021, дайджест доказывает, что запись существовала и была удалена. Без дайджеста пробел неотличим от периода затишья.

Конкретный механизм: граница инструмента пишет в локальный Unix domain socket, принадлежащий процессу-сайдкару. Сайдкар хранит учётные данные приёмника, буферизует события, присваивает номера последовательности и пересылает их. Контейнер агента не имеет сетевого маршрута к приёмнику и доступа к файловой системе хранилища учётных данных сайдкара. Сайдкар — единственный писатель. Агент может убить сайдкар, но его убийство также останавливает вызовы инструментов, потому что вызовы инструменто![ClClose-up of suspension bridge cables and tower against a blue sky with cloudsью.

Circuit board macro

Последствия для реагирования на инциденты

Считайте лог, видимый агенту, недоверенным и реконструируйте из приёмника. Локальный лог — это удобство для отладки. Приёмник — это запись. Специалисты по реагированию на инциденты должны рассматривать любое расхождение между ними как сигнал, а не как ошибку синхронизации.

Рассматривайте любой пропущенный номер последовательности как инцидент, а не как ошибку логирования. Пробел означает либо потерю данных приёмником, либо их удаление кем-то. И то, и другое заслуживает вызова дежурного. Дайджест делает эту проверку дешёвой: сравните опубликованный дайджест с пересчитанным дайджестом по сохранённому диапазону. Если они различаются, диапазон был изменён.

Заложите бюджет на стоимость хранения и исходящего трафика для приёмника, недоступного агенту. Это честный компромисс. Приёмник только для записи с независимыми учётными данными, кросс-региональной репликацией и задачей дайджеста стоит дороже локального файла. Исходящий трафик из среды агента в отдельный аккаунт не бесплатен. Хранение в управляемом сервисе тарифицируется за гигабайт и за запрос. Альтернатива — более дешёвая система, чьи доказательства исчезают именно тогда, когда они нужны.

Стоимость не только денежная. Сайдкар добавляет режим отказа: если он не работает, вызовы инструментов блокируются или завершаются ошибкой. Это осознанный выбор. Блокировка на трассировке безопаснее, чем продолжение без неё, но это меняет профиль доступности агента. Команды должны явно решить, отказывает ли агент закрыто или открыто, и задокументировать это решение.

Что это меняет

Логи перестают быть побочным продуктом и становятся главным доказательством. Эта переформулировка имеет архитектурные последствия. Конвейер трассировки больше не является заботой сайдкара, прикрученной после того, как агент заработает. Это часть границы доверия, проектируемая вместе с интерфейсом инструментов и моделью учётных данных.

Проверка проста: может ли агент, используя только свои собственные учётные данные и доступные системы, удалить или изменить запись о том, что он сделал? Если ответ да, лог не является доказательством. Это история, которую агент рассказывает о себе, и она надёжна лишь настолько, насколько надёжно текущее расположение агента.

Для команд, строящих агентные системы, задача — сделать так, чтобы ответ был нет. Отдельная идентичность, генерация на стороне вызываемой стороны, монотонная последовательность и внешний дайджест. Ничто из этого не ново. Новизна в применении их к субъекту, который может прочитать свою собственную инструментацию и решить её переписать.

ПоделитьсяXLinkedInПостоянная ссылка6 мин чтения

Связанное чтение

На какие вопросы это отвечает

Why is an append-only file not enough for agent audit logs?

Append-only files on a writable volume are still writable by the same principal. If the agent has filesystem or superuser access, it can truncate, rotate or delete the file. The append-only property is a convention enforced by the same kernel and identity the agent may already control, so it does not create a boundary between the agent and its own record.

What does a separation-of-duties trace pattern look like in practice?

Write traces to a sink with a different identity and no delete permission for the agent's principal. Emit structured events at the tool boundary so the callee produces the record, not the agent. Keep a monotonic sequence and publish a periodic external digest so gaps are detectable even if entries are removed.

How should incident response change when agents can erase traces?

Assume the agent-visible log is untrusted and reconstruct from the sink. Treat any missing sequence number as an incident rather than a logging bug. Compare the published digest against the recomputed digest over the retained range; a mismatch means the range has been altered.

What is the main trade-off of a sink the agent cannot reach?

Storage and egress cost, plus a new availability dependency. A write-only sink with independent credentials, cross-region replication and a digest job costs more than a local file, and a sidecar that blocks tool calls when it is down changes the agent's failure profile. Teams should decide explicitly whether the agent fails closed or fails open.