Читать 7 мин

Данные об авторизации: как доказать завершение действий AI-агента

Данные об авторизации AI-агентов должны фиксировать одобрение человека и результат API- или SSH-вызова, включая тайм-ауты и неизвестные состояния.

Данные об авторизации: как доказать завершение действий AI-агента

Запись о разрешении показывает, что человек позволил агенту попробовать выполнить действие. Но она не говорит, дошел ли запрос до сервиса, принял ли удаленный хост команду и произошло ли нужное изменение. Если считать разрешение доказательством завершения, журнал аудита будет выглядеть убедительно ровно до момента, когда проверяющий спросит: «Что произошло на самом деле?»

Для AI-агентов это различие особенно важно. Во время обычной задачи разработки они могут выполнять множество реальных действий. Человек один раз разрешает запуск агента, после чего тот создает тикет, меняет настройку развертывания, обращается к API рабочей системы или запускает удаленную команду. Для каждого действия нужны данные с собственным смыслом. Решение человека и полученный результат должны рассматриваться вместе, но заменять друг друга они не могут.

Разрешение фиксирует право, а не завершение

Данные об авторизации отвечают на вопрос, разрешил ли признанный ответственный выполнить определенное действие в конкретное время. Данные об исполнении показывают, что пытался сделать шлюз действий и что вернула целевая система. В архитектуре аудита, которая сохраняет только первый ответ, остается большая брешь.

Представьте агента, получившего разрешение вызвать API для создания токена доступа. Шлюз отправляет запрос, но соединение обрывается после обработки запроса сервисом и до того, как вызывающая сторона получает ответ. Разрешение остается действительным. Запись «разрешено» не говорит проверяющему, существует ли токен. Еще хуже, если запись утверждает «завершено» только потому, что шлюз отправил байты: так неопределенность превращается в ложный факт.

С SSH возникает та же ошибка. Человек разрешает deploy.sh. SSH-клиент проходит аутентификацию, удаленная оболочка запускается, а сетевое соединение обрывается во время работы скрипта. Завершился ли скрипт? Успел ли он частично изменить систему? Запись о соединении этого не покажет. Нужен код завершения на удаленной стороне, если клиент его получил, и четкая запись о неизвестном результате, если не получил.

Разделяйте эти вопросы:

  • Разрешил ли человек или утвержденный механизм этот процесс агента?
  • Какие именно возможности покрывает разрешение?
  • Отправил ли шлюз действие в место назначения?
  • Какой результат вернула целевая система или транспорт?
  • Смогут ли проверяющие позднее убедиться, что историю никто не изменял?

Многие команды сжимают все пять вопросов в одно событие agent_action. Для панели это удобно, но при расхождении фактов бесполезно. Храните связанные события отдельно, а в интерфейсе показывайте их вместе.

NIST Special Publication 800-53 Rev. 5 предъявляет похожее практическое требование в контроле AU-3. Содержание записи аудита включает то, что произошло, время и место события, источник, результат и связанную с событием личность. Важна здесь не формулировка чек-листа, а требование включать результат в запись. Решение о разрешении не может заполнить это поле.

Для двух записей нужны разные поля

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

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

Полезная форма выглядит так:

{
  "event_type": "authorization.granted",
  "action_id": "act_01JX7K8N4Q",
  "session_id": "ses_01JX7JYQ2M",
  "time": "2025-03-08T14:21:18Z",
  "agent_process": {
    "pid": 4812,
    "code_signing_authority": "Example Development Team"
  },
  "human_decision": {
    "method": "local_confirmation",
    "actor": "local_user"
  },
  "requested_action": {
    "channel": "http",
    "credential_ref": "billing-api-prod",
    "method": "POST",
    "destination": "api.internal.example",
    "path": "/v1/refunds"
  }
}

По умолчанию в этой записи не должны находиться секрет API, закрытый SSH-ключ, заголовок авторизации или необработанное тело запроса. Хранилище аудита, заполненное учетными данными, само становится путем для второй утечки. Если проверяющим нужно различать запросы с закрытым содержимым, храните криптографический дайджест защищенной части и короткое обезличенное резюме по задокументированным правилам.

