Skip to content

Plugins & extensions

Plugins add tasks, metadata providers, watch-state sync, endpoints, widgets, library sources, and notifications. For development, see Writing a plugin.

Drop-in: for plugins you wrote or audited yourself

Section titled “Drop-in: for plugins you wrote or audited yourself”

Copy the plugin directory into $PLUGINS_EXTERNAL_DIR:

$PLUGINS_EXTERNAL_DIR/
my-plugin/
index.js

Lumastra loads it at startup. Reload plugins under Settings → Plugins & features picks up newly added directories without a restart. Drop-ins have no signature or checksum verification, including on later loads.

Configure the publisher’s public key, then enter the manifest URL and detached signature under Settings → Plugins & features. The publisher supplies the signed manifest.json and plugin bundle.

Lumastra applies SSRF, size, and timeout guards, verifies the signature over the exact manifest bytes, and checks the bundle checksum. Every later load checks the installed files against their recorded digest; modified files refuse to load.

Add a JSON repository index under Settings → Plugins & features to browse and install plugins. Repository installs use the same signature, checksum, compatibility, publisher continuity, and anti-rollback checks as manual signed installs.

https://lumastra.org/plugins/index.json

Its reference plugins use the built-in key lumastra-official-2026 and need no additional key configuration. They demonstrate plugin contracts and are intended for adaptation. Compare your build’s key with the published signing keys; that document is informational and does not configure server trust.

Third-party repositories require the publisher’s key in PLUGIN_TRUSTED_KEYS before installation. A listing grants no trust or endorsement. Indexes are unsigned: they can misrepresent a plugin or suppress updates, but cannot bypass per-plugin signatures. Plugin details are verified against the signed manifest at install time, and the catalog only offers versions compatible with your server’s plugin ABI.

The Check for Plugin Updates task refreshes repositories every 12 hours and reports available updates without installing them. Sync now refreshes manually. Removing a repository leaves its installed plugins running.

A signature identifies a publisher and protects against forged updates. It does not prove that code is safe or reviewed. Signed plugins have the same server access as drop-ins.

The official key ships with Lumastra. Trust other publishers through the environment:

Terminal window
PLUGIN_TRUSTED_KEYS="alice-2026:MCowBQYDK2VwAyEA…"

Use a comma-separated list of keyId:base64Spki entries with Ed25519 keys. The key ID appears in the admin UI and audit log.

Removing a key blocks future installs signed by it. Already installed plugins keep loading because load-time checks verify file digests. To revoke a plugin, uninstall it and restart Lumastra.

What takes effect immediately, and what needs a restart

Section titled “What takes effect immediately, and what needs a restart”
ActionEffect
Install (new plugin)Loads immediately
Reload pluginsPicks up newly added directories
EnableLoads immediately
DisableNext restart
UninstallNext restart
Upgrade / downgradeNext restart

Lumastra cannot unload code from a running process. Removed or replaced plugins remain loaded until restart.

With multiple replicas, shared storage distributes files, but only the replica serving the install request loads the plugin immediately. Restart the other replicas to load it; their cards report loaded: false — restart required.

POST /api/plugin-webhooks/<plugin-id>

The endpoint returns 404 until the plugin declares the webhook capability and has a webhookSecret configured. Callers then authenticate with the X-Plugin-Webhook-Secret header, without a browser session. Use a long random secret unique to each plugin.

What a plugin declares, and what the host checks

Section titled “What a plugin declares, and what the host checks”

Signed manifests contain publisher, licence, source, and capability disclosures, including database access, outbound domains, and dashboard code. Catalogs and mirrors cannot alter these signed declarations.

A plugin registering capabilities beyond its declaration is refused and rolled back. This check runs after code has loaded: rollback removes files and registrations, but cannot undo code already executed.

An update signed by a different key is refused, even if both keys are trusted. For a verified publisher key rotation, explicitly accept it with force; the audit log records both key IDs.

Plugins must match Lumastra’s plugin ABI version to install or load. An ABI error after upgrading Lumastra requires a plugin rebuild by its author.

