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

agent-access

До чего на самом деле могут дотянуться ваши AI-агенты: построение карты доступа агентов на реальной инфраструктуре

Автор Olivares AI 6 мин чтения

AI-агент с операционной точки зрения — это процесс, владеющий учётными данными. Кто-то выдаёт ему сервисный аккаунт, API-ключ или IAM-роль, чтобы он выполнял свою работу, и с этого момента он может дотянуться до всего, до чего дотягиваются эти учётные данные. В описании задачи было сказано «выгружать данные биллинга по ночам». В учётных данных было сказано «читать и записывать продакшен-базу данных, а также объектное хранилище и очередь». Никто не сопоставил одно с другим. Спустя месяцы никто в команде не может ответить на вопрос, который должен быть тривиальным: до чего на самом деле может дотянуться этот агент и чего он реально касается?

Этот разрыв не гипотетический. Независимое отраслевое исследование (CSA/Token) показало, что примерно у 82% организаций работают AI-агенты, о которых они не знают, и лишь около 21% ведут их инвентаризацию в реальном времени. Невозможно управлять тем, чего вы не видите, а сейчас большинство инфраструктур вообще не видит своих агентов — не говоря уже о связях, соединяющих каждого агента с ресурсами, до которых он может дотянуться.

Три разных вопроса, которые регулярно смешивают

Причина, по которой на вопрос «до чего может дотянуться этот агент» так трудно ответить, в том, что он сводит три отдельных вопроса в один. Удержать их раздельно — в этом вся суть.

  • Имеющиеся (Held) — учётные данные, которыми владеет агент. Токен, ключ, привязка роли. Это факт идентичности: к каким дверям у агента есть ключи.
  • Разрешённые (Permitted) — то, что этим учётным данным разрешено делать согласно политике: IAM-права, роли базы данных, сетевые правила. Это факт политики, и он почти всегда шире, чем кто-либо помнит, потому что права накапливаются, а отзывать их никто не отзывает.
  • Наблюдаемые (Observed) — то, что агент реально видели делающим: к каким ресурсам он обращался и было ли каждое обращение чтением или записью. Это факт поведения, и пока вы его не собрали, он попросту нигде не существует.

Большинство средств безопасности останавливается на разрешённом. Они читают ваш IAM и сообщают, что агент мог бы записывать в бакет с выгрузками биллинга. Это необходимо, но недостаточно, потому что «мог бы» — это набор из тысяч латентных возможностей, а человек не способен разобрать тысячи «может быть». Разговор меняется тогда, когда вы ставите наблюдаемое рядом с разрешённым и смотрите на разницу.

Карта доступа

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

R (read) означает, что агент извлёк данные, не изменяя их: SELECT, GET, чтение файла. RW (read/write) означает, что он изменил состояние: INSERT/UPDATE/DELETE, PUT в объектное хранилище, миграцию схемы. Радиус поражения у этих двух несопоставим. Связь на чтение к чувствительной таблице — это вопрос раскрытия данных. Связь на запись — особенно непреднамеренная — это вопрос целостности и инцидента. Относиться к ним как к одному и тому же «доступу» — это и есть способ пропустить ту самую находку, которая имела значение.

Вот как выглядит строка одного агента после того, как карта построена:

АгентРесурсРазрешеноНаблюдалосьУверенность
data-export-jobprod-postgresRWRWатрибутировано
data-export-jobs3://billing-exportsRWRатрибутировано
data-export-jobinternal-metrics-apiRприблизительно

Посмотрите на первую строку. Задача выгрузки предполагала чтение из prod-postgres и запись результата в s3://billing-exports. Читать источник, записывать в назначение. Но выданные ей учётные данные дают RW на базу данных, и сборщик наблюдал, как она записывает в prod-postgres — изменение продакшен-системы учёта, которое никто не проверял, не предполагал и не может сейчас объяснить. Колонка «разрешено» всё это время незаметно говорила, что это допустимо. Это зародыш инцидента, лежащий на виду, и без колонки «наблюдалось» сигнализировать не о чем.

Разрешённое минус наблюдаемое равно дрейфу

Характерный итог — это разница. Дрейф least-privilege — это то, что получается, когда вы вычитаете одну колонку из другой, и работает он в обе стороны:

  • Разрешено, но ни разу не наблюдалось — агент может дотянуться до internal-metrics-api, но за всё окно наблюдения ни разу этого не сделал. Это мёртвые права: выданное право, которое можно безопасно предложить к отзыву, сокращая поверхность атаки без изменения поведения.
  • Наблюдалось сверх того, что проверяли — запись в prod-postgres, которую никто не утверждал. Это и есть значимая находка: происходящее действие, которое, если бы кого-то спросили на этапе выдачи прав, он бы не одобрил.

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

Обнаружено пассивно, атрибутировано по каждому агенту

Два проектных решения делают это заслуживающим доверия, а не просто очередной панелью.

Во-первых, обнаружение — пассивное. Сборщик наблюдает — логи, трассировки OpenTelemetry, потоки аудита баз данных вроде pgAudit у PostgreSQL и eBPF на уровне ядра как опору на ground truth — и он не находится на пути данных агента. Обязательного прокси нет. Если сборщик откажет, агент продолжит работать; деградирует наблюдаемость, а не продакшен. Для системы, весь смысл которой — управление критической инфраструктурой, эта асимметрия и есть замысел: низкий риск, высокий сигнал.

Во-вторых, каждое действие атрибутируется конкретной идентичности агента, а не общему сервисному аккаунту. В этом разница между журналом аудита, который говорит «роль выгрузки записала в prod-postgres в 02:14», и тем, который говорит, какой именно агент это сделал, под чьим владением и против какого предполагаемого набора прав. Идентичность для каждого агента — это предпосылка для того, чтобы least-privilege вообще что-либо значил: без неё действие можно увидеть, но никогда не возвести к ответственному владельцу.

Хранятся только связи и факты чтения/записи. Карта фиксирует отношения — агент к ресурсу, R или RW — а не полезную нагрузку, не прочитанные строки, не секреты. Входные данные, которые могут содержать секреты или персональные данные, редактируются и сканируются на секреты до того, как что-либо записывается. Граф чувствителен именно потому, что это карта доступа, поэтому он построен так, чтобы хранить тот минимум, который делает управление возможным, и ничего сверх того.

Сигналы из собственной экосистемы агента помогают, но сами по себе им доверять нельзя. MCP-сервер может объявить, что инструмент работает только на чтение, через аннотации вроде readOnlyHint; согласно спецификации MCP эти подсказки не являются доверенными и должны подтверждаться, а не приниматься на веру вслепую. Именно представление на уровне ядра ловит инструмент, который заявил работу только на чтение, но всё равно записал.

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

agent "data-export-job" {
  resource "prod-postgres" {
    access = "read"        # intended scope: read source only
    deny   = ["write", "ddl"]
  }
  resource "s3://billing-exports" {
    access = "read-write"  # intended scope: write destination
  }
  on_violation {
    action = "block"
    alert  = "secops"
  }
}

Карта подсказывает вам политику, которую вам следовало написать, потому что показывает тот один доступ, который агенту реально был нужен, и десяток, которыми он ни разу не воспользовался. В этом и есть разница между угадыванием least-privilege и выведением его из ground truth.

Если это тот вопрос, на который ваша инфраструктура сегодня не может ответить — до чего может дотянуться каждый агент и чего он реально касается — то именно для этого и существует карта доступа. Обзор продукта проводит по обнаружению и сравнению «разрешённого против наблюдаемого»; архитектура рассказывает, как пассивный сбор, идентичность для каждого агента и журнал аудита складываются вместе, ни разу не оказываясь на пути данных ваших агентов.

Часто задаваемые вопросы

В чём разница между разрешённым доступом агента и наблюдаемым доступом?

Разрешённый доступ — это то, что ваша политика, IAM-роли и выданные права позволяют агенту делать в теории. Наблюдаемый доступ — это то, что пассивный сборщик реально увидел: к каким ресурсам агент обращался и читал он или записывал. Эти две величины редко совпадают: разрешённый доступ обычно гораздо шире наблюдаемого (избыточно выданные права), а изредка наблюдаемый превышает то, что кто-либо проверял и предполагал (дрейф). Сопоставление этих двух величин — это и есть способ обнаружить дрейф least-privilege, а не догадываться о нём.

Что означают R и RW на карте доступа агента?

R (read) означает, что агент извлёк данные из ресурса, не изменяя их — SELECT, GET, чтение файла. RW (read/write) означает, что он также изменил состояние: INSERT/UPDATE/DELETE, PUT в объектное хранилище, изменение схемы. Это различие важно, потому что доступ на чтение и доступ на запись несут совершенно разный радиус поражения. Агент, который должен иметь доступ только на чтение к продакшен-базе данных, но за которым наблюдают запись в неё, — это одна из самых значимых находок, которые даёт карта доступа.

Узнайте, до чего могут добраться ваши агенты

Olivares AI — открытая self-hosted платформа для управления вашим парком AI. Разверните её на собственной инфраструктуре и получите карту доступа, которую давно запрашивают ваши команды безопасности и платформ.