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

least-privilege

Дрейф от least-privilege: как обнаружить чрезмерно привилегированных AI-агентов до инцидента

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

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

AI-агенты тихо ломают эту модель. Агенту выдают учётные данные, инструмент, подключение к MCP-серверу — и с этого момента его поведение становится динамическим. Он решает в рантайме, какие ресурсы читать, какие писать, какой инструмент вызвать следующим. Грант, который вы записали в первый день, описывает потолок, а не то, что агент делает. А поскольку агенты продуктивны, этот потолок обычно ставят с запасом: широкие роли в базе данных, доступ на запись «на всякий случай», сервисный аккаунт, общий для полудюжины рабочих процессов. В итоге получается ландшафт, где разрешённый доступ и фактически используемый доступ расходятся — тихо, каждый день.

Независимые отраслевые исследования отражают масштаб этого слепого пятна: примерно 82% организаций сообщают, что у них работают AI-агенты, о которых они не знали, при этом лишь около 21% ведут их инвентаризацию в реальном времени (CSA/Token Security, n=418). Вы не сможете применить least-privilege к ландшафту, который не видите.

Определение дрейфа от least-privilege

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

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

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

Превращение дрейфа в проверяемый сигнал

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

Наблюдение должно вестись в режиме read-first. Сборщик, который наблюдает из логов, трейсов OpenTelemetry и сигналов ядра eBPF, находится вне пути данных агента. Это не прокси, он не пропускает вызовы через себя, и если он отказывает, то отказывает «открыто» в безопасном смысле: агент продолжает работать, вы теряете видимость, а не доступность. Эта асимметрия важна: средство защиты, способное положить прод, — это средство, которое команды тихо отключают. Слой eBPF, в частности, выступает как ground truth на уровне ядра — та часть, которую агент не может обойти, — и именно поэтому подсказки на уровне протокола, такие как аннотации инструментов MCP (readOnlyHint, destructiveHint), сверяются с ним, а не принимаются на веру. Сама спецификация MCP говорит, что этим аннотациям доверять нельзя; сигналы ядра — это то, что делает такую сверку реальной.

Результатом наблюдения является карта доступа: для каждого агента — к каким ресурсам он обращался и читал ли он (R) или читал и писал (RW). Карта хранит отношения доступа, а не полезные нагрузки, секреты или PII. Интересная часть — это сравнение:

АгентРесурсРазрешеноНаблюдаетсяДрейф
data-export-jobprod-postgresRRнет
data-export-jobs3://billing-exportsRRWнепроверенная запись
report-builderanalytics-dbR(не используется)мёртвая привилегия

Значимая строка — средняя. Политика дала чтение бакета экспорта; сборщик наблюдал запись. Эта единственная строка — главный риск, который дрейф от least-privilege и призван выявить: задействованная привилегия, которую никто не проверял, отнесённая к конкретному агенту, а не к общему сервисному аккаунту, потому что именно идентичность на уровне отдельного агента вообще делает возможными атрибуцию и аудит.

Применение в момент доступа, а не просто логирование

Обнаружение говорит вам, что дрейф произошёл. Чтобы замкнуть цикл, вы хотите, чтобы непроверенная запись стала запрещённым путём, а не залогированным. Здесь и вступает в дело policy-as-code, оцениваемый в момент доступа. То самое сравнение, которое выявило дрейф, становится правилом, которое его предотвращает.

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

agent "data-export-job" {
  # Read-only on the operational database. No writes, ever.
  access "prod-postgres" {
    mode  = "read"
    deny  = ["write", "delete", "ddl"]
  }

  # The export target the job is *supposed* to use.
  access "s3://billing-exports" {
    mode = "read"
  }

  on_violation {
    action = "block"        # deny the call at access time
    alert  = "security-oncall"
    audit  = "append"       # write to the tamper-evident ledger
  }
}

Пройдём «до» и «после» конкретно.

До. Задание экспорта, обладая широкой ролью, выполняет запись в s3://billing-exports. Ничто его не останавливает. Действие проходит успешно, сливается с обычным трафиком и проявляется днями позже, если вообще проявляется, как аномалия на карте доступа. Разрыв между разрешённым и наблюдаемым расширился, а единственный артефакт — строка лога, которую никто не прочитал.

После. Приходит та же запись. Политика оценивается в момент доступа, видит write на ресурсе, ограниченном до read, и возвращает отказ ещё до того, как операция совершится. Нарушение блокирует вызов, поднимает оповещение для дежурной смены и добавляет запись в дополняемый только в конец, связанный хешами журнал аудита. Непроверенная запись так и не становится непроверенным изменением. Дрейф в тот же момент конвертируется обратно в путь, соответствующий least-privilege.

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

Вывод

Least-privilege не подвёл для AI-агентов; подвела периодичность проверок. Гранты грубы, поведение динамично, а ежеквартальные сертификации не могут отслеживать поверхность доступа, которая меняется от запуска к запуску. Решение — не более тяжёлый прокси на критическом пути. Это непрерывное наблюдение в режиме read-first, которое формирует сравнение «разрешено vs наблюдается», плюс policy-as-code, который применяет исправленную границу в момент доступа, — так что чрезмерно привилегированный агент обнаруживается как проверяемый сигнал задолго до того, как он превратится в инцидент.

Если вы хотите увидеть, как сборщик, карта доступа и применение в момент доступа складываются вместе, не находясь на пути данных ваших агентов, страница архитектуры разбирает дизайн, а продукт показывает, как выглядит представление «разрешено vs наблюдается» на реальном ландшафте.

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

Что такое дрейф от least-privilege для AI-агента?

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

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

Наблюдайте, а не перехватывайте. Сборщик, работающий в режиме read-first, читает из логов, OpenTelemetry и сигналов ядра eBPF, вместо того чтобы находиться на пути данных агента, поэтому сбой сборщика никогда не блокирует агента. Это наблюдение питает сравнение «разрешено vs наблюдается». Применение же реализуется через policy-as-code, оцениваемый в момент доступа, где непроверенная запись становится запрещённым путём плюс оповещение.

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

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