feat: real plugin system with loadable instances + OpenBao secrets (v1.17.0)

Generalize the half-built discovery plugins into a real plugin system: plugin
TYPES (the plugins/<category>/<type>.js modules with manifests) and loadable,
configurable, multi-copy plugin INSTANCES (PluginInstance ORM model) managed
from a dedicated /plugins page and /api/plugins API, with per-instance secrets
in OpenBao at secret/plugins/<id>/conf.

- plugin_registry.js: getTypes/getModule/splitConfig/mask + required-field helpers
- PluginInstance model (Sequelize): id/pluginType/category/name/slug(unique)/
  enabled/cron/config(json, non-secret)/lastRun*; registered in models/index.js
- plugin_secrets.js: read/write/remove/mergeForRun over @simpleworkjs/bao-conf
- scheduler.js: schedules from the DB registry; per-instance stable BullMQ
  JobScheduler ids (plugin:<id>) for load/unload; legacy migration from
  conf.discovery.plugins on first boot (idempotent, empty-table-guarded)
- api_plugins.js (replaces routes/plugins.js): types/list/get/create/update/
  secrets/test/load/unload/run/delete/runs; admin-gated; secrets always masked
- /plugins page (plugins.ejs) + nav; Agents & Scheduler tab removed from
  /directory; /docs/agents aliased to /docs/plugins
- proxmox/unifi/nmap gained manifests (configSchema/validate/run alias)
- tests/plugins.test.js: registry unit + plugin_secrets (mocked bao-conf) +
  PluginInstance model round-trip/unique-slug
- docs (plugins.md, vault.md, _config.yml, API.md) + 1.16.1 -> 1.17.0

Requires theta-suite >= v1.30.1 for the sso-broker secret/plugins/* grant;
fails-soft with a clear error if absent.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-08-01 20:33:57 -04:00
parent 21a56dce50
commit cec0d92c25
23 changed files with 1679 additions and 326 deletions
+3
View File
@@ -34,6 +34,9 @@ nav:
- title: Directory
page: /directory.html
icon: fa-server
- title: Plugins
page: /plugins.html
icon: fa-plug
# API.md lives at the repo root, not under docs/, so Jekyll never renders an
# api.html for it — link the source directly, same as the Changelog.
- title: API
+7 -1
View File
@@ -36,4 +36,10 @@ Currently, secrets are maintained at `/v1/secret/data/sso-manager/conf` using th
## Plugin Integration
When building custom Agents or integrations, they can utilize the local Vault to retrieve API tokens instead of hardcoding them. Always use the `/api/vault` proxy to ensure permissions are consistently enforced.
Plugin instances store their per-instance secrets in OpenBao at
`secret/plugins/<instance-id>/conf` (configured, loaded/unloaded, and run from
the **Plugins** page — see [Plugins](plugins.html)). The plugin process runs
in-process, so the SSO Manager reads/writes those secrets server-side through
the `sso-broker` token; the admin UI only ever sees masked values, and external
apps can retrieve API tokens via the `/api/vault` proxy to keep permissions
consistently enforced instead of hardcoding them.