Licensing & activation
How nivq licensing works — activate a fresh deployment, bind to a host, and understand the licence lifecycle.
Every nivq deployment runs under a signed licence. Enforcement is unconditional: there is no flag to turn it off. With no licence, nivq boots into activation-pending — it starts and stays up, but only sign-in and the licence endpoints work until a valid licence is installed.
How it works
A licence is a signed token (a JSON Web Signature). Nivorbit signs it with a private key that never leaves a hardware security module, and the matching public key ships inside the nivq build to verify every licence offline — nivq never calls home. Once verified, the token is stored in nivq's own database, which is the durable source of truth: a deleted file or a recycled container can't cost you the licence.
Feature entitlement
The licence is the source of truth for which features a deployment may use — not
config, not the database. It carries an edition (e.g. enterprise) and an explicit
features set, both signed. On-prem, nivq resolves a workspace's effective features from
the licence and ignores the subscription-plan tables entirely, so a self-hosted
operator cannot unlock anything — e.g. self-learning, RBAC, or enterprise SSO — by editing
environment variables or rows in the database. An enterprise licence grants the full set;
any other edition grants the operational baseline plus exactly the features it lists.
No env unlock
There is intentionally no environment variable that grants features. Capabilities track the signed licence and nothing else; the upgrade path is a new licence from Nivorbit.
On-prem is a licensed box, not a metered subscription: the SaaS plan rules (query,
token, model, and schema metering) don't apply. The only quotas are the licence's
deployment-wide ceilings — total workspaces (maxWorkspaces), agents (maxAgents), and
user accounts (maxUsers) — enforced when you create each. A ceiling left at 0 means
unlimited.
Activate a fresh deployment
-
nivq boots activation-pending.
-
Read the host fingerprint and send it to Nivorbit:
Shell curl http://localhost:8080/v1/license/fingerprint # → NIVQ-FP-XXXXX-XXXXX-XXXXX-XXXXX -
Nivorbit issues a licence bound to that fingerprint and returns
license.jwt. -
Upload it — verified, stored, and activated without a restart:
Shell curl -F "[email protected]" http://localhost:8080/v1/license/upload
Those two calls — fingerprint and upload — are the only endpoints open before a licence exists, which is exactly what an installer needs during activation. Once you sign in, the licence banner in the app shows the current state at a glance (it reads the authenticated GET /v1/license/status endpoint behind the scenes).
Who can upload?
The first install is open (a brand-new deployment has no workspace owner yet). Once a licence is installed, replacing it requires a workspace OWNER. Only a Nivorbit-signed licence is ever accepted, so the open first-install window cannot be abused.
Seeding instead of uploading
For automated/declarative installs, mount the licence at nivq.licensing.license-file (default /etc/nivq/license.jwt, e.g. a Kubernetes Secret). The first boot reads it and stores it in the database; after that the file is no longer consulted.
The licence lifecycle
| State | When | Behaviour |
|---|---|---|
VALID | Before the warning window | Full access |
EXPIRING_SOON | Within the warning window before expiry | Full access + a renewal banner |
GRACE_PERIOD | After expiry, within the grace days | Read-only — writes are blocked |
LOCKED | After the grace period | Locked except sign-in and the licence endpoints, so you can install a renewal |
Rolling back to an older licence is rejected, and a detected clock rollback (tamper) is caught.
Binding a licence
A licence can be bound so it runs only on the deployment it was issued for. Binding is decided by Nivorbit when the licence is issued — there is no configuration flag to switch on or off. Two kinds, used alone or together:
-
Host binding. The licence is tied to your deployment's host fingerprint. Read it once and send it to Nivorbit when you request the licence:
Shell curl http://localhost:8080/v1/license/fingerprint # → NIVQ-FP-...On Kubernetes every replica resolves to the same fingerprint, so horizontal scaling, rolling updates, and rescheduling all keep the licence valid with no extra wiring.
-
Domain binding. The licence is tied to the domain your API is served on — the host of
BACKEND_URL, e.g.api.acme.com. Tell Nivorbit this domain when you request the licence and it will be issued for it. A wildcard like*.acme.comcovers every subdomain; if you reach the API by IP, send that instead.
A licence with neither (the default) is unbound and moves between machines freely.
Renewals and replacements
When a licence nears expiry, ask Nivorbit for a renewal and upload it the same way — no restart, no downtime. If you migrate to new hardware or a new API domain, send Nivorbit the new fingerprint or domain and you'll get a licence bound to it.