Найменші привілеї — одна з найдавніших і найнадійніших ідей у безпеці. Надайте ідентичності рівно той доступ, який їй потрібен, і нічого більше, — і радіус ураження від будь-якої компрометації залишиться малим. Для облікових записів людей та довготривалих службових облікових записів ця модель тримається доволі добре: ролі переглядаються, права обмежуються за призначенням, а сертифікації доступу виконуються щоквартально.
AI-агенти руйнують цю модель непомітно. Агентові надають облікові дані, інструмент, з’єднання з MCP-сервером — і з цієї миті його поведінка стає динамічною. Він вирішує під час виконання, які ресурси читати, які — записувати, який інструмент викликати наступним. Права, які ви прописали в перший день, описують стелю, а не те, що агент робить. А оскільки агенти продуктивні, ця стеля зазвичай буває щедрою: широкі ролі в базі даних, доступ на запис «про всяк випадок», службовий обліковий запис, спільний для півдюжини робочих процесів. У результаті виникає середовище, де дозволений доступ і фактично використовуваний доступ розходяться, непомітно, щодня.
Незалежні галузеві дослідження фіксують масштаб цієї сліпої зони: близько 82% організацій повідомляють про наявність AI-агентів, про яких вони не знали, тоді як лише близько 21% ведуть їхній інвентар у реальному часі (CSA/Token Security, n=418). Не можна застосовувати найменші привілеї до середовища, якого ви не бачите.
Визначення дрейфу найменших привілеїв
Назвемо це явище точно. Дрейф найменших привілеїв — це зростаючий розрив між доступом, який агентові дозволено, і доступом, який, за спостереженнями, він використовує. У нього два напрямки збою, і лише один із них очевидний.
Очевидний напрямок — це недовикористання: агент має доступ на запис до таблиці, у яку він жодного разу не записував. Це мертвий привілей, і це ризик, який ви несете без жодної користі. Небезпечний же напрямок — це зворотний сигнал, який він передбачає: коли спостережений набір містить щось, чого дозволений набір ніколи свідомо не надавав, у вас відбувається дія, яку ніхто не переглядав. Завдання експорту, яке раптом записує у кошик, з якого досі лише читало. Агент, якому політика обмежила доступ однією схемою, дотягується до іншої. Це не якась екзотика; це повсякденна тканина агентів, з’єднаних між собою через грубо надані права.
Причина, чому це складно, і чому це специфічно саме для агентів, а не для людей, полягає в тому, що поведінка є згенерованою, а не налаштованою. Людина з надмірним доступом здебільшого ним не користується. Агент із надмірним доступом використає все, що допоможе йому виконати поставлене перед ним завдання, зокрема й шляхи, яких ніхто не передбачав. Статичний перегляд політики не встигає за поведінкою, що змінюється від запуску до запуску.
Перетворення дрейфу на придатний для перегляду сигнал
Дрейф небезпечний лише доти, доки він невидимий. Завдання — зробити його сигналом, який людина може переглянути, а це потребує, щоб дві речі працювали разом: безперервного спостереження за тим, до чого агенти насправді звертаються, і стабільного запису того, до чого їм було дозволено звертатися.
Спостереження має працювати за принципом «спершу читання». Колектор, який спостерігає за журналами, трасуваннями OpenTelemetry та сигналами ядра eBPF, перебуває поза шляхом даних агента. Він не є проксі, не контролює виклики, а якщо він збоїть, то збоїть «у безпечний бік» — агент продовжує працювати, ви втрачаєте видимість, а не доступність. Ця асиметрія має значення: засіб безпеки, здатний покласти продакшен, — це засіб, який команди тихо вимикають. Шар eBPF зокрема діє як істина рівня ядра, та частина, яку агент не може обійти, — саме тому підказки на рівні протоколу, як-от анотації інструментів MCP (readOnlyHint, destructiveHint), звіряються з ним, а не приймаються на віру. Сама специфікація MCP стверджує, що ці анотації не є довіреними; сигнали ядра — це те, що робить звірку реальною.
Те, що продукує спостереження, — це карта доступу: для кожного агента — до яких ресурсів він звертався і чи читав він (R) чи читав/записував (RW). Карта зберігає відношення доступу, а не корисне навантаження, секрети чи PII. Найцікавіша частина — це порівняння:
| Агент | Ресурс | Дозволено | Спостережено | Дрейф |
|---|---|---|---|---|
| data-export-job | prod-postgres | R | R | немає |
| data-export-job | s3://billing-exports | R | RW | неперевірений запис |
| report-builder | analytics-db | R | (не використовується) | мертвий привілей |
Рядок, який має значення, — середній. Політика надала читання для кошика експорту; колектор спостеріг запис. Цей один рядок — це ключовий ризик, який дрейф найменших привілеїв і має виявляти: реалізований привілей, який ніхто не переглядав, приписаний конкретному агентові, а не спільному службовому обліковому запису, бо саме ідентичність на рівні окремого агента взагалі робить можливими атрибуцію та аудит.
Застосування в момент доступу, а не лише журналювання
Виявлення повідомляє вам, що дрейф стався. Щоб замкнути цикл, ви хочете, щоб неперевірений запис був заблокованим шляхом, а не зажурнальованим. Саме тут у гру вступає policy-as-code, що оцінюється в момент доступу. Те саме порівняння, яке позначило дрейф, стає правилом, що його запобігає.
Розгляньмо закріплення завдання експорту в режимі лише для читання у продакшен-базі даних та пряму заборону записів, з порушенням, яке блокує й сповіщає, а не проходить безшумно:
agent "data-export-job" {
# Лише читання операційної бази даних. Жодних записів, ніколи.
access "prod-postgres" {
mode = "read"
deny = ["write", "delete", "ddl"]
}
# Ціль експорту, яку завдання *має* використовувати.
access "s3://billing-exports" {
mode = "read"
}
on_violation {
action = "block" # відхилити виклик у момент доступу
alert = "security-oncall"
audit = "append" # запис до журналу з захистом від підробки
}
}
Розгляньмо конкретно стан «до» і «після».
До. Завдання експорту, маючи широку роль, виконує запис до s3://billing-exports. Ніщо його не зупиняє. Дія виконується успішно, зливається зі звичайним трафіком і спливає днями пізніше, якщо взагалі спливає, як аномалія в карті доступу. Розрив між дозволеним і спостереженим розширився, а єдиний артефакт — рядок журналу, якого ніхто не прочитав.
Після. Надходить той самий запис. Політика оцінюється в момент доступу, бачить write на ресурсі, обмеженому режимом read, і повертає відмову до того, як операція відбудеться. Порушення блокує виклик, піднімає сповіщення для дежурної зміни та додає запис до журналу аудиту, що дозволяє тільки додавання й захищений хеш-ланцюгом. Неперевірений запис так і не стає неперевіреною зміною. Дрейф цієї ж миті перетворюється назад на шлях найменших привілеїв.
Дві властивості тримають це чесним. По-перше, кожен привілейований перегляд карти доступу сам піддається аудиту — хто на що дивився, — бо карта є чутливою, а засіб безпеки, який не може відзвітувати за власних операторів, не заслуговує на довіру. По-друге, впевненість показується прямо: дія, приписана агентові на підставі доказів рівня ядра, позначається інакше, ніж дія, виведена приблизно. Вас ніколи не просять діяти на основі вигаданої впевненості.
Висновок
Найменші привілеї не зазнали невдачі з AI-агентами; невдачі зазнала періодичність перегляду. Права грубі, поведінка динамічна, а щоквартальні сертифікації не можуть відстежувати поверхню доступу, яка змінюється з кожним запуском. Виправлення — це не важчий проксі на критичному шляху. Це безперервне спостереження за принципом «спершу читання», що продукує порівняння «дозволено проти спостережено», плюс policy-as-code, який застосовує виправлену межу в момент доступу, тож агента з надмірними привілеями виявляють як придатний для перегляду сигнал задовго до того, як він перетвориться на інцидент.
Якщо ви хочете побачити, як колектор, карта доступу та застосування в момент доступу поєднуються між собою, не перебуваючи на шляху даних ваших агентів, сторінка архітектури проводить через увесь дизайн, а продукт показує, який вигляд має подання «дозволено проти спостережено» на реальному середовищі.