Запись исполнения начинается, когда шлюз пытается выполнить действие. В ней должно быть указано, достигло ли действие границы протокола и что вернулось в ответ. Для HTTP сохраните метод, место назначения, статус ответа, транспортную ошибку, размер ответа и ограниченную классификацию ответа. Для SSH сохраните учетную запись, идентификатор хоста, представление команды, код завершения, сигнал, если он был, и результат соединения на стороне клиента.

{
  "event_type": "execution.finished",
  "action_id": "act_01JX7K8N4Q",
  "time": "2025-03-08T14:21:20Z",
  "channel": "http",
  "attempt": 1,
  "delivery": "response_received",
  "result": {
    "http_status": 201,
    "response_bytes": 428,
    "response_digest": "sha256:..."
  }
}

Не записывайте success: true как единственное поле результата. Смысл успеха различается в разных протоколах и продуктах. HTTP 201 означает, что сервер сообщает о создании ресурса. HTTP 202 означает, что сервер принял работу для последующей обработки. Код завершения SSH 0 означает, что удаленная команда сообщила об успехе, но скрипт все равно мог проигнорировать внутреннюю ошибку. Типизированный результат дает проверяющим факты, а не расплывчатую зеленую метку.

Доверенная граница действий должна создавать связь

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

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

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

Для HTTP-запроса используйте отдельный заголовок, который целевая система согласна записывать, например X-Action-ID. Не путайте этот заголовок с ключом идемпотентности. Идентификатор действия помогает расследованию. Ключ идемпотентности позволяет поддерживающему серверу распознать повторную операцию изменения. Иногда одно значение может выполнять обе роли, но только после того, как владелец сервиса подтвердит его смысл и срок хранения.

Authorization: action_id=act_01JX7K8N4Q
Outbound request: POST /v1/refunds
Request header: X-Action-ID: act_01JX7K8N4Q
Response: 201 Created
Execution record: action_id=act_01JX7K8N4Q, delivery=response_received

Не полагайтесь на одни временные метки при связывании записей. Часы расходятся, запросы пересекаются, а агенты могут выполнять одинаковые вызовы в одну секунду. Метки времени помогают восстановить порядок, но не доказывают принадлежность события.

Важен и идентификатор сессии, но он отвечает на более общий вопрос: какой запуск процесса агента создал этот запрос? Сохраняйте оба идентификатора. Сессия показывает, какой процесс получил постоянное разрешение. Идентификатор действия показывает, какая конкретная операция получила конкретный результат.

Коды состояния HTTP дают данные, но имеют ограничения

Ответ HTTP дает более сильные доказательства исполнения, чем локальное разрешение, но его все равно нужно правильно интерпретировать. Записывайте итоговый статус и достаточно контекста для его объяснения. Не сводите любой статус вне диапазона 200 к ошибке.

200 OK или 201 Created являются явным сообщением сервера. 204 No Content часто означает успешную операцию без тела ответа. 202 Accepted означает другое: целевая система получила запрос на асинхронную обработку, но окончательная работа позднее может завершиться ошибкой. В записи исполнения укажите accepted_for_async_processing, а затем, если сервис поддерживает такой подход, свяжите с тем же действием последующую проверку состояния или обратный вызов.

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

Ошибки клиента и сервера тоже содержат полезные факты. 403 доказывает, что сервис отклонил запрос. 409 может показать, что дубликат или конфликтующее состояние уже существует. 429 означает, что целевая система пока отказалась выполнять работу. 500 говорит о том, что сервер сообщил об ошибке, но не доказывает, что изменение не произошло. Тело ответа может уточнить результат, но хранить его следует только после обезличивания и ограничения размера. Ответы об ошибках часто содержат больше операционных подробностей, чем успешные ответы.

Транспортные сбои должны иметь собственные значения результата. Различайте, например, dns_failure, tls_validation_failure, connect_timeout, write_interrupted, response_timeout и connection_reset. Такие результаты показывают проверяющему, где заканчивается уверенность.

