Skip to main content
Version: v5.7.0

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_status attribute of the GET /api/info singleton (served beside the legacy licence_info attribute, whose GUI contract is unchanged);
  • in the PUT /api/licence 201 response (beside the applied document) and the DELETE /api/licence/{licence_id} 200 response;
  • as the licence_status field of GET /api/admin/licence (and its original mount GET /admin/licence), wrapped in the usage report below;
  • over API v2 as LicenceService.GetLicenceStatus (field for field, same any-authenticated exposure; a resolution failure answers unavailable instead of embedding an error field). See opschain docs api-v2.

The v2 OpenAPI document declares this resource's schema; the resource-field coverage gate holds this page to it.

Fields​

FieldTypeMeaning
tierstringThe 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.)
statestringThe computed licence lifecycle state — vocabulary below. With no base document the evaluation footprint applies and state is valid (the footprint never expires).
limitsobjectThe effective countable limits: projects, environments, assets, runners, agents (ints; -1 = unlimited), and runner_groups (optional int — absent from a licence document means unlimited).
featuresstring arrayThe effective feature entitlements. Always present (serialized [] when empty). Fixed vocabulary: agents, assets, maintenance, templates, triggers, plus packs:<name> per signed commercial pack.
unknown_featuresstring arrayGranted 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_daysintThe effective expiry grace window in days — the winning base document's own grace_days (default 30). Grace is licence-carried, never a server setting.
grantsobject mapWhich 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).
registrationobjectThe 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_verificationarrayPresent 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.
documentsarrayEvery stored, verified, non-denylisted document's own report (below). Always present.
invalid_documentsintStored documents that failed signature re-verification this resolution — they contribute nothing. Absent when 0.
denied_documentsintStored documents revoked by the embedded denylist — they contribute nothing. Absent when 0.

documents entries​

FieldTypeMeaning
licence_idstringThe document's identity; applying a renewal with a new id accumulates beside its predecessor.
licenseestringWho the licence was issued to.
tierstringThe document's own tier: enterprise or pack.
issuedstringIssue date (plain date or RFC 3339). Absent when the document carries none.
expiresstringExpiry (plain date or RFC 3339; a date-only value ends validity at 00:00:00 UTC that day).
statestringThis 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​

FieldTypeMeaning
statestringunregistered — the evaluation footprint applies and no base document is stored.
messagestringThe 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, with state carrying 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:

FieldTypeMeaning
enforcementstringenforced, or not wired when the composition has no entitlement service (then licence_status and usage are absent).
store_kindstringThe 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_statusobjectThe payload above.
usageobject mapPer 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.
notesstring arrayNamed degradations (e.g. "node usage counts are unavailable: …") rather than silent omission. Absent when none.
  • opschain docs entitlements — enforcement gates, grace and the apply / remove lifecycle.
  • opschain docs fleet-queue — the licence expired dispatch verdict the expired state produces.