Skip to content

Host API (WASM)

Host API — набор функций, доступных WASM-плагинам для взаимодействия с платформой. Все вызовы проходят через единый конвейер: проверка разрешений, rate limiting, трассировка, автоочистка ресурсов.

На текущем этапе host layer уже умеет:

  • применять requirement-driven HTTP policy
  • выполнять typed inter-plugin RPC через отдельный handle_rpc
  • публиковать события в in-memory или Postgres event bus backend

Диаграмма классов

Все host-функции

Чтение файлов: текущий и legacy ABI

Для новых сборок плагинов чтение чанков идёт через file_read_into:

  1. Плагин выделяет буфер в своей WASM memory.
  2. Передаёт file_id, offset, dst_ptr, dst_len.
  3. Host читает чанк из FileStore и пишет его прямо в guest memory.
  4. Обратно возвращается только небольшой ответ {bytes_read, eof}.

file_read оставлен как deprecated compatibility path для ранее собранных плагинов. Публичные методы SDK ctx.FileRead(...) и ctx.FileReadAll(...) остаются штатным API и не помечены как устаревшие.

Конвейер вызова

Каждый host-вызов проходит через единый wrapper в registerFunc:

Система разрешений

Разрешения назначаются плагину при установке на основе requirements из манифеста.

RequirementPermissionЧто даёт
databasesqlДоступ к sql_* функциям
httpnetworkДоступ к http_request
kvkvДоступ к kv_* функциям
notifynotifyДоступ к notify_* функциям
eventseventsДоступ к publish_event
filefileДоступ к file_* функциям
plugin:Xplugins:call:XВызов конкретного плагина X

Проверка — перед каждым вызовом. Без разрешения вызов возвращает ошибку, WASM-модуль не получает доступа к ресурсу.

Для http requirement поверх базового permission может применяться policy:

  • allowlist хостов
  • allowlist HTTP-методов
  • лимит request body
  • лимит response body

Rate Limits

Лимиты на одно выполнение (один HandleEvent):

ФункцияЛимитФункцияЛимит
kv_get200sql_open10
kv_set200sql_exec100
kv_delete100sql_query100
kv_list50sql_next5000
http_request20sql_begin20
call_plugin10sql_end20
publish_event50sql_close10

RateLimiter создаётся через context hook на каждое выполнение и сбрасывается после.

Сетевая песочница

http_request блокирует обращения к:

ЗаблокированоПричина
localhost, 127.0.0.1, ::1Loopback
10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16RFC 1918 (приватные сети)
169.254.0.0/16Link-local
169.254.169.254, metadata.google.internalCloud metadata API (SSRF)

HTTP policy enforcement

Когда включён wasm.http_policy_enabled, http_request дополнительно читает resolved policy из plugin config и блокирует вызов до выхода в сеть, если:

  • хост не входит в allowlist
  • HTTP-метод не разрешён
  • request body превышает лимит
  • response body превышает лимит

Политики резолвятся по ключу pluginID -> requirement name -> HTTPPolicy.

Inter-plugin RPC

call_plugin сейчас работает как typed RPC path:

  1. Проверка plugins:call:<target>.
  2. Проверка cycle/depth guard.
  3. Lookup target plugin через PluginRegistry.
  4. Проверка, что метод опубликован в RPCMethods.
  5. Выполнение handle_rpc в целевом плагине.

Это отделяет RPC от обычного handle_event и делает контракт явным.

SQL: управление ресурсами

  • Макс. хэндлов на выполнение: 16 (connections + transactions + result sets)
  • Таймаут SQL-операций: 4 секунды
  • CleanupExecution вызывается через context.AfterFunc — автоочистка при завершении

Лимиты KV Store

ПараметрЛимит
Макс. ключей на плагин1 000
Макс. размер значения64 KB
Макс. объём на плагин10 MB
TTLопционально, per key

RPC sequence

Защиты:

  • Max call depth: 5 уровней вложенности
  • Cycle detection: A → B → A блокируется
  • Permission: нужен plugins:call:{target} для каждого целевого плагина

Wire Protocol

Все host-функции используют единый формат сериализации:

┌────────┬──────────────────────────┐
│ 0x01   │  MessagePack payload     │
│ 1 byte │  variable length         │
└────────┴──────────────────────────┘

Параметры передаются через WASM memory:

  • Вызов: (offset: i32, length: i32) → host читает из памяти WASM
  • Возврат: i64 = (offset << 32) | length → host пишет в память WASM через alloc

Трассировка

Каждое выполнение получает traceID (16 случайных hex-байт). Все host-вызовы логируются с:

trace_id, plugin_id, function, duration_ms, status (ok | error | rate_limited)

Пример из логов:

level=INFO msg="host api call" trace_id=789a8b69 plugin_id=schedule function=sql_query duration_ms=3 status=ok