Читать 7 мин

Проверки работоспособности локального шлюза действий агента

Проверки работоспособности локального шлюза действий агента: состояние приложения, отказ заблокированного хранилища, HTTP- и SSH-канарейки и целостность аудита без утечки учётных данных.

Проверки работоспособности локального шлюза действий агента

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

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

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

Запущенное приложение - лишь первое условие

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

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

#!/bin/sh
set -eu

APP_NAME="Sallyport"

if ! pgrep -x "$APP_NAME" >/dev/null 2>&1; then
  open -a "$APP_NAME"
  sleep 2
fi

if pgrep -x "$APP_NAME" >/dev/null 2>&1; then
  printf 'app=ready\n'
  exit 0
fi

printf 'app=unavailable\n' >&2
exit 2

Здесь намеренно заявлено немного. open -a просит macOS запустить приложение, а pgrep проверяет наличие процесса после этого запроса. Это не доказывает, что приложение завершило инициализацию, что его хранилище может ответить на запрос или что его MCP-совместимый слой принимает клиента. Apple описывает Launch Services как системный интерфейс для запуска и активации приложений, поэтому запуск через операционную систему лучше, чем жёстко заданный путь к пакету приложения.

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

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

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

Состояние хранилища должно быть явным результатом

Заблокированное хранилище работает нормально, когда оно запрещает действия. Если назвать это состояние сбоем, можно перепутать защитное поведение с отказом сервиса.

Шлюз хранилища Sallyport работает без исключений: пока хранилище заблокировано, любое действие запрещено. На совместимом оборудовании macOS шлюз использует Secure Enclave и Touch ID. Проверка должна сохранять это правило. Не пишите скрипт, который вводит пароли в интерфейс, хранит токен обхода биометрии или считает разблокированный рабочий стол доказательством того, что хранилище следует разблокировать.

Вместо логического значения используйте четыре состояния:

  • ready: приложение доступно, хранилище разблокировано, можно запускать контролируемые проверки.
  • locked: приложение доступно, но хранилище правильно запрещает действия.
  • denied-unexpectedly: хранилище разблокировано, однако ожидаемое канареечное действие запрещено.
  • unavailable: приложение или локальный путь MCP не отвечает.

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

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

{
  "run_id": "hc-2026-07-22T141501Z-8f29",
  "app": "ready",
  "vault": "locked",
  "http": "skipped",
  "ssh": "skipped",
  "audit": "verified",
  "reason": "credentialed checks require an unlocked vault"
}

Идентификатор запуска не является секретом. Он даёт операторам стабильное значение для последующего сравнения с записью активности. Не используйте в качестве идентификатора имя пользователя, серийный номер компьютера, URL конечной точки или название учётных данных.

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

Используйте канареечные цели, которые доказывают внедрение учётных данных

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

Создайте небольшой сервис, который принимает один путь, один метод и один вид учётных данных. Ожидаемый канареечный секрет храните на стороне сервиса. Такой же секрет храните в хранилище шлюза. Клиент, запускающий действие, не должен получать секрет, а сервис не должен его возвращать.

Контракт ответа может быть таким коротким:

{
  "check": "agent-gateway-http",
  "result": "ok",
  "request_id": "7d7a0f3c"
}

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

Используйте отдельный маршрут, например /agent-gateway-canary. Не добавляйте проверку к существующей рабочей конечной точке. Со временем рабочие конечные точки обрастают ограничениями частоты, перенаправлениями, согласованием содержимого, правилами кэширования, побочными эффектами биллинга и изменениями разрешений. Канареечный маршрут может оставаться намеренно простым.

RFC 9110 определяет семантику методов запросов и относит GET, HEAD, OPTIONS и TRACE к безопасным методам. Но в HTTP слово «безопасный» означает, что запрошенное действие не должно менять предполагаемое состояние ресурса. Это не значит, что вызов безвреден для аккаунта, журналов, квот или последующего поведения. API может записать GET, списать плату за запрос или вызвать побочный эффект из-за неудачной реализации. Создайте маршрут, поведение которого на сервере можно проверить, вместо того чтобы доверять знакомому глаголу.

Часто советуют использовать curl с рабочим API-токеном в проверке состояния. Такой вариант популярен, потому что занимает одну строку. Но он неверен: история оболочки, просмотр процессов, журналы CI и сообщения об ошибках создают слишком много мест, где может оказаться bearer-токен. Кроме того, такая проверка обходит поведение, которое вам нужно проверить, если обычно шлюз сам внедряет учётные данные.

Запуск должен обращаться к шлюзу через тот же маршрут MCP, который использует агент. Не создавайте для проверки обходной HTTP-клиент. Спрячьте вызов, зависящий от транспорта, за локальным адаптером, поскольку названия инструментов и формы запросов могут меняться. Адаптер принимает логическое действие, просит подключённый к MCP шлюз выполнить его и выдаёт только нормализованный результат.

{
  "action": "http_canary",
  "target": "canary-api",
  "method": "POST",
  "path": "/agent-gateway-canary",
  "expected_status": 200,
  "expected_check": "agent-gateway-http"
}

При сбое адаптер должен удалять секреты. Он может сообщить http_status=401, transport_error=timeout или response_schema=invalid. Но он не должен выводить исходящие заголовки, тело запроса, полный URL с параметрами запроса или необработанный ответ, если вы заранее не проверили безопасность этих данных.

Успешный HTTP должен доказывать нужное действие

Сам по себе 200 даёт слабое свидетельство. Проверка должна подтвердить ответ сервиса, метод и идентификатор цели, чтобы перенаправление, страница прокси или устаревший тестовый объект не превратились в ложный успех.

Пусть ответ канарейки обозначает тест, но не раскрывает учётные данные. Сравните несколько точных полей:

status=200
check=agent-gateway-http
result=ok
request_id=7d7a0f3c

Проверка должна принимать любой синтаксически корректный request_id, а затем сохранять его вместе с идентификатором запуска. Она должна отклонять отсутствующее поле, тело с заявленным успехом при статусе не 2xx и неожиданный тип содержимого. Captive portal, ошибка корпоративного прокси или неверная DNS-запись часто возвращают корректный HTTP-ответ. Это успех транспорта, а не успех действия.

Документация curl отмечает связанный момент: без --fail или --fail-with-body curl не считает HTTP-статус вроде 404 или 401 ошибкой команды. Для обычного клиента передачи это правильное поведение, но оно вводит в заблуждение тех, кто пишет мониторинг только по коду завершения curl. Если адаптер использует curl внутри, сохраняйте и результат процесса, и HTTP-статус, а затем определяйте успех по явному контракту.

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

Для тайм-аутов нужны отдельные обозначения. Ошибка DNS, отказ TCP, ошибка проверки TLS, отказ шлюза, ответ upstream 401, ответ upstream 500 и несовпадение ответа требуют разных ответственных. Если запуск обозначает всё это как http=failed, первые десять минут каждого инцидента уйдут на выяснение, где остановился запрос.

Полезная запись о сбое выглядит так:

{
  "run_id": "hc-2026-07-22T141501Z-8f29",
  "check": "http_canary",
  "outcome": "failed",
  "stage": "upstream_response",
  "http_status": 401,
  "request_id": null,
  "secret_material": "redacted"
}

Строка secret_material напоминает людям, читающим запись, о необходимости удаления секретов, но не доказывает, что удаление сработало. Проверьте это тестами: намеренно заставьте канарейку отклонить учётные данные, сохраните stdout и stderr запуска и найдите в этих файлах тестовый секрет. Секрет не должен появиться. Повторите тест с некорректным JSON, тайм-аутом, ошибкой TLS и ошибкой инструмента на стороне агента. Именно в ветках ошибок секреты чаще всего утекают.

Для SSH нужна изолированная цель, а не оболочка входа

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

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

Создайте отдельную учётную запись, например gateway-health, на контролируемом тестовом хосте. Задайте для неё принудительную команду в authorized_keys или аналогичное ограничение на стороне сервера. Принудительная команда должна игнорировать исходную команду, записывать временную метку и непрозрачный идентификатор запуска в локальный журнал аудита, а затем возвращать постоянный ответ.

Концептуальная запись authorized_keys выглядит так:

command="/usr/local/libexec/gateway-health",no-port-forwarding,no-agent-forwarding,no-X11-forwarding,no-pty ssh-ed25519 AAAA... gateway-health

Открытый ключ принадлежит канареечной идентичности шлюза. Закрытый ключ остаётся в хранилище. Текст AAAA... здесь намеренно неполный: создайте собственные ключи и не копируйте пример в рабочий файл.

Команда сервера не должна возвращать $SSH_ORIGINAL_COMMAND, переменные окружения или сведения об аутентификации. Она может возвращать фиксированный формат:

{"check":"agent-gateway-ssh","result":"ok","receipt":"c2b91a"}

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

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

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

Sallyport отправляет SSH через встроенный stateless-помощник sp-ssh. Поэтому тест должен проходить через обычный путь действия шлюза, а не запускать локальный закрытый ключ через OpenSSH. В противном случае вы проверите только хост и аккаунт, пропустив границу учётных данных, которую нужно подтвердить.

Проверка аудита - отдельное утверждение

Успешное канареечное действие и корректный журнал аудита являются разными утверждениями. Проверяйте оба.

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

Для каждого успешного HTTP- или SSH-действия соберите три несекретных свидетельства:

  • идентификатор проверки, созданный запуском;
  • непрозрачную квитанцию или идентификатор запроса, созданный канареечным сервисом;
  • время локального действия в UTC.

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

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

sp audit verify

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

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

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

Держите запуск вне проверяемой границы доверия

Запускайте Sallyport как приложение для Mac
Одно подписанное постоянно работающее приложение macOS в строке меню держит ядро хранилища внутри процесса, а не в отдельном демоне.

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

Практическая схема состоит из четырёх компонентов:

  1. Локальный планировщик запускает небольшой процесс проверки под отдельной учётной записью macOS.
  2. Процесс проверяет наличие приложения и вызывает локальный MCP-адаптер.
  3. Адаптер запрашивает именованные канареечные действия через шлюз и возвращает структурированные результаты без секретов.
  4. Процесс проверяет целостность аудита и записывает один короткий отчёт в защищённый локальный каталог.

У отдельной учётной записи не должно быть доступа к файлам данных хранилища. Apple размещает данные поддержки несatboxed-приложений macOS в каталоге текущего пользователя ~/Library/Application Support, но мониторинг не должен считать, что ему можно или нужно читать эти файлы. Проверке нужно поведение, а не копия содержимого хранилища.

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

checks:
  http_canary:
    target_alias: canary-api
    expected_status: 200
    expected_check: agent-gateway-http
    timeout_seconds: 10
  ssh_canary:
    target_alias: canary-ssh
    expected_check: agent-gateway-ssh
    timeout_seconds: 10
  audit:
    command: sp audit verify
    timeout_seconds: 15

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

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

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

Сбой должен давать полезный диагноз

Держите проверки вне хранилища
Sallyport сам выполняет HTTP- или SSH-действие, поэтому клиенту мониторинга не нужны сохранённые учётные данные.

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

Представьте реалистичную последовательность. Приложение работает. Хранилище разблокировано. HTTP-канарейка возвращает 401. Первая мысль - вставить канареечный токен в оболочку и вызвать конечную точку напрямую. Не делайте этого. Вы докажете, что токен работает, но обойдёте хранилище и создадите новый путь утечки секрета.

Вместо этого последовательно проверьте свидетельства:

  1. Убедитесь, что локальный MCP-адаптер достиг шлюза и получил результат действия, а не завершился по тайм-ауту до отправки.
  2. Проверьте, что псевдоним цели по-прежнему выбирает нужные сохранённые учётные данные и конфигурацию конечной точки.
  3. Проверьте журналы канареечного сервиса по непрозрачному идентификатору запроса, методу, маршруту и причине отказа. Не записывайте полученное значение авторизации.
  4. Найдите в журнале активности соответствующую попытку действия и проверьте цепочку аудита командой sp audit verify.
  5. Замените канареечные учётные данные, если проверка конфигурации показывает, что их ожидаемое значение изменилось или могло быть раскрыто.

Такая последовательность разделяет четыре сбоя, которые иначе выглядят одинаково: неверное сопоставление цели, отозванный или заменённый секрет, ошибка внедрения на шлюзе и изменение конфигурации upstream-сервиса. Она также помогает избежать знакомого инцидента, когда оператор «проверяет» секрет в терминале, а затем обнаруживает его в истории оболочки, буфере прокрутки или пакете поддержки.

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

Не скрывайте эти категории за одним красным или зелёным значком. Оператор, который видит vault=locked, audit=verified и http=skipped, точно понимает, что делать. Оператор, который видит health=warning, вынужден гадать.

Минимально полезное расписание состоит из двух потоков

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

Автоматический поток можно запускать в любое время, когда Mac должен быть активен. Он проверяет наличие приложения, отказ действия при заблокированном хранилище, классифицированный ответ локального пути MCP и успешность sp audit verify. Ни одна из этих проверок не должна требовать извлечения учётных данных или разблокировки хранилища.

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

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

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

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

Что должна проверять проверка шлюза действий локального агента?

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

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

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

Должен ли мониторинг считать заблокированное хранилище сбоем?

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

Как выглядит безопасная HTTP-проверка шлюза агента?

Безопасная HTTP-проверка обращается к специально созданной конечной точке, которая проверяет внедрённые учётные данные и возвращает фиксированный результат, например код состояния и идентификатор запроса. Не обращайтесь к рабочим API через GET только потому, что такие запросы кажутся безвредными.

Как проверить выполнение SSH, не предоставляя агенту доступ к оболочке?

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

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

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

Как не допустить утечки учётных данных в журналы во время проверки?

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

О каких сбоях проверки шлюза агента нужно сообщать?

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

Как часто запускать проверки действий с учётными данными?

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

Могут ли эти проверки работать, когда у Mac нет подключения к сети?

Даже без сети можно проверить доступность приложения, локальное поведение хранилища, локальную целостность аудита и подключение MCP. Проверить удалённое HTTP- или SSH-действие можно только после появления доступной контролируемой цели.

Sallyport

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

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