Опаснее всего прерывание после того, как шлюз начал отправлять запрос. Сервис мог выполнить действие. Пометьте состояние как unknown_remote_outcome, а не как ошибку, поскольку у клиента нет ответа. Если вызов меняет состояние, агент должен остановиться и использовать безопасный способ сверки. Это может быть запрос к сервису по ключу идемпотентности, чтение ресурса по идентификатору запроса или просьба к человеку проверить целевую систему.

Для SSH нужны данные об удаленном процессе

Проверяйте вызовы, а не догадки
Открывайте журнал Activity и проверяйте отдельные вызовы HTTP API и команды SSH.

Журналы SSH часто останавливаются на записи «подключено к хосту». Это доказывает лишь то, что клиент установил SSH-сессию. Запись ничего не говорит о результате команды и может даже не показывать, какой именно хост ответил, если не записывать проверку ключа хоста.

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

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

requested_command: /usr/local/bin/rotate-service-token --project payments --token [redacted]
command_digest: sha256:...
remote_exit_status: 0
remote_signal: null
connection_result: clean_close

Код завершения 0 является данными от удаленной команды, но не доказывает, что произошел каждый ожидаемый бизнес-эффект. Плохо написанный shell-скрипт может запустить curl, проигнорировать его ошибку и все равно завершиться с кодом 0. Если скрипт под вашим контролем, заставьте его явно сообщать об ошибках и возвращать ненулевой код при сбое обязательной операции. Если вы не управляете им, точно записывайте результат команды и не утверждайте большего.

К интерактивным SSH-сессиям нужно относиться с осторожностью. Они создают огромный разрыв между «разрешение выдано» и «команды выполнены». Ограниченная удаленная команда дает более надежные данные, чем общий интерактивный shell для агента. Если задаче нужны несколько команд, используйте проверенный скрипт с явными кодами выхода или создавайте отдельную запись действия для каждой команды. Это менее эффектно, чем свободная печать агента в терминале, зато значительно упрощает расследование.

Проверка хоста должна оставаться включенной. Запись о том, что агент выполнил команду на build-01, мало значит, если клиент принял непроверенный хост во время сетевой атаки или после ошибочной замены хоста. Сохраняйте в событии исполнения проверенный отпечаток ключа хоста. Тогда проверяющие смогут отличить имя хоста от его криптографической идентичности.

Тайм-аут должен приводить к неопределенности, а не к шквалу повторов

Частая ошибка начинается с изменяющего вызова API и заканчивается тайм-аутом. Агент получил разрешение. Шлюз открыл соединение и отправил запрос. Целевая система выполнила изменение, но ответ исчез, либо система так и не получила последние байты. Для вызывающей стороны эти варианты выглядят одинаково.

Представьте, что агент создает тикет производственного инцидента через API. Он отправляет:

POST /v1/incidents
Idempotency-Key: inc_72f9c
X-Action-ID: act_01JX7K8N4Q

Клиент ждет, а затем записывает response_timeout. Аудит только разрешений говорит, что человек одобрил тикет. Упрощенный журнал действий утверждает, что создание тикета не удалось. Ни одно из этих утверждений небезопасно.

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

В последовательности есть три отдельных факта:

  1. Человек одобрил исходный запрос.
  2. Шлюз не смог подтвердить первоначальный результат.
  3. Последующее чтение или идемпотентный повтор установили итоговое состояние.

Не удаляйте тайм-аут после сверки. Он объясняет, почему возникло последующее действие. Он также показывает повторяющуюся транспортную проблему, которую скрыл бы красивый счетчик успешных операций.

У SSH есть аналогичная проблема. Удаленная команда может продолжить работу после потери локального соединения. Не повторяйте команды автоматически, если их идемпотентность нельзя надежно доказать. Лучше использовать идентификатор удаленной операции, файл состояния с контролируемыми правами или API целевой системы, возвращающий состояние. Если ничего этого нет, запишите неизвестный результат и потребуйте проверки человеком. Дублирующиеся команды развертывания и без того причиняли достаточно вреда, чтобы агент еще и повторял их с машинной скоростью.

