Типовое внедрение агента выглядит так: создают сервисный аккаунт, выдают ему широкие права «чтобы не падало», кладут ключ в конфиг — и агент работает от своего имени по поручениям десятков пользователей. Через полгода аудитор спрашивает: «вот это удаление — кто его разрешил?» Ответа нет. В журнале — сервисный аккаунт, поручения — в чатах, связь между ними — нигде. Проблема не в агенте, а в модели идентичности: shared-ключ стирает_principal_ — человека, чьей волей действие совершено. Решение известно из мира микросервисов и стандартизировано: on-behalf-of flow — действие от имени пользователя с сохраняющейся цепочкой делегирования. Для агентов 2026 год добавил к стандарту агентное расширение. Разберём механику целиком.
Проблема shared service account
Сервисный аккаунт с широкими правами — это три потери сразу. Потеря attribution: все действия свалены на одну идентичность, и отличить поручение CEO от поручения стажёра невозможно. Потеря least privilege: права выдаются по объединению потребностей всех пользователей — каждый отдельный вызов избыточен. Потеря отзыва: уволившийся сотрудник не отзывает ничего — ключ живёт своей жизнью, а «отозвать доступ уволенного» превращается в аудит всех мест, где агент мог действовать в его интересах. Альтернатива «выдать каждому пользователю своего агента с его правами» не масштабируется и плодит standing privilege. Нужна третья модель: одна агентная идентичность, действующая в контексте конкретного пользователя — с доказательствами.
Delegation vs impersonation
RFC 8693 фиксирует различие, на котором держится вся конструкция. При impersonation сторона A получает ограниченный credential, который продолжает идентифицировать B как уполномоченную сущность: система видит «B». При delegation у A остаётся собственная идентичность отдельно от B, и явно понимается: B делегировал часть прав A, действия выполняет A, представляя B. В каком-то смысле A — агент B. Так и написано в стандарте — буквально.
Для агентов правильная семантика — delegation: downstream-система обязана видеть обе стороны — кто действует (агент) и от чьего имени (пользователь). Impersonation стирает агента из картины и мешает применять к нему собственные политики: лимиты, allowlist, бюджет. Потребитель токена при контроле доступа смотрит только на top-level claims и текущего актора из act — вложенные act дают историю, но не права. Это и есть ответ аудитору «кто разрешил»: субъект плюс цепочка акторов.
RFC 8693 за десять минут
Протокол обменного STS: клиент предъявляет subject_token (в чьих интересах запрашивается — обычно токен пользователя) и опционально actor_token (кому делегируются права — идентичность агента), получает новый токен для downstream-сервиса. Ключевые элементы:
- Сужение scope. Новый токен выпускается с меньшим или равным scope исходного — никогда шире. Сужение — обязательное направление: вниз по цепочке права только тают.
actclaim. Вложенный объект в JWT, идентифицирующий действующего актора; цепочка делегирования выражается вложениемactвact— внешний claim текущий актор, глубже — предыдущие.may_actclaim. Заявление, что одна сторона уполномочена становиться актором от имени другой: authorization server проверяет его в subject-токене, решая, разрешить ли обмен.- Безопасность обмена. Делегирование создаёт риск злоупотребления — стандарт прямо требует смягчать его через
scopeи проверять политики на каждом обмене, а не только на первом.
Практика Auth0 показывает, как это ложится на агентов: OBO-обмен сохраняет identity и RBAC пользователя через всю цепочку вызовов — сценарий из документации прямо называет MCP-серверы, которым нужно звать first-party API от имени пользователя. Цепочка ограничена пятью вложенными уровнями — обмен упадёт, если subject уже несёт четыре act: глубина делегирования проектируется, а не случается.
Transaction Tokens для агентов (2026)
Весной 2026 года IETF-черновик Transaction Tokens for Agents надстроил над обменом агентную семантику. Три клейма несут нагрузку: act — агент-исполнитель в терминах actor-токенов RFC 8693, sub — принципал, от имени которого идёт транзакция, agentic_ctx — атрибуты агента и его операционных ограничений для авторизации, аудита и политик. Ключевые правила жёсткие и правильные:
- TTS (сервис выпуска) не верит самодекларации агента:
agentic_ctxзаполняется через verified exchange из авторитетного источника идентичности, а не из слов агента о себе. - Делегат не получает токен делегатора: суб-агенту выпускается суженный токен через replacement flow с scope/purpose под конкретную подзадачу.
- Сохранение lineage опционально, но сужение обязательно: каждый переход вниз — меньше прав, уже purpose, короче жизнь.
Это ровно та механика, которой не хватало multi-agent системам: оркестратор не раздаёт свой ключ «детям», а выбивает каждому пропуск под задачу.
Сужение вниз по цепочке
Правило, которое стоит повесить над рабочим местом: права текут только вниз. Пользователь → агент: scope пользователя минус всё, что агенту не нужно для задачи. Агент → суб-агент: минус всё, что не нужно подзадаче. Агент → инструмент: минимум на вызов. На каждом переходе — короткое время жизни: токен живёт минуты, а не месяцы, потому что цепочка дешёвая в построении и дорогая в компрометации. Отдельно — purpose: токен под «прочитать сделку X» не работает для «прочитать сделку Y», даже если scope формально позволяет. Purpose превращает scope из забора вокруг поля в пропуск в конкретную комнату.
Sender-constraining и отзыв
Украденный bearer-токен использует кто угодно — поэтому обмен поддерживает привязку к владельцу: DPoP или mTLS. При OBO middle-tier предъявляет свой DPoP-proof или сертификат — выпущенный токен привязывается к держателю, и кража токена без ключа бесполезна. Отзыв строится двухуровнево: отзыв subject (пользователь отозвал согласие, уволен, скомпрометирован) инвалидирует всю цепочку вниз — проверять это обязан каждый STS при обмене, а не только конечный ресурс. Плюс короткий TTL как страховка: даже пропущенный отзыв умирает за минуты.
Чеклист внедрения
- Агент имеет собственную идентичность отдельно от пользователей; shared-ключи без attribution запрещены.
- Downstream-вызовы идут через token exchange: subject — пользователь, actor — агент, scope сужается.
- Цепочка
actпишется и проверяется; глубина спроектирована (лимит 5 — не сюрприз). -
may_act— какие агенты вправе действовать от чьего имени — задан явно, а не «все ото всех». - Суб-агентам — только суженные токены через replacement flow; передача своего токена запрещена.
- Токены короткоживущие, с purpose под задачу; sender-constraining там, где цена кражи высока.
- Отзыв subject инвалидирует цепочку; TTL — минуты.
- Журнал хранит связку «поручение → обмены → вызовы» — аудитор читает по пользователю.
Где Codenik
Codenik реализует именно эту модель: поручение пользователя фиксируется, агент получает суженный короткоживущий доступ под задачу с цепочкой «кто поручил → кто исполняет», каждый вызов downstream несёт обе идентичности. Суб-агентам и инструментам права только тают вниз, отзыв пользователя рвёт цепочку целиком, журнал читается в обе стороны — и по агенту, и по человеку. Shared-ключ «на всё» в этой архитектуре просто негде выдать: его место занято обменом с доказательствами.
Короткий вывод
Агент без пользовательского контекста — это действие без автора. On-behalf-of по RFC 8693 и агентные transaction tokens дают механику: delegation вместо impersonation, сужение scope вниз, цепочка act, короткая жизнь, привязка к владельцу. Постройте обмен до первого продакшен-вызова — и вопрос «кто разрешил» всегда будет иметь ответ с подписью.