Files
vantage/docs/superpowers/specs
mrhid6 b027ad3f7f docs: add licensing programme specs
Seven specs covering the licensing and billing programme:

- 0a shared-module: extract shared Go module, remove sitesvc duplication
- 0b instance-rename: Org -> Instance, including the database field
- 1  licensing-core: lk-signed licence payload, offline verify, CLI issuer
- 2  instance-licensing: storage, enforcement, degraded mode, settings UI
- 3  admin-backend: accounts, instances, licences, subscriptions, injection
- 4  admin-site: staff and customer portal
- 5  paddle-billing: catalog, checkout, webhooks, signup migration

Design only. No implementation.

Un-ignores docs/superpowers/ so specs are versioned.
2026-07-24 13:13:47 +01:00
..
2026-07-24 13:13:47 +01:00

Vantage Licensing Programme — Spec Index

Seven specs, designed 2026-07-24. Build in this order.

# Spec Ships alone Blocks
0a shared-module yes everything
0b instance-rename yes 1, 2, 3
1 licensing-core yes 2, 3
2 instance-licensing yes, with lkctl-issued licences
3 admin-backend no 4, 5
4 admin-site no
5 paddle-billing no

4 and 5 can run in parallel once 3 lands.

The shape

Account (admin only)
 ├── Instance 1  cloud        vantage.hostxtra.co.uk/<slug>   licence auto-injected
 ├── Instance 2  cloud                                        licence auto-injected
 └── Instance 3  self-hosted  customer's own deployment       licence pasted by hand

The control plane knows only Instance. Accounts exist solely in the admin service, because a self-hosted instance has no row in the cloud database at all.

Decisions that everything else follows from

Licences are offline-verified signed blobs. ed25519 via github.com/hyperboloide/lk, public key compiled into the server, no phone-home anywhere. This buys air-gapped self-hosting and means no Vantage instance ever depends on the licensing service being up. It costs revocation: a licence is valid until it expires whatever Paddle later says. Self Hosted is annual-only to bound that window.

Every licence is bound to one instance UUID. Self-hosted customers link their UUID before the licence is signed, so there is no unbound licence and no claim protocol.

Expiry degrades, it does not break. Monitors keep executing, alerts keep firing, agents keep their keys, in-flight workflow runs finish. Mutations stop. Deletes and OS-update application stay open so a customer is never trapped over-limit or unpatched.

Tiers are data, not code. The server reads Limits and Features and never branches on tier name. Tier contents live in the admin plans table and are snapshotted into each issued licence, so editing a plan never rewrites history — the same rule as workflow_runs.steps_snapshot.

Free Professional Self Hosted
deployment cloud only cloud self-hosted
max servers 3 unlimited unlimited
max secret groups 1 unlimited unlimited
max channels 1 unlimited unlimited
console no yes yes
OIDC no yes yes
term monthly, £0 monthly or annual annual only

Free is cloud-only by construction: it is only ever signed with deployment: "cloud", and verification rejects a deployment mismatch. There is no server-side flag to edit. One Free instance per account.

Existing cloud tenants are grandfathered to Professional, one year out, by migration 0005.