English · Русский

Модель безопасности для интеграторов

См. также: index.md (индекс) · developer-guide.md (быстрый старт, выпуск ключа, примеры запросов) · errors.md (обработка 401/403/404/409/429/501/503) · versioning-and-deprecation.md (политика semver) · openapi/index.html (полный справочник OpenAPI в Redoc).

Три вещи, которые должен понимать каждый интегратор до того, как считать этот API границей доверия.

1. Только localhost

Оба хоста — ProjectMaker (:5299) и ZennoPoster Core (:5300) — принимают только вызовы с loopback.

Запрос, чей адрес пира не является loopback (127.0.0.0/8, ::1 или их IPv4-mapped формы), отклоняется с 403 без тела; запрос без резолвируемого адреса пира отклоняется тоже. Проверка выполняется до маршрутизации и до аутентификации, поэтому покрывает и анонимные T0-маршруты (/ping, /capabilities, /auth/whoami). MCP-серверы применяют то же правило на своём ingress.

В этом релизе внешнего сетевого доступа нет, как нет и удалённого режима или режима TLS. Публикация контракта OpenAPI и этой документации — это именно публикация контракта, а не открытие API для сети. Если вам нужен удалённый доступ, ответственность за собственный туннель или прокси и его безопасность лежит на вас.

2. Ключ — не всемогущий

Выпущенный ApiKey намеренно не эквивалентен работе от имени владельца машины:

  • Скоупирован — каждая операция требует конкретный скоуп (task:read, project:edit, code:author, …); ключ несёт только те скоупы, с которыми он был выпущен.
  • С уровнем риска — каждая операция несёт свой тир (T0 чтение → T3 уровень ОС / класс RCE, например компиляция и запуск OwnCode); ключ работает только до своего maxTier.
  • Отзывается мгновенно — отзыв удаляет запись ключа; следующая же попытка аутентификации с ним завершается 401. Задержки распространения, о которой надо было бы думать, нет.
  • С сроком действия — выпускается с явным абсолютным expiresAt; после истечения аутентификация не проходит так же, как у отозванного ключа.
  • Никогда не хранится и не восстанавливается в открытом виде — необработанный ключ показывается ровно один раз при выпуске (в стиле GitHub PAT). Хранится только солёный хэш PBKDF2/HMAC-SHA256 (210 000 итераций, случайная соль на ключ), причём сам реестр ключей зашифрован на диске. Если вы потеряли необработанный ключ, пути восстановления нет: отозвать и выпустить новый.

От чего это НЕ защищает: ключ не защищает от того, кто контролирует машину, на которой работает API, — такой человек в любом случае может прочитать память процесса, интерфейс и файловую систему. Что ключ действительно даёт: он закрывает дыру открытого localhost для других локальных процессов без валидного ключа, ограничивает объём того, что может сделать любая отдельная интеграция (включая AI-агента) — скоуп плюс тир, и привязывает каждый вызов к именованному ключу, который можно отозвать отдельно.

3. Аудит

В журнал только для добавления (JSONL — один JSON-объект на строку) записывается администрирование ключей; журнал доступен через GET /api/v1/audit (только скоуп admin): временная метка, id ключа, метод, путь, код статуса, требуемые скоупы, тир, длительность. Это операции скоупа admin — выпуск, перечисление и отзыв ключей, а также чтение самого журнала, — включая отклонённые попытки.

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

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

Подтверждения человеком для вызовов с высоким тиром (T2/T3) нет: авторизация — это скоуп и тир, а сам вызов не оставляет записи в аудите. Не проектируйте интеграцию в предположении, что перед выполнением операции T3 (уровня ОС) человека о чём-то спросят или что вы найдёте её потом в журнале.


Generated from the frozen operation catalog of ZennoPoster. Questions and issues — github.com/ZennoLab/zennoposter-mcp/issues

This site uses Just the Docs, a documentation theme for Jekyll.