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

Идентичность без задачи: почему учётные данные для каждого агента всё ещё дают избыточные права

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

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

Улучшение и его границы

Дайте AI-агенту учётные данные, срок действия которых истекает вместе с задачей, и вы устраните одну из старейших проблем управления доступом: долгоживущий bearer-токен, лежащий в конфигурационном файле, действительный месяцами и полезный для атакующего ещё долго после завершения процесса агента. Подход в стиле 1Password и более широкие предложения по IAM для агентов движутся в этом направлении. Учётные данные выпускаются на задачу, привязываются к сессии и отзываются при её закрытии. Окно, в течение которого утёкший токен остаётся полезным, сокращается с месяцев до минут. Это реальный выигрыш.

Но этот выигрыш ортогонален вопросу, который на самом деле волнует большинство проверок безопасности: до чего этот учётный доступ может дотянуться, пока он жив? Токен с областью действия на уровне задачи и временем жизни в пять минут, имеющий s3:GetObject на *, — это всё ещё пятиминутное окно до всего бакета. Время жизни узкое. Область действия — нет. И область действия не определяется системой, выпускающей учётные данные, самостоятельно — она наследуется от решения, принятого ранее, другим компонентом, на другом языке.

Область действия — это результат декомпозиции

Рассмотрим две инструкции, которые оркестратор может передать субагенту:

subtask: reconcile the account
subtask: read invoice 4417

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

High voltage power line and insulators against a clear blue sky

Иными словами, планировщик занимается управлением доступом, независимо от того, относится ли кто-то к нему так. Когда он разбивает «разобраться с жалобой клиента» на «прочитать тикет, прочитать заказ, оформить возврат», он только что решил, какие учётные данные понадобятся рою. Когда он разбивает тот же запрос на «прочитать тикет, прочитать заказ, прочитать историю платежей, прочитать запись о доставке, прочитать заметки по аккаунту», он решил нечто более широкое. Слой IAM ниже по потоку — формальность; содержательное решение принято выше по потоку, в компоненте, который большинство команд всё ещё называют оркестрацией.

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

Что требуется для аудируемости

Если область действия определяется декомпозицией, то аудит доступа означает аудит декомпозиции. Журнал выпуска токенов, в котором записано agent-7 requested scope X, granted scope X, ничего не говорит проверяющему о том, была ли X обоснована. Он фиксирует формальный шаг и опускает содержательный.

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

{
  "plan_node": "P-118",
  "subtask": "S-118-3",
  "intent": "read invoice 4417",
  "requested_scope": ["billing:invoices:read:4417"],
  "granted_scope": ["billing:invoices:read:4417"],
  "parent_scope_ceiling": ["billing:invoices:read:*"]
}

Поле parent_scope_ceiling — самое важное. Это максимальная область действия, которую узел плана может распределять между своими дочерними элементами, и она устанавливается при создании плана, а не при запросе учётных данных. Это даёт проверяющему две вещи для проверки: осталась ли подзадача в пределах потолка своего родителя, и был ли потолок родителя сам обоснован исходным запросом. Вторая проверка — та, что ловит планировщика, который тихо решил, что «разобраться с аккаунтом» означает «про![Close-up of rClose-up of rusty screws on a corroded metal surface showing decay

Режим отказа, за которым нужно следить, — не злонамеренный агент. А услужливый. Агент натыкается на ошибку доступа — он попытался прочитать счёт 4417, а область действия была billing:invoices:read:4417, но счёт находится в другой системе, или для сверки нужна ещё и запись о платеже — и повторяет попытку. Если логике повторных попыток разрешено расширять область действия, агент расширит область действия. Это не баг агента; это агент, делающий то, что делают агенты, — преследующий цель. Баг — в политике повторных попыток, которая трактует ошибку доступа как запрос на больше прав, а не как сигнал о том, что декомпозиция была неверной.

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

Честный компромисс

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

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

Что строить

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

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

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

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

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

Does task-scoped credential issuance solve least privilege for agents?

It solves the lifetime half. A short-lived token limits how long a leak is useful, but the token can still reach whatever the task was scoped to, and that scope is set by the planner's decomposition, not by the issuer.

Why is the planner a security-relevant component?

Because the planner decides how work is split, and the split determines what credentials each subagent needs. A coarse decomposition produces coarse grants regardless of how short the token lifetime is.

What should a credential request carry?

The originating subtask identifier and its parent plan node, plus a scope ceiling set when the plan was created. Grants that exceed the declared subtask should be rejected, and the decomposition should be logged with the grant.

How should retry-with-broader-scope be handled?

As a first-class incident signal. A retry requesting a scope larger than the original subtask should fail closed and route to re-decomposition by a component other than the agent that hit the permission error.