Разрешение на сессию и разрешение на вызов решают разные задачи

Остановите рискованный запуск агента
Мгновенно отзовите запуск агента в журнале Sessions, если его работу нужно остановить.

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

Авторизация каждого вызова фиксирует решение человека при каждом использовании выбранных учетных данных. Применяйте ее для операций, где каждое место назначения, изменение или удаленная команда заслуживают отдельного внимания. Запись исполнения все равно необходима. Человек может одобрить опасный вызов API, а сервис отклонит его, частично обработает или не ответит вовремя.

Различие особенно заметно, когда проверяющие спрашивают: «Кто одобрил это изменение?» Запись сессии может ответить: «Этот подписанный процесс агента имел право вызывать данный канал». Запись отдельного вызова ответит: «Человек одобрил именно этот запрос в такое-то время». Но ни одна из них не отвечает на вопрос: «Произошло ли это?» На него могут ответить только данные об исполнении.

В запросе на подтверждение должно быть достаточно информации для осмысленного решения: идентификатор вызывающего процесса, ссылка на учетные данные, место назначения, метод или команда и указание, меняет ли запрос состояние. Запрос «Разрешить доступ агенту?» фиксирует нажатие кнопки, но почти не сохраняет полезного намерения.

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

Цепочки хешей защищают историю, но не истинность утверждения

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

Это свойство особенно важно для активности агентов, поскольку чаще всего хотят удалить самые неудобные записи: отклоненное действие, неудачное развертывание, запрос не тому сервису или сессию, продолжавшуюся дольше ожидаемого. Журнал, который администраторы могут незаметно редактировать, не выдержит серьезной проверки.

Но цепочка хешей не делает ложную запись правдивой. Если недоверенный агент передаст «HTTP 201», а журнал честно включит эту ложь в цепочку, цепочка докажет лишь то, что ложь сохранилась. Сборщик должен наблюдать событие на границе действий. Шлюз должен создавать результат исполнения после получения ответа или обнаружения транспортной ошибки.

NIST SP 800-92, Guide to Computer Security Log Management, предупреждает, что журналы нужно защищать на этапах создания, передачи, хранения, анализа и удаления. Практический вывод шире, чем простая централизация текстовых файлов. Сохраняйте исходный источник события, защищайте последовательность, контролируйте, кто может менять записи, и делайте проверку возможной без широкого доступа к секретам, которые использовали действия.

Sallyport записывает запуски агентов и отдельные вызовы в один защищенный от записи зашифрованный журнал аудита, связанный цепочкой хешей. Команда sp audit verify проверяет цепочку в автономном режиме поверх шифротекста, не требуя ключа хранилища. Так проверяющий целостность истории отделен от процесса, который может использовать рабочие учетные данные.

Команда проверки должна выдавать однозначный результат и обозначать проверенный диапазон. Например:

$ sp audit verify
verified: 1847 records
chain: valid
first_record: 2025-03-01T08:15:02Z
last_record: 2025-03-08T14:21:20Z

Действительная цепочка не решает вопрос, выполнил ли внешний API свое обещание. Но она подтверждает, что сохраненное шлюзом описание разрешения и полученного результата не изменилось незаметно.

Проверяйте связи, а не отдельные числа событий

Отделите разрешение от активности
Sallyport хранит запуски агентов и отдельные вызовы в разных журналах единого зашифрованного аудита.

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

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

Используйте небольшой набор запросов или отчетов, которые заставляют отвечать на такие вопросы:

  • Какие одобренные изменяющие действия завершились неизвестным удаленным результатом?
  • Какие вызовы получили ответ за пределами области разрешения?
  • Какие команды SSH завершились без кода выхода?
  • Какие разрешения на сессию породили действия после ожидаемого завершения задачи?
  • Какие идентификаторы действий есть в локальных записях, но отсутствуют в журналах целевого сервиса?

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

Журналы сессий и активности Sallyport делают такое разделение практичным: один вид показывает запуск агента и состояние его отзыва, другой, отдельные вызовы. Проверяющие должны переходить между ними по идентификаторам сессии и действия, а не считать какой-либо один журнал полной картиной.

