extensibility
plugin engine
HalcoPay ships a first-class plugin engine: ed25519-signed .mvgateway packages that drop into modules/, capability enforcement at install time, a runtime audit hook, and optional subprocess isolation. the engine is in production. a public marketplace catalog is on the roadmap — see below.
ready today — the engine
everything in this group is written, tested, and shipping in the current release. you can build, sign, install, and run plugins today using the cli in scripts/.
1. what a plugin can do
plugins declare a capability set in their manifest. the loader enforces it at install time (ast analysis) and at runtime (audit hook). capabilities include:
- network — outbound http or sockets
- subprocess — spawn child processes
- filesystem-write — write outside the plugin's sandbox dir
- eval — exec/eval/compile/__import__
- database — direct sqlalchemy session access
- coin-sdk — call into the cryptocurrency rpc layer
plugins without a capability cannot use it, even if the underlying python module is importable.
2. what plugins are useful for
operators we've worked with so far have used the engine for things like:
- checkout customization — branded templates, custom payment options
- compliance hooks — aml screening before invoice settlement, tax-receipt generation, jurisdiction-aware rate limits
- integrations — push events into your erp, accounting, crm
- industry-specific logic — vendor payout automation for marketplaces, kyc gates for igaming, donation-receipt emails for charity
- alternative payment rails — on-ramp providers, lightning network apis
none of these are bundled — they're examples of what the engine supports. shipped first-party plugins land on the roadmap below.
3. signing & trust
plugins are signed with ed25519. the loader verifies the signature against your operator-managed trust store before installation. trust-store mutations are recorded in a transparency log at <DATADIR>/trust/transparency.jsonl.
publishers can rotate keys with overlap windows (per-publisher rotation, sprint 15) and cross-sign new keys (sprint 20). expired keys stop verifying new installs but don't break existing ones.
installer modes (MVGATEWAY_PLUGIN_SIGNATURE_MODE):
- optional — verify if signed, warn if not (default in dev)
- required — refuse unsigned plugins (recommended for prod)
4. isolation modes
plugins run in one of two modes (MVGATEWAY_PLUGIN_ISOLATION_MODE):
- inline — in-process, audit-hook enforced. fastest, default.
- subprocess — each plugin host is its own process with rlimit cpu/memory/fd caps, json-rpc ipc, per-call timeout. opt-in via sprint 21 work.
subprocess mode is slightly slower but gives you os-level isolation — the right choice for plugins you don't fully trust.
5. building & shipping a plugin
a plugin is just a folder with:
- manifest.json — name, version, capabilities, hooks, settings schema
- your python code, with each hook registered via the plugin sdk
- optional templates/, static/, and migrations/ directories
zip the folder, sign it with scripts/sign_plugin.py, you have a .mvgateway. install via the admin ui or the /plugins api endpoint.
coming next — the marketplace
the engine is ready. what's being built on top of it:
- public marketplace catalog — a browseable directory of signed plugins, by category, with reviews and version history
- first-party plugin bundles — payout exports, observability adapters (sentry, slack, pagerduty), e-commerce bridges (woocommerce, shopify), on-ramp connectors (transak, moonpay). these will ship as separate signed releases, not as part of the core repo
- external publisher onboarding — a way for third-party authors to get their key into the default trust store after review
no firm ship date yet — the engine landed in sprints 9–21, marketplace work is sprint 22+. if you want to be early on the catalog (publisher or operator), tell us.