Licensing and entitlements#
A MAQPNA licence is a signed file that switches paid features on. It is verified offline against public keys built into the binaries: there is no licence server, no activation call and no phone-home. And it has one hard rule, stated in pkg/license and pkg/entitlement and guarded by the gateway test TestLicenseNeverBlocksToolCalls:
Without a licence an installation runs as the Community edition. See editions for what each edition includes.
The licence#
A licence is a compact JWS:
| Part | Value |
|---|---|
| Header | typ: maqpna-license+jwt, alg: EdDSA or ES256 |
iss |
https://maqpna.com (anything else is invalid) |
jti |
Licence ID |
sub |
Customer |
edition |
enterprise, sovereign or operator |
features |
Paid feature names, or * for all |
limits |
nodes, tenants, sandboxHours per month (0 = unlimited); reported, never enforced |
iat, nbf, exp |
Validity |
The trusted public keys (pkg/license/trusted.pem) are embedded at build time; there is no runtime override. A licence that only verifies with a key passed on the command line (maqpna license verify --pubkey) enables nothing in a real installation.
States#
stateDiagram-v2
[*] --> none: no licence file
none --> valid: licence installed, signature and issuer valid
none --> invalid: malformed, bad signature,<br/>wrong issuer, not yet valid
valid --> grace: exp passed
grace --> expired: 30 days after exp
grace --> valid: new licence installed
expired --> valid: new licence installed
invalid --> valid: valid licence installed
note right of grace
Features stay on in valid and grace.
Agent traffic is identical in every state.
end note
| State | Paid features | Agent traffic |
|---|---|---|
none (Community) |
Off | Unaffected |
invalid |
Off | Unaffected |
valid |
On, as listed in features |
Unaffected |
grace (up to 30 days after exp) |
On | Unaffected |
expired |
Off | Unaffected |
The flow#
sequenceDiagram
autonumber
participant V as Vendor or reseller
participant Ad as Platform team
participant K as Kubernetes Secret maqpna-license
participant GW as Gateway
participant Op as Operator
V->>Ad: licence file (JWS)
Ad->>Ad: maqpna license verify licence.jws
Ad->>K: maqpna license install licence.jws
K-->>GW: mounted optional, re-read every 30 s
K-->>Op: --license-file, re-read every 30 s
GW->>GW: pkg/license Evaluate, entitlement.Set
GW->>GW: GET /v1/license, posture check license,<br/>maqpna_license_* metrics
Note over GW: A paid admin feature asks entitlement.Required(f):<br/>disabled means HTTP 402, reason license_required.<br/>The /mcp, /llm and /a2a paths never ask.
- Issue. The vendor signs the licence:
maqpna license issue --key KEYURI --id ID --customer C --edition enterprise|sovereign|operator (--days N | --not-after RFC3339) [--feature F]... [--nodes N] [--tenants N] [--sandbox-hours N]. An Ed25519 key (a PKCS#8 file, or a registeredpkcs11:orkms:backend) signs EdDSA; an Azure Key Vault EC P-256 key (azurekv://VAULT/KEY[/VERSION]) signs ES256. - Verify before installing.
maqpna license verify FILEchecks the licence against the keys built into the CLI, and exits 3 when it is invalid or expired. - Install.
maqpna license install FILEcreates or updates the Secret the chart mounts (license.secretRef, defaultmaqpna-license, keylicense) in the install namespace. - Load. The gateway (
licenseFile) and the operator (--license-file) re-read the file every 30 seconds, so a new licence takes effect within about a minute (kubelet Secret sync plus the poll), without a restart. A missing file is the Community edition. - Entitle. Code that implements a paid feature asks
entitlement.Entitled(feature)(orRequired) at the edge of that feature: the admin or console handler, the controller that would create its objects, the report export. It re-evaluates the licence on every use, so expiry and a new licence take effect at once. A disabled feature answers HTTP 402 with reasonlicense_requiredon the admin API. - Report. The state is visible at
GET /v1/license, in the posture checklicense(maqpna doctor) and as metrics.
Entitlement features#
| Feature | Meaning |
|---|---|
fleet |
Multi-cluster and multi-tenant fleet view |
whitelabel |
White-label console |
evidence-packs |
Signed compliance evidence packs |
usage-reports |
Signed usage reports for billing |
sso-console |
Console single sign-on |
Node limit#
The licence's limits.nodes is compared with the billable node count the operator records (see usage metering). It is never enforced: the gateway and operator export maqpna_license_node_limit next to maqpna_billable_nodes, and the chart alert MaqpnaLicenseNodeLimitExceeded tells you when you need a larger licence. MaqpnaLicenseExpiring warns before exp (two thresholds, warning and critical).
What you see#
maqpna license status reads the installed Secret and evaluates it with the CLI's own keys (format from cmd/maqpna/license.go; values illustrative):
licence: valid (enterprise edition), customer ACME Bank AG, licence lic-2026-0042, expires 2027-10-01 (363 days left)
secret: maqpna-system/maqpna-license key license (installed)
features: sso-console, evidence-packs
entitled: evidence-packs, sso-console
billable nodes this month: 14 (licence limit 20)
Without a licence, the entitled line reads none (paid features off; agent traffic is never affected) and the limit reads none: Community. maqpna license verify prints state, id, customer, edition, features, limits, valid and signed by lines and verified with <keys>. Both exit 3 when the licence is invalid or expired. See maqpna license and maqpna doctor.
Failure modes#
| Failure | Effect |
|---|---|
| Secret missing or unreadable | Community edition; traffic unaffected |
| Licence for another build's keys | invalid; traffic unaffected; maqpna license install warns that paid features stay off |
| Licence expired more than 30 days | expired, features off; traffic unaffected |