Используйте явный словарь степеней уверенности. authorized, attempted, response_received, remote_exit_received, denied, failed_before_send и unknown_remote_outcome легче защищать, чем один флаг успеха. Когда команда применяет эти термины последовательно, сложные случаи перестают исчезать в приятных зеленых панелях.

Сначала создайте данные, затем расширяйте доступ агентов

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

Затем проверяйте записи в условиях сбоя, а не только на удачном пути. Одобрите запрос и оборвите соединение после отправки. Запустите SSH-команду, которая вернет ненулевой код. Вызовите ошибку DNS. Отзовите сессию агента и убедитесь, что последующие вызовы получают записи об отказе. Проверьте, может ли проверяющий объяснить каждое событие, не открывая исходный файл и не спрашивая агента, что он имел в виду.

Агенту можно разрешить действовать, не передавая ему учетные данные. Но ему нельзя позволять определять, что произошло. Сохраняйте запись решения, сохраняйте результат исполнения и оставляйте неопределенность видимой, когда сеть не дает надежного ответа.

Вопросы и ответы

Доказывает ли журнал разрешений, что AI-агент выполнил действие?

Нет. Разрешение подтверждает, что человек допустил попытку выполнить действие на оговоренных условиях. Для подтверждения завершения нужны отдельные данные об исполнении: статус ответа, код завершения SSH, результат удаленной команды и время, связанное с тем же действием.

Что должно входить в запись аудита разрешения AI-агента?

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

Как связать разрешение с ответом API или результатом SSH?

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

Доказывает ли успешное сетевое соединение, что действие API или SSH выполнено успешно?

Обычно нет. Успешное TCP- или TLS-соединение доказывает лишь, что клиент достиг чего-то, что приняло соединение. Для HTTP сохраните итоговый статус ответа и результат запроса. Для SSH сохраните код завершения удаленной команды, а также ошибки соединения или аутентификации.

Что записывать, если действие агента завершилось тайм-аутом?

В записи должно быть указано, что система не получила результат, а также причина: тайм-аут, сброс соединения, завершение процесса или прерванное локальное действие. Считайте состояние удаленной стороны неизвестным, пока целевая система не предоставит безопасный способ проверки или механизм идемпотентности.

Может ли AI-агент безопасно повторить неудачный вызов API?

Только если целевая система поддерживает безопасный, аутентифицированный способ проверить итоговое состояние. Повторная отправка изменяющего запрос после тайм-аута может создать дубликаты тикетов, платежей, развертываний или изменений пользователей. Идемпотентные ключи и проверки состояния после записи безопаснее слепых повторов.

Должны ли журналы аудита SSH содержать полную команду?

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

В чем разница между журналированием с защитой от подмены и достоверным журналированием?

Защита от подмены означает, что проверяющий может обнаружить измененные, удаленные или переставленные записи. Это не значит, что каждое утверждение в журнале истинно. Цепочка хешей защищает историю после сбора, а доверенные точки сбора и аутентифицированные идентификаторы определяют, описывают ли записи реальные события.

Когда нужно требовать подтверждение для каждого действия агента?

Авторизация сессии определяет, может ли конкретный процесс агента начать использовать набор разрешений в рамках своего запуска. Авторизация каждого вызова требует решения человека при каждом использовании выбранных учетных данных или действия. Второй вариант подходит для действий, влияние которых человек должен оценивать заново каждый раз.

Как шлюз действий улучшает аудит AI-агентов?

Шлюз может не допускать учетные данные к агенту, определить вызывающий процесс, запросить подтверждение человека, выполнить действие по HTTP или SSH и записать результат в момент его появления. Такой подход дает более надежные данные, чем просьба к агенту задним числом рассказать, что он сделал.

Sallyport

Sallyport выполняет API-вызовы и SSH-команды за вашего ИИ-агента. Ключи остаются в локальном хранилище на вашем Mac; вы подтверждаете каждый запуск, и каждое действие попадает в запечатанный журнал.

© 2026 Sallyport · Открытый код по лицензии Apache-2.0 · Oleg Sotnikov