How Do You Charge for a Plugin When the Customer Owns the Server?

Selling features is easy in a cloud you control. It’s a puzzle when the customer runs the whole thing themselves. VBWD gates plugins by a signed license’s feature list — without breaking its clean-core rule.

Rewritten for redrobot.

Imagine you hand a customer the full source of your platform, the database it runs on, and the keys to the server it runs on. Now try to sell them an add-on. Not a support contract, not a hosted service — an actual capability inside the software they already control. What stops them from just switching it on?

That question sounds rhetorical, like the setup for “you can’t.” But it has a real answer, and the answer is more interesting than a padlock. VBWD is a self-hosted, source-available platform, and it sells capabilities the way a SaaS sells tiers — without a license server it controls at runtime, without a phone-home, without a black box. The mechanism is a signed list of words. Here is how a list of words decides what your deployment is allowed to run.

The awkward middle ground

Most licensing lives at one of two comfortable extremes. Pure SaaS keeps the binary on the vendor’s own machines, so entitlement is trivial: the server checks a database row and either serves you or doesn’t. Pure open source gives up on entitlement entirely — the code is yours, run what you like. VBWD sits in the awkward middle: the customer runs the software themselves, but the vendor still wants to bundle, tier, and resell what runs.

The core platform is Python/Flask on Postgres with a Vue 3 admin and user frontend, shipped in Docker. It is deliberately agnostic: it knows nothing about subscriptions, shops, booking, CMS, bots, or marketplace vendors. Every one of those is a plugin. The core never imports a plugin and never holds plugin vocabulary — an automated oracle fails the build the moment it does. So the licensing question becomes very specific: how does an agnostic core, which by design cannot know what “booking” means, decide that this deployment may run booking and not the marketplace tools?

A permission, not a file check

The first move is to stop treating “the plugin is on disk” as permission to run it. Two deployments can carry byte-identical images; what separates them is a signed token that names the features each is entitled to. Enablement becomes a permission grant rather than a file-presence check.

The token is a small signed document. Past the usual issuer, subject, and expiry, one field does the work:

{
  "sub": "acme-oem-deployment-4417",
  "iss": "vbwd-license-authority",
  "exp": "2027-01-01T00:00:00Z",
  "features": ["cms", "shop", "booking", "subscription"],
  "sig": "<ed25519 signature over the canonical payload>"
}

The signature is Ed25519, made with a private key the vendor holds. Every deployment carries the matching public key and verifies the token entirely offline. No network round-trip, no authority to reach at runtime — which is the whole point when the product’s promise is that the customer runs it on their own infrastructure, air-gapped if they like.

Where the check actually sits

The tempting-but-wrong place to enforce this is the admin UI: grey out the button, show an “upgrade” banner. A determined operator scrolls right past that. VBWD puts the check somewhere a scroll can’t reach — the enablement seam every plugin already passes through to mount its routes and register its services.

The flow, at startup and on every operator toggle, is short:

  1. The core reads the token and verifies the signature against the embedded public key. A tampered payload, a bad signature, or an expired token means the features list is not trusted.
  2. When a plugin asks to enable, the platform checks whether the feature that plugin declares is present in the verified list.
  3. If it is, the plugin enables normally — blueprint mounts, dependency-injection providers register, migrations are expected to have run. If it isn’t, enablement is refused at the seam.

The consequence is sharper than hiding a menu item. A plugin that isn’t entitled never gets its providers wired, so its capability isn’t concealed — it is never constructed. There is no live object to reach.

Why the core stays dumb on purpose

Here is the constraint that shapes everything. If the core held a table saying “the marketplace feature unlocks the vendor plugin, which belongs to the Pro bundle,” that is plugin vocabulary living in the core, and the agnosticism oracle would fail the build. It would also be the wrong home: bundling and pricing are business policy that churns far faster than a signature-verification routine.

So the responsibility splits cleanly:

  • The core owns the mechanism. It holds the offline public-key verifier, the idea of a trusted feature list, and the enforcement point at the enablement seam. Everything is generic: a feature is an opaque string, a plugin declares which string it needs, the core compares strings. Zero domain knowledge.
  • A plugin owns the policy. Which features map to which plugins, how features bundle into products, what a tier costs, how a partner’s token is issued — all domain-shaped, so all outside the core.

VBWD already uses this shape elsewhere. Its route-audit oracle is a core mechanism enforcing a declared policy — which routes may be publicly exposed — without the core deciding any route’s business meaning. Feature-gating is the same move: generic enforcement inside, specific policy declared from outside. Holding that line is exactly what keeps the agnosticism oracle green while the platform still sells capabilities. Paid plugins are simply plugins whose feature isn’t in a free deployment’s default token; the hub sets pricing and mints tokens, and the core only ever checks a signature and compares strings. The pricing tier and the technical entitlement turn out to be the same object.

What a token swap looks like

Picture an OEM partner, Acme, reselling VBWD to service businesses. A Standard customer holds features: ["cms", "shop", "subscription"]. The booking plugin can sit right there on disk — the image is identical to a Pro box — but when an operator tries to enable it, the core checks booking’s declared feature against the verified list, doesn’t find it, and refuses at the seam. When the customer upgrades, Acme reissues a token adding "booking" and "marketplace"; the operator drops it in, restarts the API, and both plugins now pass the check and run. No image rebuilt, no branch forked, no “lite” edition maintained. The only thing that changed is a signed list. Acme edits its bundle definition once, in the hub, and every future token reflects it — the mechanics of installing and rotating a token live in the operator documentation.

The honest part

None of this pretends to be DRM, and it shouldn’t, because the product is source-available under BSL 1.1 — not a black box, and never CC0. The customer has the source, and that has consequences no cryptography erases:

  • Signatures stop forgery, not deletion. Nobody without the private key can mint a token granting features you didn’t sell. But a signature does nothing to stop someone with the source from editing out the lines that read the token. Crypto solves forgery; it does not solve “delete these three lines.”
  • Entanglement raises the cost of deletion. The answer to that isn’t a stronger lock, it’s making the lock load-bearing. Rather than one boolean gate, real limits and enablement are derived from the token’s claims and threaded through the seams the plugin genuinely depends on. Ripping the check out then means untangling working behaviour, not deleting a guard clause — costly rather than impossible.
  • The license is the backstop. BSL 1.1 governs use. Its Additional Use Grant is generous — commercial use is free while annual VBWD-attributable sales stay under the value threshold in the license — but stripping entitlement checks to run unlicensed capabilities is a violation, and that is where enforcement finally rests. The technical measures make casual circumvention costly; the license makes it actionable.

This is a designed model, and parts of it are still being built — read it as architecture, not a shipped tamper-proof guarantee. That framing is deliberate and, I’d argue, the honest one: make forgery cryptographically impossible, make removal expensive through entanglement, and let the license carry the final weight, rather than pretending a binary running on someone else’s server can be made untouchable. A list of words, signed once and verified offline, turns out to be enough to sell a capability — as long as you’re honest about what the signature can and can’t promise.

Learn more about VBWD

VBWD is a self-hosted, source-available platform for building subscription products, marketplaces, and AI-powered apps. Explore it further:

VBWD is source-available — get the SDK on GitHub.

Happy
Happy
0%
Sad
Sad
0%
Excited
Excited
0%
Angry
Angry
0%
Surprise
Surprise
0%
Sleepy
Sleepy
0%

The License That Verifies Itself When Your Server Can’t Be Reached

Your Customer Has the Deed, the Alarm Code, and the Wiring Diagram: Licensing Code You Give Away

Leave a Reply

Your email address will not be published. Required fields are marked *

4 × 4 =