Skip to content
Get started

Licensing

Mildport licensing is offline. Your engine verifies each key locally against a public key you deploy with it, so imports keep working whether or not you can reach us — in an air-gap, during our maintenance, on a Sunday night.

The same license works everywhere. There is no separate “cloud key” and “self-hosted key”: one key, verified the same way in our cloud and in your VPC.

  1. You get a license key from the Licenses page of your Mildport account.
  2. Your engine holds the public key it verifies against — IMPORT_LICENSE_PUBLIC_KEY, shown on the Self-hosting page of the same account.
  3. Every request verifies locally. No network call, ever.

A key carries its tenant, plan, limits and expiry, so one deployment can serve many tenants with different entitlements — the engine reads all of it from the key itself.

Keys used against our managed cloud are deliberately short-lived (weeks, not years) and renew unattended: alongside your license key you receive a refresh secret (also shown exactly once). Your server calls the refresh endpoint with it on a cron — same plan, same origins, fresh key and expiry — and swaps the key into wherever you embed it. A leaked cloud key therefore dies on its own within days, without any revocation infrastructure and without verification ever phoning home.

Self-hosted and air-gapped deployments are exempt by design: their keys keep the long per-plan lifetime and never need to reach us — nothing in the engine knows the refresh endpoint exists. Regenerating a key manually also rotates the refresh secret.

Sign in to your account, open Licenses, and create a tenant. The key appears once, right after minting.

The key belongs in the embedding host, as the widget’s license-key attribute (see Configure). It is a bearer credential: treat it like an API key and keep it out of public repositories.

Keys are time-limited, and expiry is the only thing that ends a key’s life — there is no remote kill switch, because there is no remote anything.

  • We email you 30 days before a key expires, to the address that created it.
  • Renewing is one click: regenerate on the Licenses page. You get a fresh key, and the current one keeps working right up to its expiry date — so you can renew early and swap at your leisure, with no downtime in between.
  • After expiry, imports with that key stop. The fix is the same one click.

The panel shows a countdown on any license inside its last 30 days, so the state is visible without waiting for the email.

A key used by a browser embed can be pinned to the sites allowed to use it. Leave the list empty and the key works from anywhere; add origins and browser requests from anywhere else are refused. Server-side calls are unaffected — this protects embedded keys specifically, which are visible to anyone who views your page source.

Set the list when you create or regenerate a key. Wildcard subdomains are supported as https://*.example.com, and ports are significant.

Because verification is offline, a compromised key cannot be recalled remotely. Two levers:

  • Revocation list — add the license id to IMPORT_LICENSE_REVOKED_IDS on your engine (comma-separated). It takes effect on your next deploy and needs no new public key.
  • Regenerate — issue a fresh key from the panel and stop distributing the old one. It still works until it expires, which is why the revocation list exists for the urgent case.

The preflight tells you whether the engine can validate keys at all, before traffic arrives:

Terminal window
pnpm import:self-host-check

Running from an image rather than a source checkout? The same check is built in:

Terminal window
docker run --rm --env-file .env ghcr.io/capitality-io/mildport-aio \
bun dist/cli/self-host-check.js

On Kubernetes, helm test mildport runs it inside the cluster.

Next: Configuration reference · Image access