Доступ AI-агента к API: прямые токены или действия через посредника?
Доступ AI-агента к API требует большего, чем узкие области действия токенов. Сравниваем прямые учетные данные и действия через посредника для задач, развертываний, поддержки и SSH.

AI-агенту для программирования не стоит выдавать общий токен SaaS только потому, что ему нужно вызвать API. Прямая передача токена превращает процесс агента в держателя учетных данных, а значит, открывает привычные пути утечки: подробный вывод команды, дочерний процесс, загруженный диагностический архив, результат работы инструмента или инструкция, которая велит агенту вывести свою конфигурацию.
Это не значит, что каждый вызов API должен превращаться в церемонию. Нужно разделять полномочия на выполнение действия и обладание учетными данными, которые это действие разрешают. Дайте агенту ограниченный способ запросить нужную работу, оставьте учетные данные у компонента, который ее выполняет, и подключайте человека там, где последствия этого требуют.
Разницу легко не заметить, потому что успешная команда curl выглядит безобидно. Проблемы начинаются, когда агент может создать развертывание в рабочей среде, закрыть обращение клиента, изменить задачу или выполнить удаленную команду. В этот момент токен уже не деталь настройки. Это операционные полномочия без человеческого суждения.
Прямая передача токена превращает агента в границу доверия
Если поместить SAAS_TOKEN в окружение агента, файл конфигурации, описание инструмента или доступное из подсказок хранилище секретов, агент сможет выполнять аутентифицированные запросы без отдельного компонента, который проверяет, относится ли каждый запрос к задаче. У токена могут быть разумные области доступа, но он все равно становится доступен любому поведению этого процесса и часто программам, которые он запускает.
Разработчики иногда утверждают, что агент не может «увидеть» переменную окружения. Обычное использование инструментов это опровергает. Агент может попросить оболочку показать окружение, запустить унаследовавший его скрипт, выполнить тестовый инструмент с подробным журналированием или записать снимок конфигурации в репозиторий. Конкретный путь утечки зависит от агента и его инструментов, поэтому безопасное предположение простое: если процесс может напрямую использовать токен-носитель, он обычно может привести к появлению токена там, где вы этого не планировали.
У токена-носителя есть и другое неприятное свойство. SaaS-сервис не может отличить задуманного агента от любого другого человека, скопировавшего строку. Спецификация OAuth 2.0 Bearer Token Usage, RFC 6750, говорит, что токены-носители нужно защищать от раскрытия при хранении и передаче, поскольку для их использования достаточно обладать ими. Это не академическая формулировка. Если агент выведет токен в журнал сборки, сервис увидит действующего вызывающего, а не ошибку.
Прямой доступ также размывает ответственность. Журналы аудита сервиса могут указать учетную запись бота, но редко показывают, какой запуск агента сформировал запрос, какие инструкции получил агент, кто его запустил и подтвердил ли человек получившийся эффект. В итоге остается событие API постфактум, но нет цепочки решений, которая объясняет, почему оно произошло.
Прямой токен может быть приемлем в одноразовой локальной песочнице, если одновременно выполняются все условия:
- Токен быстро истекает и имеет только минимальные права вне рабочей среды.
- В целевой системе нет данных клиентов, сотрудников или рабочей среды.
- Агент запускается в изолированном окружении, которое можно удалить.
- Человек может отозвать учетные данные, не нарушив общую работу.
Команды растягивают это исключение до обычной практики, потому что скопировать токен быстро. Скорость важна, но важна и уборка последствий, когда токен попадает в артефакт или агент следует вредоносной инструкции, спрятанной в описании задачи.
Области доступа ограничивают права, но не управляют намерением
Области OAuth, роли API и права репозитория отвечают на вопрос «что может делать эта идентичность?». Они не отвечают на вопрос «стоит ли выполнять этот запрос сейчас?». Это разные средства контроля, и смешивание их оставляет большую брешь.
Представьте токен системы задач с правом изменять задачи в одном проекте. Такая область доступа может быть правильной для агента, который сортирует ошибки. Инъекция в подсказку внутри импортированной задачи все равно может приказать агенту закрыть все открытые задачи, изменить приоритеты или оставить вводящие в заблуждение комментарии. Каждый запрос укладывается в разрешенные права. Но каждый запрос все равно ошибочен.
Та же проблема возникает у платформы развертывания. Токен с правами для одного приложения не знает, должен ли агент развернуть текущий коммит, откатить выпуск, изменить переменную окружения или удалить предварительную среду. Сервис видит разрешенные вызовы API. Только ваш рабочий процесс может решить, соответствуют ли они задаче и приемлемой цели.
Актуальная рекомендация IETF по безопасности OAuth 2.0 советует использовать короткоживущие токены доступа, по возможности токены, привязанные к отправителю, и более узкие права, чтобы уменьшить ущерб от токенов-носителей. Это хорошие практики. Они сокращают срок действия и радиус применения скопированных учетных данных. Но они не добавляют подтверждение для разрушительного, хотя и разрешенного действия и не объясняют намерения агента.
Не отвечайте на это созданием огромного каталога правил, который пытается предсказать каждую конечную точку и аргумент. Команды строят такие каталоги, а затем месяцами поддерживают исключения для новых API сервисов и необычных процедур выпуска. Узкий интерфейс действий и подтверждение человеком в нужный момент обычно лучше выдерживают реальную работу, чем язык политик, который никто не может уверенно читать.
Системам задач нужны пути записи, сохраняющие человеческое решение
Системы задач выглядят малорискованными, пока агент не начинает массово вносить изменения. Закрытие задачи может скрыть сообщение клиента. Изменение меток может нарушить отчеты сортировки. Комментарий может раскрыть внутренние рассуждения внешним участникам. Добавление пользователя к задаче может расширить доступ к чувствительному контексту.
Разделите работу агента на наблюдение и изменение. Разрешите ему получать задачи, искать метки, проверять связанные запросы на слияние и готовить проект обновления. Финальное изменение направляйте через действие, в котором указаны проект, задача, измененные поля и текст комментария. Перед отправкой в сервис рецензент должен увидеть фактическое содержимое.
Контракт запроса делает эту границу конкретной. Агент должен отправлять структурированное намерение, а не собирать командную строку с учетными данными.
{
"service": "issue-tracker",
"action": "update_issue",
"issue": "APP-184",
"changes": {
"labels_add": ["needs-reproduction"],
"comment": "I reproduced this on the current release and attached the failing test."
}
}
Исполнитель должен сам добавить учетные данные и вернуть ограниченный результат:
{
"ok": true,
"issue": "APP-184",
"updated_fields": ["labels", "comment"],
"request_id": "service-request-id"
}
Не возвращайте исходный заголовок Authorization, полный HTTP-трейс или отладочный объект с секретами. Это кажется очевидным, пока кто-нибудь не включает подробную диагностику HTTP во время сложной интеграции. Держите диагностику за отдельным путем устранения проблем, которым управляет человек, и проверяйте маскирование секретов, а не принимайте его на веру.
Даже после подтверждения сессии человеком агент может принять плохое решение. Поэтому разрушительные изменения задач должны иметь отдельный вариант подтверждения. Авторизация сессии отвечает на вопрос, может ли эта запущенная программа вообще использовать интеграцию. Подтверждение отдельного вызова отвечает на вопрос, должно ли произойти именно это изменение. Разница особенно важна, когда агент читает недоверенный текст из задач, документов или комментариев к запросам на слияние.
API развертывания несут последствия, выходящие за рамки кнопки выпуска
API развертывания часто предлагает больше, чем «развернуть эту версию». Через него можно изменить переменные окружения, запустить сборки, перезапустить рабочие нагрузки, создать домены, откатить версии, получить журналы или удалить ресурсы. Широкий токен развертывания становится удобным пультом управления для агента, который уже составил ошибочный план.
Разделяйте категории действий при работе с развертываниями. Проверка статуса сборки и получение общедоступных метаданных развертывания обычно не требуют особых мер. Перемещение артефакта в рабочую среду, откат выпуска, изменение ссылки на секрет и удаление окружения имеют разные последствия. Не объединяйте их под одним подтверждением «доступ к развертыванию».
Хороший запрос содержит неизменяемую ссылку на артефакт и явную цель. Отклоняйте расплывчатые значения вроде «последний», если сервис может разрешить их в коммит, дайджест образа или идентификатор сборки. Изменяемые метки создают разрыв между подтверждением и выполнением: рецензент подтверждает одно, а действие запускает другое.
{
"service": "deployment-platform",
"action": "promote_release",
"application": "billing-api",
"environment": "production",
"artifact": {
"git_commit": "8cf4f3a",
"build_id": "build-4921"
},
"reason": "Fixes the confirmed invoice retry failure"
}
Исполнитель должен проверить, что подтвержденные идентификаторы совпадают с запросом, который он отправляет. Он также должен записать идентификатор ответа сервиса и целевое окружение. Запись только «развертывание успешно» мало поможет в два часа ночи, когда кто-то спросит, какой артефакт был перемещен и кто это разрешил.
Не заставляйте агента считывать веб-панель, чтобы обойти проектирование API. Автоматизация браузера скрывает детали от проверки, неожиданно ломается и может нажать на устаревшее состояние страницы. Если у платформы есть API, используйте узкое действие-посредник поверх этого API. Если доступна только панель, примите, что часть операций останется ручной, пока вы не создадите надежный коннектор.
Инструменты поддержки клиентов требуют минимизации данных до автоматизации
Системы поддержки объединяют операционные действия и персональные данные. В задаче могут быть данные учетной записи, контактная информация, вложения, история заказов, журналы и эмоциональные сообщения. Прямой доступ агента поднимает два вопроса: может ли он читать материалы, которые ему не нужны, и может ли отправить вредный ответ от имени компании?
Не решайте эту проблему, передавая агенту полную переписку по задаче по умолчанию. Запрашивайте только нужные для работы поля. Если агенту нужно классифицировать обращение, ему могут понадобиться тема, текст без чувствительных данных и область продукта. Ему, скорее всего, не нужны все предыдущие внутренние заметки, платежная информация и вложения.
К действиям записи нужно относиться строже, чем к классификации. Полезный подход: сначала черновик, потом отправка. Агент создает предложение ответа со ссылками на задачу и внутренние источники, которыми он пользовался. Человек проверяет тон, фактические утверждения, данные конкретной учетной записи и то, не раскрывает ли ответ случайно внутренние заметки. Только после этого исполнитель публикует сообщение.
Закрытие, объединение и переназначение задач тоже должны иметь явную семантику действий. «Решить задачу» слишком расплывчато, если это незаметно отправляет письмо о закрытии, меняет таймер соглашения об уровне обслуживания или удаляет черновик. Схема запроса должна указывать побочный эффект, который выполнит сервис поддержки.
Именно здесь особенно соблазнительна широкая сервисная учетная запись. Она избавляет от сложностей с правами и позволяет агенту обрабатывать любую очередь. Но одна ошибочная инструкция может пересечь границы учетных записей. Назначайте сервисные идентичности очередям или командам, если это позволяет провайдер, а затем ограничьте интерфейс действий операциями, которые действительно нужны этой команде.
SSH дает право выполнять действия, а не просто использует другой синтаксис API
SSH требует отдельного подхода, потому что закрытый ключ может открыть оболочку, передачу файлов, перенаправление портов и доступ к инструментам со своими учетными данными. API развертывания может предлагать конечный набор операций. Удаленная оболочка способна на месте составить новые операции.
Передача AI-агенту для программирования закрытого SSH-ключа создает сразу два риска. Ключ может утечь, а агент может генерировать произвольные удаленные команды. Ограниченная учетная запись помогает, но ограниченная учетная запись с доступом к скриптам развертывания, учетным данным облачного CLI или конфигурации рабочей среды все равно может сделать гораздо больше, чем предполагала исходная задача.
Используйте посредника, который хранит закрытый ключ и получает запрошенные хост, команду и аргументы. В записи действия фиксируйте разрешенный хост и точную команду после обработки аргументов. Не подтверждайте строку оболочки, которую агент позже может переосмыслить через вложенные кавычки, подстановку команд или удаленный скрипт из недоверенной ветки.
Для чувствительных хостов отдавайте предпочтение фиксированным удаленным операциям вместо общей оболочки. Команду вроде release-status --service billing-api проще проверить, чем bash -lc '...'. Если нужно разрешить общую команду, показывайте ее в точности в том виде, в котором она будет выполнена, и требуйте подтверждение каждого вызова. Считайте sudo, установку пакетов, чтение файлов с секретами, перенаправление оболочки и команды копирования наружу случаями повышенного риска, а не обычным обслуживанием.
Верификация хоста SSH тоже важна. Клиент должен сверять ключ хоста сервера с управляемой записью в known_hosts. Автоматическое принятие нового отпечатка позволяет сетевой ошибке или ошибке DNS превратиться в событие использования учетных данных. Это сводит на нет смысл тщательно скрывать закрытый ключ.
Действия через посредника удерживают учетные данные и создают точку решения
Система действий через посредника держит токен SaaS или закрытый SSH-ключ внутри исполнителя и дает агенту интерфейс для запроса определенной работы. Исполнитель добавляет учетные данные, отправляет запрос и возвращает результат. Агент никогда не получает секрет, включая заполнитель, который он может случайно подставить в команду.
Это меняет характер сбоя. Агент с прямым доступом, приняв вредоносную инструкцию, может одновременно решить, какое действие выполнить, и выполнить его с многоразовыми учетными данными. Агент через посредника все еще может запросить плохое действие, потому что ни один механизм защиты не делает суждение языковой модели идеальным. Но исполнитель может определить вызывающего, потребовать подтверждение человека, оставить учетные данные недоступными агенту и записать запрос вместе с результатом.
Sallyport использует эту модель для вызовов HTTP API и SSH-команд: MCP-совместимый агент подключается через sp mcp, а приложение macOS хранит API- и SSH-учетные данные в зашифрованном хранилище и само выполняет действия. Блокировка хранилища запрещает любые действия, пока оно закрыто. Это правильное поведение, когда ответственного человека нет у машины.
Не путайте посредника с прокси, работающим по принципу «человек посередине». Прокси наблюдает общий трафик или передает его дальше. Шлюз действий получает конкретный запрос на действие, применяет правила авторизации, использует хранящиеся у него учетные данные и возвращает результат. Такая форма полезна тем, что дает точку подтверждения и запись аудита, вместо попытки интерпретировать весь трафик после того, как агент уже его сформировал.
Лучшие интерфейсы действий намеренно скучны. Они предоставляют небольшое число понятных глаголов, принимают структурированные параметры, отклоняют неоднозначные цели и сообщают достаточно, чтобы проверить результат. Универсальная конечная точка, принимающая произвольные URL, заголовки и тела запросов, может незаметно воссоздать прямой доступ, добавив лишь несколько шагов.
Проектирование подтверждений ломается, когда люди не могут оценить запрос
Запрос на подтверждение должен помогать человеку принять решение, а не просто прерывать работу. «Агент запрашивает доступ к инструменту поддержки» предлагает подтвердить неизвестное будущее. «Опубликовать этот ответ в задаче 4821 от имени команды поддержки» дает конкретное действие для проверки.
Для первого вызова нового процесса агента показывайте идентичность процесса и полномочия подписи кода. Идентичность процесса не декоративна. На машине разработки несколько терминалов, расширений и вспомогательных программ могут запросить одну и ту же интеграцию. Перед разрешением сессии рецензент должен понимать, какая подписанная программа обращается к интеграции.
Затем выбирайте подходящий уровень авторизации:
- Для малозначительных операций, которым нужны повторные чтения или обычные вызовы в рамках одного запуска агента, используйте подтверждение сессии.
- Для внешних сообщений, изменений состояния, развертываний, удаленных команд и необратимых действий используйте подтверждение каждого вызова.
- Блокируйте хранилище учетных данных, когда отходите от компьютера, чтобы любое действие завершалось отказом, а не ожидало подтверждения без присмотра.
- Отзывайте текущую сессию, если задача изменилась, агент ведет себя странно или процесс вам больше не знаком.
Усталость от подтверждений говорит о плохом проектировании. Если человек должен подтверждать каждое безобидное получение данных, он привыкнет нажимать кнопку не глядя. Если одно подтверждение дает агенту на весь день возможность изменять рабочую среду, интерфейс спрятал слишком много полномочий за удобством. Разделяйте типы действий по последствиям, оставляя обычную активность тихой, а важную активность конкретной.
Не повторяйте в тексте подтверждения расплывчатое описание самого агента. На уровне действия уже есть структурированные поля. Используйте их. Показывайте сервис, аутентифицированную учетную запись или роль, целевой проект или хост, операцию и весь текст, который покинет организацию и будет виден людям. Маскируйте учетные данные и личные поля, которые рецензенту не нужны.
Журналы должны связывать запуск агента с каждым внешним эффектом
Одних журналов провайдера недостаточно для работы агентов, потому что они начинаются на границе API. Одних расшифровок сессий агента тоже недостаточно, потому что в них может отсутствовать фактический запрос или они могут быть изменены. Нужны запись уровня запуска и запись уровня вызова, связанные надежным идентификатором.
Журнал уровня запуска должен указывать процесс агента, начало и конец сессии, подтверждение, которое ее разрешило, и способ немедленного отзыва. Журнал уровня вызова должен содержать запрос действия, результат авторизации и выполнения, цель и идентификатор запроса сервиса, если он существует. Не показывайте в обычных представлениях чувствительные тела запросов, если в них есть данные клиентов, но храните достаточно защищенных свидетельств для расследования инцидента.
Если журналы могут использоваться при споре, важна защита от незаметного изменения. Обычный локальный текстовый файл показывает полезную историю, но пользователь или скомпрометированный процесс может переписать его. Цепочка хешей делает каждую запись зависимой от предыдущей, поэтому позднее изменение нарушает проверку. Это не делает журнал безошибочным. Оно усложняет незаметную подмену и дает следователю проверяемое свойство целостности.
Sallyport строит журналы Sessions и Activity на основе доступного только для записи зашифрованного журнала аудита с цепочкой хешей. Цепочку шифротекста можно проверить офлайн с помощью sp audit verify, не имея ключа хранилища. При успешной проверке вывод должен выглядеть примерно так:
Audit chain: valid
Records checked: 184
First sequence: 1
Last sequence: 184
Если проверка сообщает о нарушенной последовательности или несовпадении хеша, сохраните файлы и проведите расследование, прежде чем полагаться на журнал. Не «исправляйте» подозрительный журнал удалением поврежденного хвоста. Так можно удалить единственное свидетельство того, когда и как изменилась запись.
Миграцию с прямых токенов стоит начать с самых опасных учетных данных
Не пытайтесь за одну неделю переделать все интеграции. Начните с учетных данных, неправильное использование которых сложнее всего исправить: полномочий на развертывание в рабочей среде, широкого доступа к поддержке клиентов или SSH-ключа к общим системам. Сначала уберите рабочие секреты из агента, а уже потом доводите до идеала каждый процесс.
Для каждой интеграции используйте такую последовательность:
- Определите, откуда агент сегодня получает учетные данные. Проверьте переменные окружения, файлы репозитория, секреты CI, профили оболочки, конфигурацию инструментов и скопированные подсказки.
- Перечислите операции, которые агент действительно выполняет, и разделите чтение, подготовку черновиков, изменения и удаленное выполнение. Большинство прямых токенов позволяют гораздо больше.
- Создайте структурированные запросы действий для нужных операций. Привязывайте каждую запись к именованной цели, а каждое развертывание к неизменяемой ссылке на артефакт.
- Переместите учетные данные в исполнитель, который агент не может прочитать. После проверки нового пути замените старые учетные данные.
- Намеренно проверьте отказы: заблокируйте хранилище, отклоните подтверждение, отзовите сессию, отправьте недопустимую цель и запустите проверку аудита. Демонстрация успешного сценария почти ничего не доказывает.
Этап замены обнаруживает распространенную ошибку: команды добавляют посредника, но оставляют исходный токен в окружении агента «на случай отказа». Так появляются два пути к одним и тем же полномочиям, и рано или поздно будет использован менее контролируемый. Уберите запасной путь. Если посредник пока не поддерживает нужную операцию, зафиксируйте временное исключение, ограничьте его область и срок действия и назначьте конкретного человека ответственным за его удаление.
Прямая передача токена удобна, потому что перекладывает сложное решение на строку в окружении процесса. Для одноразовых песочниц такой компромисс может быть разумным. Но для сервисов, влияющих на клиентов, развертывания или общую инфраструктуру, держите учетные данные вне агента и делайте само действие видимым до его выполнения.
Вопросы и ответы
Можно ли выдать AI-агенту для программирования персональный токен доступа?
Иногда, но только если у токена узкая область доступа, короткий срок действия, понятный владелец и задача не влечет последствий за пределами порученной агенту работы. Широкий персональный токен, скопированный в окружение агента, этим условиям не соответствует. Считайте такой вариант исключением с заранее записанной датой окончания действия, а не стандартной настройкой.
Безопасен ли для AI-агента доступ к API только для чтения?
Доступ только для чтения уменьшает ущерб от ошибочного запроса, но все равно раскрывает данные клиентов, метаданные исходного кода, заметки об инцидентах и внутреннюю структуру. Кроме того, токен остается в месте, где его могут раскрыть подсказки, журналы или дочерние процессы. Доступ только для чтения ограничивает права, но не решает вопрос обращения с учетными данными.
Делает ли OAuth прямой доступ агента безопасным?
Нет. Подтвержденная человеком OAuth-авторизация означает, что пользователь на определенный срок разрешил приложению действовать от его имени. Она не доказывает, что каждый последующий запрос соответствует задаче, и не защищает токен-носитель после его передачи процессу агента. Используйте OAuth для делегированной идентификации, когда это подходит, но по возможности не помещайте полученные полномочия в процесс агента.
Стоит ли AI-агенту использовать отдельную сервисную учетную запись?
Используйте отдельную идентичность, если сервис это поддерживает и ей можно назначить узкую роль. Но не считайте учетную запись бота средством изоляции, если агент по-прежнему получает постоянные учетные данные. Идентичность бота уменьшает масштаб возможного ущерба, а выполнение через посредника скрывает учетные данные и записывает каждое действие.
Что должно быть показано перед тем, как агент вызовет API?
Подтверждение должно показывать вызывающий процесс и описывать действие так, чтобы человек мог его оценить: целевой сервис, учетную запись, конечную точку или команду и существенный эффект. Подтверждение расплывчатого запроса вроде «разрешить доступ к инструменту» приучает одобрять вслепую. Подтверждение сессии и подтверждение отдельного вызова решают разные задачи, поэтому при соответствующем уровне риска используйте оба варианта.
Можно ли хранить API-токены агента в переменных окружения?
Нет, если машина или рабочая область агента имеют доступ к файлу, где хранится секрет. Переменные окружения часто передаются дочерним процессам, диагностике, отчетам о сбоях и отладочному выводу. Менеджер секретов помогает хранить значение, но при прямой передаче процесс агента все равно получает рабочий секрет.
Как доступ к API через посредника ограничивает ущерб от инъекций в подсказки?
Инъекция в подсказку может убедить агента сделать внешне законный вызов инструмента с незаконной целью. Слой действий-посредник не заставит модель идеально понимать намерения, но скроет учетные данные, запросит согласие в момент воздействия, ограничит доступные операции и оставит свидетельства для проверки. Эти меры превращают незаметную ошибку в событие, которое можно наблюдать и расследовать.
Что делать, если агент раскрыл API-токен?
Считайте токен раскрытым и немедленно отзовите или замените его. Затем проверьте журналы аудита сервиса, записи сессии агента, историю оболочки, журналы CI, локальные журналы и все артефакты, которые мог создать агент. Не ждите доказательств использования: токен-носитель не позволяет отличить законного владельца от того, кто скопировал строку.
Почему SSH для агентов опаснее токена SaaS API?
SSH добавляет выбор хоста, выполнение удаленных команд, перенаправление портов, передачу файлов и составление команд. Токен развертывания может обращаться к небольшому API, а SSH-учетные данные часто открывают операционную систему со множеством путей к одному и тому же результату. Держите закрытый ключ вне агента и требуйте ясной проверки команд, влияющих на рабочую среду.
Когда для AI-агентов стоит использовать шлюз действий?
Настройка оправдана, когда агент может затронуть рабочую среду, данные клиентов, платежи, развертывания или общую инфраструктуру. Для одноразовой локальной песочницы с короткоживущими правами минимального уровня прямой доступ может быть быстрее и приемлемее. Решающее значение имеют последствия, а не то, называет ли агент себя автономным.