Истекшие API-токены: правила восстановления для долгих задач агентов
Истекшие API-токены не обязаны срывать долгие задачи агентов. Назначьте владельца обновления, классифицируйте ошибки, ограничьте повторы и безопасно восстанавливайте записи.

Долгие задачи агентов особенно нелепо завершаются сбоем, когда за истечение токена никто не отвечает. Агент получает 401, повторяет тот же вызов, расходует лимит запросов и иногда превращает одну неопределенную запись в несколько. Это не сбой аутентификации. Это ошибка проектирования восстановления.
Считайте истечение ожидаемым изменением состояния. Передайте обновление одному компоненту, классифицируйте ошибки до действий, привяжите повторы к смыслу операции и сохраняйте запись, по которой оператор поймет, приняла ли удаленная сторона работу. Агенту не приходится угадывать, может ли он выпустить учетные данные и безопасно ли повторить запись.
Истечение токена меняет состояние, но не означает сбой
Истекший API-токен сообщает, что срок действия краткоживущих учетных данных закончился. Он не сообщает, что задача провалена. Долгая задача может успешно выполнить десять удаленных операций, прежде чем следующий запрос столкнется с истечением. Код восстановления должен сохранять это различие.
Команды часто сводят четыре разных события к одной ветке auth_failed. Такой прием приводит к плохому поведению, потому что каждому событию нужен свой ответ:
- Истечение означает, что срок жизни токена закончился, а уполномоченный владелец обновления может запросить новый токен доступа.
- Отзыв означает, что пользователь, администратор или провайдер отменил разрешение. Обновление может быть намеренно запрещено.
- Неверная аутентификация запроса может означать поврежденный заголовок, неправильный тип учетных данных, несоответствие издателя или неправильную аудиторию.
- Недостаточные права означают, что личность действительна, но не может выполнить эту операцию.
OAuth различает эти случаи не случайно. RFC 6750 определяет ошибку bearer-токена invalid_token и указывает, что сервер ресурса использует ответ 401 с вызовом WWW-Authenticate, когда токен истек, отозван, поврежден или иным образом недействителен. Это полезная рекомендация протокола, но она не дает клиенту права обновлять токен вслепую. Сервер ресурса лишь сообщает, что отклонил этот запрос.
У задачи есть две временные линии. Рабочая линия фиксирует то, что задача обнаружила, вычислила, создала и подтвердила. Линия авторизации фиксирует поколение учетных данных, с которым она действовала. Когда токен истекает, сохраните рабочую линию, а линию авторизации переведите в renewing или blocked. Не сбрасывайте всю задачу, называя это восстановлением.
Это особенно важно для агентов, поскольку они выполняют цепочки зависимых вызовов. Допустим, агент создает запрос на изменение, загружает артефакт, а затем теряет доступ до того, как успевает прикрепить артефакт. Перезапуск с первой инструкции создаст второй запрос на изменение. Надежная контрольная точка после каждого подтвержденного удаленного эффекта позволит агенту продолжить с отсутствующего вложения, а не повторять весь план.
Используйте явные состояния вместо булевого признака вроде authenticated:
ready -\u003e executing -\u003e authorization_expired -\u003e renewal_in_progress
renewal_in_progress -\u003e executing
renewal_in_progress -\u003e authorization_blocked
executing -\u003e outcome_unknown
outcome_unknown -\u003e reconciled -\u003e executing
outcome_unknown заслуживает отдельного состояния. Соединение может оборваться после того, как сервис зафиксировал запись, но до того, как вызывающая сторона получила ответ. Обновление токена не устранит эту неопределенность. Задача должна выполнить поиск по идентификатору операции, ключу идемпотентности или специальному запросу провайдера, прежде чем снова пытаться выполнить запись.
Обновлением должен владеть один компонент
Клиент, которому принадлежит учетная запись для обновления, должен владеть обновлением токена доступа, а агент должен запрашивать действие, не получая учетные данные, пригодные для обновления. Это правило кажется строгим, пока два агента одновременно не столкнутся с истечением токена.
Если каждый исполнитель хранит копию токена обновления, каждый сможет обновляться самостоятельно. Они начнут конкурировать, оставят за собой поток несвязанных событий с учетными данными, а ротация токена обновления может сделать недействительным токен, который все еще хранится у другого исполнителя. Кроме того, каждый процесс, способный прочитать задачу, превращается в долгоживущего носителя личности.
Разместите между агентами и провайдером брокер учетных данных или шлюз действий. Брокер хранит токен обновления или сервисные учетные данные, получает краткоживущие токены доступа, добавляет один из них только при выполнении запроса и возвращает ответ. Агент не получает ни токен доступа, ни токен обновления.
Такое разделение дает каждому участнику ясную роль:
- Агент решает, какую разрешенную операцию нужно выполнить, и передает ее параметры.
- Шлюз проверяет, может ли сеанс выполнить запрос, выбирает ссылку на учетные данные и выполняет вызов.
- Владелец обновления выполняет обновление один раз, когда провайдер сообщает классифицированную ошибку истечения.
- Оператор разбирается с отозванным разрешением, новым требованием согласия или учетными данными, для которых нужно участие человека.
Не делайте агента владельцем обновления лишь потому, что он может вызвать OAuth-эндпоинт. Возможность выполнить действие и право расширить полномочия различаются. Агенту, который умеет запросить событие календаря или развернуть артефакт, не обязательно разрешать продлевать полномочия пользователя или сервиса.
RFC 6749 описывает токены обновления как учетные данные, выданные клиенту и используемые для получения новых токенов доступа. В архитектуре воспринимайте слово «клиент» буквально. Если ваш агент не является зарегистрированным клиентом, ему не следует передавать токен обновления клиента только потому, что агент формирует API-запрос.
Есть случаи, когда сама задача действительно владеет обновлением. Узко ограниченная машинная нагрузка со своим зарегистрированным клиентом, собственным хранилищем и без делегирования человеком может работать так. Даже тогда один координатор обновления должен обслуживать все параллельные операции этой личности. Используйте мьютекс или механизм single-flight, привязанный к ссылке на учетные данные. Первый неудачный вызов выполняет обновление, остальные ждут результата и не создают лавину запросов к эндпоинту токенов.
Простая запись о владении устраняет расплывчатость:
{
"credential_ref": "billing-write-prod",
"renewal_owner": "action-gateway",
"access_token_lifetime": "provider-defined",
"refresh_allowed": true,
"reauthorization_owner": "on-call-operator",
"concurrent_refresh": "single-flight"
}
В записи хранится ссылка, а не сами учетные данные. В ней также указано, кто должен действовать, когда обновление перестает работать. Если до развертывания никто не может ответить на этот вопрос, ночью задача ответит на него плохо.
Для 401 нужны подтверждения, прежде чем запускать обновление
Выполняйте обновление только тогда, когда ответ и запись об учетных данных подтверждают диагноз «истечение». Если считать любой 401 истечением, можно скрыть ошибки конфигурации и запустить длинную цепочку бессмысленных попыток обновления.
Начните с документированных провайдером тела ошибки, заголовков и требований к формату токена. Некоторые API возвращают совместимые с OAuth значения WWW-Authenticate. Другие возвращают коды ошибок в JSON. Некоторые помещают ошибки аутентификации за шлюзом, который использует другой код состояния. Классификатор должен опираться на документированные сигналы этого провайдера, а при недостатке данных переходить к безопасной конечной ошибке.
Рабочий контракт классификации может выглядеть так:
{
"http_status": 401,
"provider_code": "invalid_token",
"www_authenticate": "Bearer error=\"invalid_token\"",
"credential_ref": "reports-read",
"token_generation": 17,
"decision": "renew_once"
}
Ответ может получить решение renew_once, только если выполнены все условия: запрос использовал учетные данные, выданные или выбранные вашим шлюзом; для них существует путь обновления; сигнал провайдера соответствует документированному истечению или условию недействительного токена; задача еще не обновляла поколение 17.
Для каждого класса ошибок используйте отдельный результат. Поврежденный заголовок относится к configuration_error, где разработчик может проверить сборщик запроса. Несоответствие аудитории относится к credential_binding_error, где нужно исправить запрос токена или конфигурацию ресурса. Отозванное разрешение относится к reauthorization_required: система останавливает внешние действия и сообщает нужному оператору, какой личности требуется согласие. Код 403 относится к permission_denied, и обновлять токен в этом случае бессмысленно.
Проблемы с часами вызывают неожиданно много неверных диагнозов. Клиент, который вычисляет истечение по локальным часам, может преждевременно отклонить пригодный токен, а клиент с неточными часами может отправить уже истекший. Записывайте срок действия, который сообщил издатель при выдаче токена, оставляйте небольшой запас и используйте надежные системные часы. Не позволяйте каждому агенту самостоятельно вычислять истечение по декодированному утверждению токена. Это дублирует логику протокола и провоцирует расхождения.
Не изучайте содержимое токена только для того, чтобы решить, можно ли ему доверять. JSON Web Token может содержать утверждение exp, но декодирование его base64url-содержимого не проверяет подпись, издателя, аудиторию или отзыв. Используйте это лишь как подсказку после того, как компонент, получивший токен, завершил документированную проверку провайдера. Непрозрачные токены доступа вообще не содержат доступного содержимого, что еще раз подтверждает: вызывающая сторона должна опираться на обработку ответа, а не на археологию токена.
Ограничения повторов защищают удаленную систему и ваши данные
После подтвержденного истечения разрешите одно согласованное обновление и один контролируемый повтор. Дополнительные повторы не улучшают авторизацию. Они в основном скрывают сломанный путь обновления и усложняют чтение аудита.
Правило повтора зависит от того, что может сделать операция. Чтение обычно можно повторить после обновления. Для записи нужны более веские подтверждения, поскольку удаленный сервис мог обработать ее до того, как ответ об истечении, тайм-аут или потеря соединения дошли до вызывающей стороны.
Классифицируйте операции при проектировании интерфейса действий:
| Класс операции | Пример | Восстановление после обновления |
|---|---|---|
| Чтение | Получить запись | Повторить один раз, если запрос не имеет внешнего побочного эффекта |
| Идемпотентная запись | Заменить документ известной версии | Повторить один раз, если провайдер гарантирует идемпотентность этого метода и условия |
| Запись с ключом идемпотентности | Создать черновик счета | Один раз повторно использовать тот же токен и тело запроса |
| Неидемпотентная запись | Отправить сообщение или запустить платеж | Сначала проверить состояние, а затем действовать только после подтверждения отсутствия предыдущего эффекта |
Названия HTTP-методов не решают вопрос. PUT часто предполагает идемпотентность, но провайдер может добавить к нему уведомление по электронной почте или асинхронное действие в другой системе. POST может быть безопасным, если провайдер поддерживает поле идемпотентности. Изучите контракт эндпоинта и проверьте фактическое поведение.
Для операций с ключом идемпотентности создайте его до первого сетевого вызова и сохраните вместе с каноническим отпечатком запроса. При каждом повторе отправляйте точно тот же ключ и логически такое же тело. Не создавайте новый ключ после 401. Новый ключ сообщает провайдеру, что это новая операция, и тем самым разрушает смысл механизма.
{
"operation_id": "job-84f3/create-draft",
"idempotency_token": "a stable random value stored before send",
"request_fingerprint": "method, path, normalized body hash",
"attempt": 1,
"authorization_generation": 17
}
Фраза «normalized body hash» важна. Если сборщик повтора меняет время, порядок элементов массива или сгенерированную метку, он может незаметно превратить ту же пару ключа идемпотентности и запроса в несовместимую операцию. Некоторые провайдеры отклоняют такое несовпадение, другие обрабатывают его непоследовательно. Сохраните первое сериализованное тело запроса или один раз приведите его к канонической форме и используйте снова.
Ограничения скорости и повторы сетевого уровня должны использовать общий бюджет. Агент, который выполняет три сетевых повтора, затем повтор обновления и еще три сетевых повтора, создает семь возможностей продублировать операцию или перегрузить систему. Определите единый бюджет попыток на уровне операции. Например, для безопасного чтения можно разрешить исходный вызов, один путь обновления и один повтор. Для действия, похожего на платеж, допустимы исходный вызов, а затем только проверка состояния.
Записывайте и подавленные повторы. Оператор должен видеть, что система намеренно остановилась после renewal_attempted=true, а не считать, что агент завершился аварийно. Эта запись также помогает заметить, что провайдер изменил формат ошибки и классификатор перестал разрешать восстановление, которое раньше разрешал.
Контрольные точки позволяют продолжить задачу, не выдумывая ее прошлое
Долгая задача агента должна отдельно сохранять завершенные удаленные эффекты и ожидающие намерения, поскольку обновленный токен не сообщает, что произошло до сбоя. Распространенная плохая схема хранит только стенограмму чата или финальный план агента, а после прерывания просит агента восстановить состояние по памяти.
Используйте журнал задачи с записями, которые можно сверять программно. Для каждого предполагаемого внешнего вызова нужен стабильный идентификатор операции. Для каждого подтвержденного результата нужны идентификатор ресурса провайдера, версия или ETag, если они доступны, и отпечаток запроса. Для каждого неопределенного результата нужно правило поиска, которое устранит неопределенность.
Компактная контрольная точка может выглядеть так:
{
"task_id": "release-2025-04-17-42",
"completed": [
{"operation_id": "create-change", "remote_id": "CR-819", "version": "6"},
{"operation_id": "upload-bundle", "remote_id": "asset-552"}
],
"pending": {
"operation_id": "attach-bundle",
"request_fingerprint": "POST /changes/CR-819/assets body-sha256:...",
"reconcile": "list assets for CR-819 and match asset-552"
},
"authorization_state": "authorization_expired"
}
Задаче не нужно сохранять каждую промежуточную мысль. Ей нужны факты, достаточные для определения следующего безопасного удаленного действия. Не храните в этом журнале секреты, bearer-заголовки и ответы на обновление. Эти материалы принадлежат владельцу учетных данных, а не общему хранилищу задач.
Условия версий важны во время паузы. Если задача прочитала документ версии 6 до истечения токена, а возобновилась через час, другой участник мог его изменить. Используйте ETag, номера ревизий, условные заголовки или специальные поля конкурентного доступа провайдера. Если условие не выполнено, сообщите агенту, что прежний план больше не действует. Не обновляйте токен и не перезаписывайте более новое состояние только потому, что задача считает мир своей собственностью.
Здесь автономной работе нужна граница для принятия решений. Задача может безопасно продолжить загрузку, если ранее записала назначение и хеш. Ей не следует бездумно заново планировать развертывание, менять запись согласования или выбирать другую цель после того, как исходный контекст устарел. Отметьте такие операции как требующие нового подтверждения после восстановления.
Ответ восстановления должен объяснять агенту, что ему разрешено
Шлюз действий должен возвращать структурированный результат восстановления, а не расплывчатую фразу об аутентификации, которая заставит агента импровизировать. Результат должен сообщать, выполнялся ли вызов, обновил ли шлюз авторизацию, разрешен ли повтор и требуется ли участие человека.
Полезный результат разделяет состояние выполнения и состояние учетных данных:
{
"operation_id": "attach-bundle",
"execution_state": "not_sent",
"authorization_state": "reauthorization_required",
"retry_allowed": false,
"credential_ref": "release-api",
"operator_action": "Reauthorize the release-api connection, then resume task release-2025-04-17-42",
"safe_resume_from": "attach-bundle"
}
not_sent означает, что шлюз остановился до передачи запроса сетевому клиенту. outcome_unknown означает, что он не может это утверждать. Не сводите оба случая к failed. Первый может ждать повторной авторизации. Во втором нужно сверить состояние с удаленным сервисом, прежде чем что-либо повторять.
Агентам также нужен узкий словарь восстановления. Дайте им результаты вроде completed, renewed_and_replayed, needs_reconciliation, reauthorization_required, permission_denied и configuration_error. Каждый результат должен соответствовать одному разрешенному поведению. Например, после renewed_and_replayed агент может продолжить; после needs_reconciliation он может выполнить документированную проверку только для чтения; после reauthorization_required он должен остановить внешние записи.
Не возвращайте необработанные ответы провайдера как единственный сигнал. Сырые детали полезны для диагностики, но агент может неправильно их истолковать, особенно если провайдеры используют непоследовательные формулировки. Храните исходный ответ в защищенной диагностической записи, а вызывающей стороне возвращайте стабильное решение, понятное машине.
Хорошее сообщение об ошибке называет ссылку на личность и заблокированную операцию, не раскрывая секреты. Фраза «Для учетных данных release-api нужна повторная авторизация, прежде чем можно будет выполнить attach-bundle» показывает оператору, где действовать. Слово «Не авторизовано» не сообщает почти ничего.
Учетные данные для обновления требуют более строгой защиты, чем токены доступа
Учетные данные для обновления нужно защищать сильнее, поскольку обычно они живут дольше заменяемого ими токена доступа. Не решайте проблему истечения, раздавая эти долгоживущие учетные данные каждому рабочему пространству агента, каталогу сборки, переменной окружения или стенограмме.
OAuth 2.0 Security Best Current Practice, RFC 9700, рекомендует ротацию токенов обновления или привязку таких токенов к отправителю для публичных клиентов. Поддержка зависит от провайдера, но общий вывод сохраняется и при другом протоколе: украденная учетная запись, пригодная для обновления, дает злоумышленнику гораздо более длинное окно для злоупотреблений, чем обычный краткоживущий bearer-токен.
Храните материалы для обновления в зашифрованном хранилище учетных данных шлюза действий. Ограничьте список определений действий, которым разрешено выбирать их, требуйте явного подтверждения человека там, где этого требует операция, и сделайте повторную авторизацию отдельным действием оператора. Заблокированное хранилище должно запрещать работу, а не подталкивать агентов к запасным секретам в конфигурационных файлах.
Sallyport использует эту модель для поддерживаемых HTTP- и SSH-действий: его зашифрованное хранилище удерживает учетные данные, а агент запрашивает действие через MCP-адаптер и получает только результат. Такое разделение полезно, поскольку агент не может вывести токен обновления в собственный контекст, если восстановление пойдет не по плану.
Внимательно обрабатывайте ответы обновления. Некоторые провайдеры ротируют токен обновления и делают старое значение недействительным сразу после использования. Владелец обновления должен атомарно заменить сохраненное значение до того, как отпустит ожидающие вызовы. Если он запишет новый токен доступа, но потеряет новый токен обновления, задача некоторое время проработает, а затем навсегда сломается при следующем истечении.
Никогда не записывайте эти поля: Authorization, токен доступа, токен обновления, секрет клиента, подписанное утверждение или полное тело запроса к эндпоинту токенов. Маскировки недостаточно, если системы копируют исходные объекты запросов до запуска маскировщика. Настройте журнал так, чтобы он принимал ссылки на учетные данные и номера поколений токенов вместо структур, содержащих секреты.
Подтверждение человеком должно восстанавливать полномочия, а не создавать лавину повторов
Подтверждение человеком полезно только тогда, когда связано с ясным решением: разрешить этот запуск агента, разрешить этот чувствительный вызов или восстановить отозванную авторизацию. Универсальная кнопка «повторить» после истечения токена часто превращает оператора в формального согласующего непонятного действия.
Разделяйте подтверждения. Повторная авторизация дает владельцу учетных данных новое разрешение или рабочий путь обновления. Авторизация сеанса определяет, может ли конкретный процесс агента запрашивать действия. Подтверждение вызова определяет, можно ли выполнить чувствительную операцию сейчас. Это разные решения, и их объединение приводит либо к потоку лишних запросов, либо к чрезмерным постоянным полномочиям.
Когда учетным данным требуется повторная авторизация, покажите ссылку на них, название личности или соединения, заблокированную операцию и контрольную точку задачи. Не показывайте сам токен. После восстановления авторизации шлюз должен возобновить только ожидающую операцию, записанную в контрольной точке. Он не должен молча повторять все неудачные вызовы из стенограммы агента.
Фиксированная лестница решений Sallyport хорошо подходит для этой границы: заблокированное хранилище запрещает каждое действие, новым процессам агентов по умолчанию нужно подтверждение сеанса, а для выбранных учетных данных можно требовать подтверждение при каждом использовании. Эти средства контроля не пытаются выводить намерение из набора правил, что особенно полезно, когда истекшие учетные данные прерывают в остальном законный запуск.
Усталость от подтверждений обычно говорит об ошибке проектирования. Если оператор видит десяток запросов, потому что десять параллельных вызовов одновременно заметили истечение, координатор обновления не объединил событие. Покажите один запрос на повторную авторизацию, заставьте остальные вызовы ждать и сообщите полученное решение каждой задаче.
Не используйте подтверждение, чтобы замаскировать неизвестный результат записи. В таком случае правильный запрос должен спрашивать, хочет ли оператор проверить состояние удаленной системы, а не повторить операцию. Человек может случайно разрешить дублирование не хуже агента.
Тесты истечения должны включать неопределенные записи и параллельных исполнителей
Тест обновления токена, который один раз возвращает искусственный 401 перед чтением, почти ничего не доказывает. Самые болезненные сбои возникают на границах: во время параллельной работы, после фиксации записи, при ротации обновления или после отзыва разрешения.
Создайте тестовый провайдер или управляемую HTTP-заглушку, которая записывает полученные идентификаторы операций и умеет вводить сбои в заданных точках. Проверки должны анализировать и запись удаленного эффекта, и локальную запись аудита. Один успешный финальный ответ может скрыть дублированное создание.
Проведите эти проверки до того, как доверить задачу долгоживущему агенту:
- Истеките токен доступа перед чтением. Убедитесь, что обновление выполняет только один исполнитель, а все ожидающие чтения используют новое поколение.
- Истеките токен перед идемпотентной записью. Убедитесь, что шлюз обновляет его один раз и повторяет запрос с исходным идентификатором операции и телом.
- Оборвите ответ после того, как провайдер зафиксировал неидемпотентную запись. Убедитесь, что задача переходит в
outcome_unknown, выполняет поиск и не создает второй эффект. - Отзовите разрешение до обновления. Убедитесь, что каждое зависимое действие останавливается с
reauthorization_required, а цикл не вызывает эндпоинт токенов снова и снова. - Верните повернутый токен обновления, а затем прервите сохранение. Убедитесь, что шлюз обнаруживает незавершенную замену и блокирует будущие обновления, а не использует устаревшую копию.
Проверяйте время явно. Передайте компоненту учетных данных часы, которыми можно управлять, чтобы разместить истечение непосредственно перед сборкой запроса, сразу после формирования заголовков и пока запрос ждет в очереди. Ожидание реального истечения токена делает тесты медленными и оставляет важные временные сценарии непроверенными.
Наконец, протестируйте путь аудита без доступа к хранилищу. Вы должны уметь проверить, что последовательность вызовов и решений об обновлении не изменилась, даже если не можете расшифровать каждую запись. Команда Sallyport sp audit verify проверяет хешированную цепочку зашифрованных данных аудита без ключа хранилища. Это правильная форма проверки во время инцидента, когда доступ к учетным данным может оставаться заблокированным.
Задача, которая хорошо обрабатывает истечение, делает меньше после сбоя авторизации. Она останавливается, классифицирует ошибку, позволяет одному владельцу выполнить обновление, устраняет неопределенность и продолжает только записанную операцию. Такая сдержанность предотвращает дублирование побочных эффектов и оставляет оператору доказательства, а не груду повторов.
Вопросы и ответы
Что произойдет, если API-токен истечет во время задачи агента?
Токен доступа может истечь, пока запрос выполняется, агент ждет снятия ограничения скорости или между двумя обычными вызовами. Считайте истечение нормальным переходом состояния: остановите работу с учетными данными, получите одну замену через владельца и продолжайте только те действия, чьи предварительные условия все еще выполняются.
Стоит ли разрешать каждому ИИ-агенту самостоятельно обновлять свой API-токен?
Обычно нет. Компонент, которому принадлежат регистрация клиента и токен обновления, должен обновлять токены доступа. Если выдать каждому агенту собственный токен обновления, появятся конкурирующие обновления, отозвать доступ станет сложнее, а расследование инцидентов потребует больше усилий.
Всегда ли HTTP 401 означает, что токен доступа истек?
Нет. Код 401 может означать истекший токен, отозванное разрешение, неверный заголовок Authorization, неправильную аудиторию или неверного издателя. Проверьте код ошибки провайдера и заголовки ответа, прежде чем считать обновление правильным решением.
Сколько раз агенту следует повторять запрос после ошибки истекшего токена?
Используйте ограниченную политику повторов. Разрешите одну попытку обновления для подтвержденной ошибки истечения, повторяйте только идемпотентный запрос или запрос с ключом идемпотентности, а после неудачного повтора передавайте ситуацию на разбор.
Где хранить токены обновления для автономных задач?
Токен обновления обычно дает больше возможностей и живет дольше токена доступа. Храните его в узком credential-брокере, защитите более строгими локальными ограничениями и отзывайте, когда меняется граница доверия к клиенту или оператору.
Достаточно ли ключей идемпотентности для безопасного восстановления после истечения токена?
Нет. Идемпотентность защищает конкретную операцию от повторного побочного эффекта, а обновление токена восстанавливает авторизацию. Если задача может создать, списать, отправить или удалить что-то, для безопасного восстановления нужны оба механизма.
Что должен записывать аудит, когда агент обновляет токен?
Записывайте ссылку на учетные данные, отпечаток запроса, класс ответа, попытку обновления, поколение токена и итоговый результат. Не помещайте в журнал bearer-токены, токены обновления и необработанные заголовки Authorization.
Что делать долгоживущему агенту, если он не может обновить учетные данные?
Не следует продолжать отправлять запросы с учетными данными, которые уже считаются истекшими. Сохраните состояние задачи, сообщите, какая авторизация нужна, и дождитесь назначенного владельца или человека, который восстановит доступ.
Как проверить обработку истечения токена до выхода в продакшен?
Смоделируйте истечение перед первым вызовом, перед неидемпотентным вызовом, после того как удаленный сервис принял запись, но до получения ответа агентом, а также во время параллельной работы. Эти сценарии выявляют ошибки дублирования, которые не видны в простом тесте с 401.
Может ли обратный прокси безопасно управлять учетными данными для ИИ-агентов?
Прокси может добавлять заголовки, но это само по себе не решает вопросы владения учетными данными, подтверждений и целостности аудита. Надежнее держать секреты в компоненте, который выполняет внешнее действие, и возвращать агенту только результат.