Pulp Engine Document Rendering
Get started

Plugin Trust Model

Audience: operators choosing whether to enable plugins, and plugin authors building against @pulp-engine/plugin-api.

Plugins are trusted server code

Pulp Engine plugins are loaded into the API process at startup via PULP_ENGINE_PLUGINS. They are not sandboxed. A plugin can:

  • Register storage backends, renderers, auth providers, routes, hooks, and events.
  • Read and write any data the API process can access (templates, assets, audit events, tenant records).
  • Make outbound network calls.
  • Read environment variables, the filesystem, and process memory.

Treat any enabled plugin as first-party server code — equivalent in trust to code you’d commit to this repository.

Operator posture

  • Source plugins from verified vendors. Pin to a specific package version (or a verified commit + checksum for file-path plugins). Avoid floating tags such as latest.
  • Audit before enabling. Read what the plugin registers and what permissions it implies. Pay attention to: storage backends (whole-database access), routes (new attack surface), auth providers (identity logic), and render hooks (run inside every render).
  • Default to disabled in production. Unless you authored or fully audited the plugin, leave PULP_ENGINE_PLUGINS unset. Production-ready features that started as plugins (e.g. @pulp-engine/barcode-renderer) graduate into the core build — there’s rarely a reason to ship a community plugin into a production deployment.
  • Multi-tenant deployments reject tenant-blind plugin storage. When MULTI_TENANT_ENABLED=true, registerStorageBackend() refuses to register plugin storage backends because the plugin-api 0.2.x storage contracts are tenant-blind and could cross tenant boundaries silently. Either disable multi-tenant mode or use a built-in storage backend (postgres, file, sqlserver). Tenant-aware plugin storage is planned for plugin-api 1.0 (Phase C.0b).
  • Reporting issues. Bugs in official packages under packages/ should be reported per SECURITY.md. Bugs in community or third-party plugins are the plugin maintainer’s responsibility — Pulp Engine cannot vet or backstop their security posture.

Why this is the right boundary

Plugins exist so operators can extend the core deliberately — adding a domain-specific renderer, an internal auth provider, a custom storage adapter — without forking the codebase. That extensibility is incompatible with strong sandboxing: the same hooks that let a barcode plugin register a renderer let a malicious plugin steal asset bytes or mint editor tokens.

The trust boundary is therefore drawn at PULP_ENGINE_PLUGINS: anything in that env var is in the trusted set; anything else is not. Operators control the env var.

If you want to evaluate a plugin without granting it production trust, run it in a non-production environment with synthetic data first.

Plugin author obligations

If you are publishing a plugin:

  • Document the runtime permissions it requires (network egress, filesystem paths, storage scope).
  • Pin the plugin-api major version your plugin targets in peerDependencies — Pulp Engine’s plugin-api contracts may change between minor versions during pre-1.0.
  • Surface failures via the structured logger; do not swallow errors silently.
  • Honour tenantId in any data-access surface (read and write) when plugin-api 1.0 lands tenant-aware contracts.

See also: