Документация Эксплуатация плагинов

Эксплуатация плагинов: внедрение, ограничения, публикация

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

Формы развёртывания

Выберите способ установки с учётом вашего развёртывания Mockarty:

  • Один узел: загрузите .zip в Администрирование → Плагины. Загрузка файла работает и с PostgreSQL, и с SQLite.
  • Кластер: используйте ту же страницу. Административные узлы разделяют установленные пакеты и их состояние, поэтому не нужно загружать файл на каждый узел. Перед включением плагина проверьте соединение узлов с общей базой данных и службой кластерных сообщений.
  • Desktop: файл можно установить без сети. Для просмотра удалённого реестра нужно подключение к нему.
  • Изолированная установка: загрузите локальный файл. Удалённый реестр необязателен и выключен, пока его не настроят.

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

Переменные окружения

Переменная По умолчанию Эффект
MOCKARTY_PLUGINS_ENABLED вкл Рубильник. false / 0 / off убирает API, раздел UI и агентские тулы плагинов целиком.
MOCKARTY_PLUGINS_REGISTRY_URL выключен URL index.json реестра (например, GitHub raw URL или внутренний каталог). Если переменная не задана, внешний реестр отключён и запросов к нему нет. Укажите URL явно, чтобы включить каталог, или off, чтобы отключить источник, заданный в другом месте.
MOCKARTY_PLUGINS_REGISTRY_ALLOW_HTTP выкл Dev-режим: разрешает http:// download-ссылки только для loopback-хостов — автор плагина прогоняет полный цикл list→install против локального статического сервера. В продакшне не нужен.
MOCKARTY_PLUGINS_REGISTRY_ALLOW_PRIVATE выкл Корпоративный режим: реестр может жить в интранете (без доступа к GitHub) — приватные диапазоны и plain http:// допускаются только для клиента реестра. Cloud-metadata и link-local остаются заблокированы в любом случае. Используйте с внутренним статическим хостом, отдающим index.json + zip’ы.
MOCKARTY_PLUGINS_TRUSTED_KEYS не задан Base64-ключи ed25519 через запятую. Бандлы с подписью одного из них получают signatureStatus: trusted.
MOCKARTY_PLUGINS_REQUIRE_SIGNATURE выкл true — отказ устанавливать неподписанные бандлы и бандлы с недоверенной подписью (для регулируемых контуров).
MOCKARTY_WIKI_IFRAME_ALLOWLIST не задан (Wiki) ограничивает хосты для !iframe:-вставок; none запрещает внешние вставки.

Политика установки в пространство

Может ли владелец пространства сам ставить no-code плагины в своё
пространство — это переключатель администратора в интерфейсе (Admin →
Plugins), а не переменная окружения: он меняет поведение продукта, поэтому
живёт там, где администратор включает его без передеплоя. По умолчанию ВЫКЛ.
Когда включено, владелец пространства может установить только no-code бандлы
(mock-киты, контент-паки, wiki-макросы, типы связей, пресеты коннекторов) из
видимого его пространству маркетплейса, с областью действия только внутри
этого пространства; WASM-модули, UI-панели, типы событий и типы задач
по-прежнему ставит администратор. Каждая установка аудируется
(plugin_ns_installed), и у администратора остаётся kill-switch — он видит и
может удалить плагины пространств в том же табе.

Жёсткие лимиты

Проверяются при установке и падают со структурным кодом ошибки; не
настраиваются:

Лимит Значение
Размер zip-бандла (сжатый) 32 MiB
Файлов в бандле 2000
Распакованный объём всего / на файл 64 MiB / 16 MiB
Вкладов на семейство (kits, packs, links, …) 50
Длина name / description 200 / 4000 символов
Имя plugin task-type префикс plugin-, ≤ 19 символов
Имя plugin event-type префикс plugin.

Модель безопасности (что плагин может и чего не может)

  • Декларативные вклады (мок-киты, контент-паки, коннекторы, связи,
    event/task-типы) — это данные. Хост сам их отрисовывает и применяет; они
    ничего не исполняют.
  • Код исполняется только в WebAssembly-песочнице: без диска, сети, часов и
    памяти хоста — с лимитами топлива, времени и памяти на вызов. Сломанный или
    медленный модуль роняет только собственный вызов, никогда запрос или процесс.
  • UI-панели живут в sandboxed iframe со строгой Content-Security-Policy на
    opaque origin: ни сессии хоста, ни cookie, ни доступа к DOM. Хост передаёт
    панели её (несекретные) настройки через postMessage.
  • Загрузки пиннятся и охраняются. Установка из реестра сверяет sha256
    бандла с индексом; установка по ссылке принимает опциональный sha256-пин; обе
    идут через SSRF-защищённый HTTP-клиент, отвергающий loopback и приватные
    адреса.
  • Секретов в манифесте не бывает. Коннектор-плагины поставляют шаблоны
    конфигурации; учётные данные вводятся per-namespace в Настройки → Интеграции
    и шифруются при хранении.
  • Мультитенантность: администратор устанавливает один раз; каждый
    неймспейс независимо включает/выключает плагин и переопределяет его
    настройки. Все каталоги и hot-path чтения фильтруются по неймспейсу.
  • Аудит: каждая установка, включение, выключение, удаление и
    неймспейс-переключение попадает в журнал аудита с действующим пользователем.

Структурные коды ошибок

Ошибки плагин-API возвращают {"error": "<детали>", "code": "<стабильный код>"}.
UI показывает локализованное сообщение по коду; агенты и скрипты ветвятся по нему:

bundle_too_large, bundle_invalid, manifest_missing, manifest_invalid,
asset_missing, signature_invalid, host_incompatible,
contribution_conflict, not_found, storage_error, internal.

Публикация в реестр

Реестр — это статический index.json плюс скачиваемые zip’ы; эталонная
конфигурация — GitHub-репозиторий с Releases, но подойдёт любой статический
хостинг.

  1. Соберите и проверьте бандл: mockarty-cli plugin pack ., затем
    mockarty-cli plugin inspect <zip>.
  2. Сгенерируйте запись индекса:
    mockarty-cli plugin publish <zip> --download-url https://github.com/<org>/<repo>/releases/download/<id>-v<version>/<zip>
    — команда печатает готовый JSON-объект с корректным sha256.
  3. Загрузите zip как Release-ассет ровно по этому URL и добавьте объект в
    массив plugins файла index.json репозитория (в общем реестре — через
    pull request).
  4. Укажите серверам raw-URL индекса в MOCKARTY_PLUGINS_REGISTRY_URL. Каталог
    появится в Админ → Плагины; установка сверит sha256.

Дайджест — это дайджест того файла, который вы загружаете, а не заново
упакованного исходника.
Повторная упаковка одного и того же плагина может
дать другие байты: архив хранит mtime и права файлов, а компрессор зависит от
сборки. Поэтому sha256, снятый с бандла, собранного на вашей машине, может не
совпасть с артефактом в релизе — и установка будет отклонена с ошибкой
downloaded bundle sha256 … does not match the registry index. Берите дайджест
у того файла, который реально публикуете (mockarty-cli plugin publish <загруженный.zip> его печатает), и перезапускайте публикацию записи всякий раз,
когда заменяете ассет.

Обновление версии — по месту: публикация 1.1.0 и установка поверх 1.0.0
сохраняет состояние «включён» и атомарно меняет вклады.

Kill-switch возможностей

Всё, что вносит плагин или внешняя интеграция — компоненты миссий, типы
задач раннера — перечислено в едином каталоге возможностей
(GET /api/v1/capabilities) рядом со встроенными. Когда динамическую
возможность нужно погасить немедленно — скомпрометированный поставщик,
некорректно ведущая себя интеграция — администратор открывает Автономные
миссии → Возможности
и нажимает Отключить. Для автоматизации та же
операция доступна одним вызовом:

curl -X POST "$MOCKARTY_URL/api/v1/capabilities/<key>/revoke" \
  -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  -d '{"reason": "ключ поставщика скомпрометирован"}'

Причина обязательна и показывается везде, где возможность появилась бы.
Одного вызова достаточно:

  • возможность становится недоступной в каталоге:
    availability.reason: "revoked" и ваша причина в revokedReason — и
    человек, и агент видят, почему, прежде чем строить планы вокруг неё;
  • управляемые оператором строки содержат operatorManaged: true,
    managementKey и точный managementNamespace; интерфейс миссий использует
    эту устойчивую идентичность для отключения и восстановления, не угадывая её
    по отображаемому фасету и не смешивая локальную строку пространства с
    политикой всего инстанса;
  • если возможность пришла из плагина, этот плагин выключается на всех узлах
    тем же вызовом (ответ называет его в sourceDisabled);
  • переустановка или повторное включение источника не воскрешает
    возможность — попытка завершается ошибкой contribution_conflict с
    сохранённой причиной, пока запрет не снят явно.

Операция работает fail-closed. Если Mockarty не может выключить источник
плагина либо прочитать/сохранить устойчивое состояние kill-switch, он
возвращает 503 и не заявляет об успешном запрете, пока исполняемые вклады
могут оставаться активными. После восстановления базы/хранилища плагинов
повторите вызов; уже выключенный плагин во время повтора остаётся выключенным.

Снятие запрета — осознанное решение из двух шагов:
POST /api/v1/capabilities/<key>/restore убирает отметку, а
плагин-источник всё равно нужно включить вручную. Внешние возможности,
зарегистрированные, но не исполняемые на этом сервере, отображаются в
каталоге с availability.reason: "declared" — видны для планирования, но
не являются обещанием исполнения. Администратор также может зарегистрировать
такую строку через Автономные миссии → Возможности → Зарегистрировать.
Все три операции доступны только администратору и попадают в журнал аудита.

Диагностика

  • Плагин установлен, но ничего не появилось — он специально
    устанавливается выключенным; нажмите Включить. Если включён и всё равно не
    виден в неймспейсе — проверьте неймспейс-переключатель (Админ → Плагины →
    Включить здесь) и флаг default_off плагина.
  • healthy: false в статусе плагина — узел не смог применить вклад (чаще
    всего WASM-модуль собран под WASI вместо wasm-unknown, либо конфликт ключа
    с другим плагином). Причина — в логе сервера.
  • Список реестра пуст — это ожидаемо, пока не задан
    MOCKARTY_PLUGINS_REGISTRY_URL или не добавлен управляемый оператором источник.
    Если источник настроен, индекс может быть недоступен или не пройти валидацию. Ответ API во всех
    случаях содержит подсказку: адрес источника проверяется ещё при добавлении, а
    «дошли, но это не реестр» отдаётся как 400, а не 502.
  • Установка по ссылке падает с bundle_invalid — URL должен быть http(s)
    и доступен без обращения к приватным адресам; закрепите sha256, чтобы
    исключить повреждённую загрузку.