Auth plugins support credential or redirect-based login through an existing directory or identity service. Their endpoints are reachable before authentication, so all three gates default to empty:

VariableWhat it permits
AUTH_PLUGIN_PROVIDERSProvider IDs allowed to authenticate users
AUTH_PLUGIN_PROVISIONProviders allowed to create unknown accounts
AUTH_PLUGIN_ADMIN_ASSERTProviders whose asserted groups may confer admin
Terminal window
AUTH_PLUGIN_PROVIDERS=acme-ldap
AUTH_PLUGIN_PROVISION=acme-ldap # optional
# AUTH_PLUGIN_ADMIN_ASSERT= # leave empty unless intended

Until a provider is listed in AUTH_PLUGIN_PROVIDERS, its login endpoint returns 404 and its verification function is never called. Removing the ID blocks login immediately; the list is read per request.

Without AUTH_PLUGIN_PROVISION, an admin must link unknown accounts. Provisioning never creates an admin and requires an existing first admin. Without AUTH_PLUGIN_ADMIN_ASSERT, groups matching ADMIN_GROUPS are stripped from provider claims; ordinary group mapping still works.

Failed, malformed, or timed-out responses (over 10 seconds) reject login. Suspended accounts remain blocked regardless of the provider’s response.

For redirect providers, Lumastra enforces browser-bound, single-use state and keeps flow context server-side. Redirect URLs require HTTPS, except HTTP loopback for local IdPs. Login rate limits are 30 attempts per IP and 10 failures per account per 15 minutes; provider outages do not consume the per-account budget.

See Verifying a login for the contract.

Where plugins live, and how to not lose them

Section titled “Where plugins live, and how to not lose them”

If storage is lost, plugin cards name the missing directory. Reinstalling the same version repairs it and is not treated as a downgrade. Multiple replicas need shared, persistent storage and a restart on each replica to load changes.

VariableDefaultPurpose
PLUGINS_ENABLEDtrueSet false to load no external plugins
PLUGINS_EXTERNAL_DIR/app/pluginsInstalled plugin directories; requires a persistent volume
PLUGIN_TRUSTED_KEYS(unset)Ed25519 keyId:base64Spki list for non-official publishers
PLUGINS_EXTERNAL_INSTALL_ENABLEDtrueSet false to remove the remote-install endpoint
PLUGINS_REQUIRE_REGISTRYfalseLoad only signed, registry-managed external plugins
PLUGIN_INSTALL_ALLOW_PRIVATEfalseAllow private-IP manifest fetches; development only
AUTH_PLUGIN_PROVIDERS(empty)Auth providers allowed to log users in
AUTH_PLUGIN_PROVISION(empty)Auth providers allowed to create accounts
AUTH_PLUGIN_ADMIN_ASSERT(empty)Auth providers whose groups may confer admin

Install resource limits:

VariableDefault
PLUGIN_INSTALL_MAX_MANIFEST_BYTES64 KiB
PLUGIN_INSTALL_MAX_BUNDLE_BYTES8 MiB
PLUGIN_INSTALL_MAX_EXTRACTED_BYTES32 MiB
PLUGIN_INSTALL_MAX_FILE_BYTES8 MiB
PLUGIN_INSTALL_MAX_ENTRIES2048
PLUGIN_INSTALL_FETCH_TIMEOUT_MS15000

For signed installs, set:

Terminal window
PLUGINS_REQUIRE_REGISTRY=true

This prevents unverified drop-ins from loading alongside signed plugins. Bundled plugins are exempt because they ship inside the image; directories in your plugin volume are not.

Keep PLUGIN_INSTALL_ALLOW_PRIVATE=false in production. Public-IP pinning prevents manifest fetches from reaching private network services.

ProblemAction
No trusted signing keys configuredSet PLUGIN_TRUSTED_KEYS if your build has no official key
Checksum mismatch on diskReinstall the plugin
Built for SDK ABI NRequest a rebuild for your Lumastra version
Runtime-imported the types-only SDK packageRequest a fix from the plugin author
Listed but not loadedCheck the card for missing files or a required restart
Loaded but inactiveCheck required settings and any plugin-specific enable toggle