Licence status
Included from Basic tier
licence_status is the resolved-entitlements payload: the effective tier,
expiry state, limits and features computed by re-verifying every stored
licence envelope against the embedded keyring and denylist, plus each stored
document's own state. One serializer (SerializeLicenceStatus) renders it
everywhere it appears:
- as the
licence_statusattribute of theGET /api/infosingleton (served beside the legacylicence_infoattribute, whose GUI contract is unchanged); - in the
PUT /api/licence201 response (beside the applied document) and theDELETE /api/licence/{licence_id}200 response; - as the
licence_statusfield ofGET /api/admin/licence(and its original mountGET /admin/licence), wrapped in the usage report below; - over API v2 as
LicenceService.GetLicenceStatus(field for field, same any-authenticated exposure; a resolution failure answersunavailableinstead of embedding an error field). Seeopschain docs api-v2.
The v2 OpenAPI document declares this resource's schema; the resource-field coverage gate holds this page to it.
Fields
| Field | Type | Meaning |
|---|---|---|
tier | string | The effective tier: basic (the embedded evaluation footprint with no base document stored, or a registered Basic document) or enterprise. (pack exists only as a per-document tier, never as the resolution tier.) |
state | string | The computed licence lifecycle state — vocabulary below. With no base document the evaluation footprint applies and state is valid (the footprint never expires). |
limits | object | The effective countable limits: projects, environments, assets, runners, agents (ints; -1 = unlimited), and runner_groups (optional int — absent from a licence document means unlimited). |
features | string array | The effective feature entitlements. Always present (serialized [] when empty). Fixed vocabulary: agents, assets, maintenance, templates, triggers, plus packs:<name> per signed commercial pack. |
unknown_features | string array | Granted names outside this build's vocabulary — inert, never a verification failure (issued licences may carry names a build does not gate). Absent when none. |
grace_days | int | The effective expiry grace window in days — the winning base document's own grace_days (default 30). Grace is licence-carried, never a server setting. |
grants | object map | Which source grants each effective feature: licence ids, the literal evaluation for the embedded footprint's own features (present only while no base document contributes), and baseline for the features every resolution carries (packs:common, identity:builtin; packs:academy on every licensed resolution). Over v2 the same map is the grants list of LicenceFeatureGrant rows (feature, sources). |
registration | object | The persistent registration notice, present only while no base document is stored (the server runs on the unregistered evaluation footprint): state is unregistered and message is the sentence the admin banner and opschain admin licence show print, naming the footprint's numbers and opschain admin licence register as the way to the Basic limits. Absent on every registered or licensed server. Over v2 this is the LicenceRegistration message. |
online_verification | array | Present when the server composes the online-licence manager: one row per stored enforcement: online installation — installation_id, licence_id, service_url, verify_interval, last_attempt, last_verified, last_outcome (ok, current, revoked, error, no_credential), last_error, failures, next_check. |
documents | array | Every stored, verified, non-denylisted document's own report (below). Always present. |
invalid_documents | int | Stored documents that failed signature re-verification this resolution — they contribute nothing. Absent when 0. |
denied_documents | int | Stored documents revoked by the embedded denylist — they contribute nothing. Absent when 0. |
documents entries
| Field | Type | Meaning |
|---|---|---|
licence_id | string | The document's identity; applying a renewal with a new id accumulates beside its predecessor. |
licensee | string | Who the licence was issued to. |
tier | string | The document's own tier: enterprise or pack. |
issued | string | Issue date (plain date or RFC 3339). Absent when the document carries none. |
expires | string | Expiry (plain date or RFC 3339; a date-only value ends validity at 00:00:00 UTC that day). |
state | string | This document's own computed expiry state (same vocabulary as the top-level state), or the reporting-only state revoked (denylisted) — such a document contributes nothing whatever the dates say. |
registration
| Field | Type | Meaning |
|---|---|---|
state | string | unregistered — the evaluation footprint applies and no base document is stored. |
message | string | The notice sentence: the footprint's numbers and the remedy, register for the Basic tier (opschain admin licence register), or apply a licence. |
state vocabulary
Verbatim from the code (pkg/licence/resolve.go): valid, in_grace,
expired; per document additionally revoked.
valid— before expiry.in_grace— past expiry, within the document's grace window.expired— past grace. This is the work-stop state: the server refuses starting new work (CheckWork) and the runner offer gate parks dispatch (WorkStopped), while reads and licence uploads always pass. Expiry never reverts entitlements — an expired enterprise licence keeps its limits and features, withstatecarrying the stop signal; only explicitly removing the last base document reverts to the evaluation footprint.
When several enterprise documents are stored, the one expiring last decides
the resolution's state; pack documents layer their features beside the base
while valid or in_grace and stop contributing once expired.
Where the values come from and what changes them
Resolution re-verifies every stored envelope on each read (never a stored
validity flag), with a 15-second cache that additionally expires at the next
expiry-state boundary so a state change is observed on time. PUT /api/licence (a verified Ed25519 envelope — opschain admin licence apply, or the document opschain admin licence register obtains) and
DELETE /api/licence/{licence_id} change the stored set and invalidate the
cache; the clock changes state on its own. Registering replaces the
footprint with the Basic document's limits and features and drops the
registration notice at the next read. The installation's phone-home
credential opschain admin licence register obtains is stored on the
server: held encrypted at rest in the database on a database store (the
StoreLicenceCredential answer then carries no credential_ref), else in
the server's secret vault under licence/<installation_id>/credential.
Each verification round reads the at-rest credential first, then
OPSCHAIN_LICENCE_CREDENTIAL, then the vault reference; none means
no_credential in online_verification.
Failure shapes: a resolution error on GET /api/info renders the attribute
as {"state": "unknown", "error": "..."}; a serialization failure renders
{"error":"licence status unavailable"}. Compositions without the
entitlement service omit the attribute entirely (the legacy shape).
The admin wrapper (GET /api/admin/licence)
The admin licence usage report embeds licence_status with:
| Field | Type | Meaning |
|---|---|---|
enforcement | string | enforced, or not wired when the composition has no entitlement service (then licence_status and usage are absent). |
store_kind | string | The server's data store: postgres or sqlite — the support bundle's licence.json carries it, so support sees at once which store the server runs on. |
licence_status | object | The payload above. |
usage | object map | Per countable limit — keys projects, environments, assets, agents, runners, runner_groups — each {"used": <int>, "limit": <int>}, counted by the same rules as the create gates (live non-deleted nodes per kind; registered unrevoked fleet members per kind; distinct runner groups). A key is absent when its count failed. |
notes | string array | Named degradations (e.g. "node usage counts are unavailable: …") rather than silent omission. Absent when none. |
Related pages
opschain docs entitlements— enforcement gates, grace and the apply / remove lifecycle.opschain docs fleet-queue— thelicence expireddispatch verdict theexpiredstate produces.