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:
- 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
featureslist is not trusted. - When a plugin asks to enable, the platform checks whether the feature that plugin declares is present in the verified list.
- 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:
- 🌐 Website and documentation: vbwd.cc — see the plugins, architecture, and developer docs.
- 💻 Source code and plugins on GitHub: github.com/VBWD-platform
- 🎥 Watch VBWD in action: demo video 1 and demo video 2
- 💼 Follow the project on LinkedIn: linkedin.com/company/vbwd
VBWD is source-available — get the SDK on GitHub.