Платформена команда розгортає Claude Code для десятка інженерів. Щоб зробити його корисним, вони підключають його до кількох MCP-серверів: один читає монорепозиторій, інший опитує репліку для звітності, ще один заводить тикети. За тиждень агент уже читає вихідний код, звертається до бази даних і викликає внутрішні інструменти — а ніхто не може відповісти на запитання, яке рано чи пізно поставить аудитор: який агент що зробив, із яким ресурсом, і чи можете ви довести, що це не було змінено згодом?
Це не гіпотетична прогалина. Незалежне галузеве дослідження (CSA/Token, n=418) виявило, що близько 82% організацій мають запущених AI-агентів, про яких вони не знають, тоді як лише близько 21% ведуть їхній інвентар у реальному часі. Claude Code та MCP — саме той тип можливостей, що з’являється швидко і випереджає історію аудиту. Хороша новина: захищений журнал можна побудувати повністю всередині вашого периметра, без виходу назовні жодних корисних навантажень чи секретів.
Чому очевидна конфігурація не проходить аудит
Звичне перше розгортання використовує одну спільну облікову дату. Кожен екземпляр Claude Code автентифікується на рівні MCP та в нижчележачих базах даних під одним і тим самим службовим обліковим записом — mcp-runner, ci-bot, чимось загальним. Воно працює — і тихо знищує приписування дій.
Коли десять агентів діють як один суб’єкт, журнал аудиту бази даних показує десять записів від mcp-runner і нічого більше. Ви не можете сказати, чия інженерська сесія виконала UPDATE, чи прийшов він з інтерактивного запиту Claude Code або з фонового завдання без нагляду, та який MCP-інструмент був у ланцюжку. Незалежне дослідження (Optro) оцінює частку організацій, здатних простежити дію агента аж до конкретної людини, приблизно у 28%. Спільний службовий обліковий запис — одна зі структурних причин, через яку приписування дій руйнується: журнал аудиту може показати, що сталося, але ніколи — який агент це зробив.
Другий провал — це цілісність. Навіть команди, які ведуть журнал для кожної дії, зазвичай пишуть у змінне сховище. Якщо журнали живуть у тій самій системі, до якої може дістатися зловмисник (або баговий агент), «у нас є журнали» — це не те саме, що «у нас є докази». Аудитор чітко розрізняє ці дві речі.
Ідентичність для кожного агента — це фундамент
Усе, що відбувається далі, залежить від приписування дій, тож спершу полагодьте ідентичність. Замість одного спільного токена видавайте окрему короткоживучу ідентичність для кожного агента — ідеально для кожної сесії. Ідентичність подорожує разом із запитом до MCP-сервера та до будь-якого ресурсу, до якого звертається агент, тож суб’єктом, зафіксованим у базі даних, є агент, а не загальний runner.
Саме це робить принцип least-privilege осмисленим. Агента для звітності можна закріпити лише за читанням на репліці для звітності; агент релізів отримує запис лише до тих артефактів, якими він володіє. Тепер один-єдиний помічений запис за межами цієї оболонки є точним, приписуваним сигналом, а не шумом у спільному обліковому записі. Виражений як політика, цей намір прямолінійний:
agent "reporting-assistant" {
# Claude Code session via the reporting MCP server
resource "prod-postgres/reporting_replica" {
access = "read" # SELECT only
deny = ["write", "ddl"]
}
resource "s3://billing-exports" {
access = "read"
}
on_violation {
action = "block_and_alert" # refuse at access time, not just log
}
}
Суть не в синтаксисі — суть у тому, що політика називає агента, називає ресурс і відокремлює читання від читання/запису. Це відокремлення — і є вся гра.
Ставтеся до анотацій MCP як до недовірених сигналів
MCP-інструменти можуть описувати себе анотаціями, як-от readOnlyHint та destructiveHint. Вони справді корисні для попереднього сортування — інструмент, який оголошує себе руйнівним, заслуговує на жорсткішу політику. Але специфікація MCP однозначна: це підказки, і клієнти не повинні покладатися на них для рішень щодо безпеки. Вони походять від сервера, який є саме тим, що ви піддаєте аудиту. Інструмент може оголосити readOnlyHint: true і все одно виконати запис — через баг, неправильну конфігурацію або навмисне ухиляння.
Тож правильна позиція — це підтвердження, а не довіра. Сприймайте анотацію як заяву, а потім перевіряйте її проти фактичних даних з рівня, який інструмент не контролює:
- Журнали аудиту бази даних (наприклад, PostgreSQL pgAudit) кажуть вам, чи справді виконувався
SELECTабоUPDATE. - Трасування OpenTelemetry з MCP-сервера та нижчележачих сервісів показують граф викликів і виконані операції.
- Сигнали eBPF на рівні ядра — це останній рубіж проти ухиляння: системний виклик запису до файлу чи сокета спостерігається на рівні ядра незалежно від того, що інструмент заявив у просторі користувача.
Коли анотація каже «лише читання», а ядро побачило запис, ця суперечність — головна знахідка: інструмент із readOnlyHint, який записав до prod-postgres, — це саме той дрейф від least-privilege, заради якого варто когось розбудити. Розбіжність між тим, що політика дозволила, і тим, що колектори спостерегли, — ось де живе справжній ризик.
Реєстр, який прийме аудитор
Журнал є доказом лише тоді, коли він захищений від підробки. Записуйте кожну подію до реєстру з можливістю лише дозапису та ланцюжком гешів: кожен запис містить геш попереднього, тож будь-яке редагування чи видалення в подальшому розриває ланцюжок і стає виявним. Кожен рядок приписує дію конкретному агенту, називає ресурс, фіксує читання проти читання/запису та несе рівень довіри — attributed, коли і ідентичність, і результат підтверджено, approximate, коли щось довелося вивести логічно. Рівень довіри показується чесно; приблизний збіг ніколи не видається за доведений.
ts=2026-06-08T09:14:02Z agent=reporting-assistant@s3f1 tool=sql-read resource=prod-postgres/reporting_replica op=R outcome=allow conf=attributed prev=8a1c…
ts=2026-06-08T09:14:05Z agent=reporting-assistant@s3f1 tool=export-writer resource=s3://billing-exports op=R outcome=allow conf=attributed prev=2f90…
ts=2026-06-08T09:17:48Z agent=data-export-job@b22e tool=sql-write resource=prod-postgres/customers op=RW outcome=DENY conf=attributed prev=c7d3… policy=read_only_violation
Той третій рядок — саме те, що цікавить аудитора: спроба запису до таблиці, на яку агент не мав права запису, відхилена в момент доступу, приписана названому агенту і закріплена в ланцюжку. Оскільки політика застосовується примусово в момент звернення — а не лише фіксується в журналі постфактум — відмова є засобом контролю, а не розбором польотів.
Ще дві властивості роблять журнал стійким. Привілейовані перегляди самі піддаються аудиту: перегляд карти доступу фіксується, тож на запитання «хто що бачив» можна відповісти. І експорт доказів захищений від підробки — ви передаєте аудитору підписаний фрагмент ланцюжка, який він може перевірити незалежно, а не CSV, який він мусить приймати на віру.
| Властивість | Спільний службовий обліковий запис | Ідентичність для кожного агента + реєстр із ланцюжком гешів |
|---|---|---|
| Приписування дій | Один суб’єкт для всіх агентів | Дія прив’язана до конкретного агента/сесії |
| Читання проти запису | Змішані | Розрізнені та перевірені політикою |
| Цілісність | Змінні журнали | Лише дозапис, ланцюжок розривається при редагуванні |
| Експорт, готовий для аудитора | CSV, прийнятий на віру | Підписаний фрагмент, перевірюваний незалежно |
Чому self-hosted тут має значення
Усе це працює без виходу будь-чого за межі вашої мережі. Колектор спостерігає — журнали, OpenTelemetry, eBPF як останній рубіж на рівні ядра — а не сидить на шляху даних агента, тож якщо він відмовляє, то ніколи не ламає агента чи виробничий запит за ним. Реєстр зберігає відносини доступу, а не корисні навантаження: він фіксує, що reporting-assistant прочитав reporting_replica, а не самі повернуті рядки. Вхідні дані, що можуть містити секрети чи PII, редагуються та скануються на секрети до того, як щось буде записано. Для air-gapped середовищ, обмежених GDPR чи вимогами до резидентності даних, це і є різниця між історією аудиту, яку ви можете захистити, і тією, яку не можете: ніщо у вашому використанні Claude Code та MCP не «дзвонить додому», бо система спочатку взагалі не бачить даних.
Claude Code та MCP варті розгортання. Їм просто потрібен журнал аудиту, побудований так само, як ви будували б його для будь-якої іншої привілейованої автоматизації — спершу ідентичність, результати підтверджені, докази закріплені. Якщо ви хочете побачити, як карта доступу та захищений від підробки реєстр поєднуються разом, модель безпеки та огляд продукту докладніше розкривають кожен із них.