stella entitlement and stella installation — Command Guide

Audience: administrators of an Installation that holds, or is about to order, a vendor entitlement record. Scope: reading the Installation identifier, authenticating an entitlement record offline, importing it into the Installation, and reading the advisory capacity status.

Checked against src/Cli/StellaOps.Cli/Commands/EntitlementCommandGroup.cs, src/Cli/StellaOps.Cli/Commands/EntitlementAdministrationCommands.cs and src/Cli/StellaOps.Cli/Commands/InstallationCommandGroup.cs on 2026-10-29 (SPRINT_20261027_005 VTR-4 and VTR-5); the import and show output below is from a local Installation on 2026-10-29, with TEST records signed by a throwaway TEST key. The placement lines of the show sample follow the current output wording (SPRINT_20261027_003 PLC-5 and PLC-12, 2026-10-29) rather than that capture. Re-run the command tests with pwsh ./tools/scripts/test-targeted-xunit.ps1 -Project src/Cli/__Tests/StellaOps.Cli.Tests/StellaOps.Cli.Tests.csproj -Class '*Entitlement*' -BuildProjectReferences.

An entitlement record is licence administration (purpose = licence-administration). It records the placement capacity and the term that an order grants to the licensee for its own Installation (record contract). It is advisory: the product never blocks or stops a workload because of it. It is not issued for third parties, and it is not a statement that anything was checked or meets a regulation.

stella installation id

Prints the identifier of this Installation. The vendor names this identifier in the entitlement record, so send it through the order channel when you order capacity.

stella installation id [--json]
OptionDescription
--jsonPrint the full identity record as JSON: installationId, createdAt, signingRoots (thumbprint, keyCount) and federationSiteId.

The command reads GET /api/v1/platform/installation from the Platform service. It needs a configured backend (STELLAOPS_BACKEND_URL or the CLI configuration) and a token with the platform.setup.read scope, which the stellaops-cli client is granted.

Against a running Installation, signed in through the stellaops-cli client:

$ stella installation id
d96a1132-51b6-46f6-a7d2-9f8673c31dfe

$ stella installation id --json
{
  "installationId": "d96a1132-51b6-46f6-a7d2-9f8673c31dfe",
  "createdAt": "2026-10-28T14:02:03.868205+00:00",
  "signingRoots": {
    "thumbprint": null,
    "keyCount": 0
  },
  "federationSiteId": null
}

Without a configured backend:

$ stella installation id
Installation identity unavailable: Backend URL is not configured. Provide STELLAOPS_BACKEND_URL or configure appsettings.
Exit codeMeaning
0The identifier was printed.
8The identity could not be read: no backend, a refused request, or an empty response.

stella entitlement verify

Authenticates an entitlement record offline against the pinned vendor roots and prints what the record states. It makes no network call.

stella entitlement verify <file> --installation-id <id> [--json]
Argument or optionDescription
<file>The entitlement record (.dsse.json) that the vendor delivered.
--installation-idRequired. The identifier of this Installation (stella installation id). The record must name it.
--jsonPrint the result as JSON.

Vendor roots

The command uses the active roots of purpose vendor-entitlement in the pinned vendor trust-root set. It reads the set from the directory named by STELLAOPS_VENDOR_TRUST_ROOTS, or from trust/vendor-roots/ beside the stella binary. A root delivered with the record is never used. Until a release ships the vendor’s entitlement root, the shipped set has none, and the command refuses with vendor_roots_missing:vendor-entitlement.

What the command checks

The command reads the DSSE envelope, its payload type and the canonical payload, checks the payload against the record contract, requires that the issuer key is an active vendor-entitlement root, checks the signature, and requires that the record names the Installation given by --installation-id. It reports where the current time falls in the recorded term: current, not yet started or ended. A record whose term has ended is still authenticated; the term is reported, not enforced. The revision history of a serial is checked when the record is imported into the Installation, not by this command.

Example output

Run against a TEST record issued with a throwaway TEST key; directory paths are shortened to <dir>.

$ stella entitlement verify TEST-SOE-0003-r1.dsse.json --installation-id 00000000-0000-4000-8000-000000000002
Entitlement record
==================

File: <dir>\TEST-SOE-0003-r1.dsse.json
Result: licence record authenticated (term not yet started)
Authenticated against: pinned vendor set <dir>\vendor-roots (vendor-entitlement), key sha256:69ddfcbe727aad023154d62aadc5b12bb5b05f50419357c7ca70e1fcd6e84389
Serial: TEST-SOE-0003, revision 1
Purpose: licence-administration
Installation: 00000000-0000-4000-8000-000000000002
Recorded capacity: 40 managed placements
Permitted use: internal-production
Recorded term: 2026-11-01T00:00:00Z until 2027-11-01T00:00:00Z
Order reference: TEST-ORD-DOCS-0001
Issued at: 2026-10-29T00:03:05Z
Payload SHA-256: sha256:df16dc328fbdc0cb8932e9336935adbb0db7f9595df464baca273ca73cc5937c

This entitlement record establishes:
  - that the vendor key sha256:69ddfcbe727aad023154d62aadc5b12bb5b05f50419357c7ca70e1fcd6e84389 signed this payload;
  - that order TEST-ORD-DOCS-0001 records a capacity of up to 40 active placements in Installation 00000000-0000-4000-8000-000000000002, within the licence scope internal-production, for the term from 2026-11-01T00:00:00Z until 2027-11-01T00:00:00Z;
  - that this is revision 1 of subscription TEST-SOE-0003.

It does not establish:
  - that any placement was actually deployed, gated, promoted or scanned, or how many;
  - that scans ran correctly, that every workload was inspected, or that any finding, policy decision or evidence package is correct or complete;
  - the security posture of anything the Installation manages, or compliance with any regulation;
  - that an Installation without an entitlement record, or with an ended one, is unlicensed: the free allowance and the other permissions of the LICENSE apply independently.

Entitlement status is advisory: nothing is blocked or stopped by it. Revision history is checked when the record is imported.

With --json, the same record:

{
  "file": "<dir>\\TEST-SOE-0003-r1.dsse.json",
  "authenticated": true,
  "refusal": null,
  "reason": null,
  "period": "not yet started",
  "authenticatedKeyId": "sha256:69ddfcbe727aad023154d62aadc5b12bb5b05f50419357c7ca70e1fcd6e84389",
  "vendorRoots": "<dir>\\vendor-roots",
  "payloadSha256": "sha256:df16dc328fbdc0cb8932e9336935adbb0db7f9595df464baca273ca73cc5937c",
  "record": {
    "purpose": "licence-administration",
    "serial": "TEST-SOE-0003",
    "revision": 1,
    "issuerKeyId": "sha256:69ddfcbe727aad023154d62aadc5b12bb5b05f50419357c7ca70e1fcd6e84389",
    "installationId": "00000000-0000-4000-8000-000000000002",
    "authorisedPlacements": 40,
    "permittedUse": "internal-production",
    "orderReference": "TEST-ORD-DOCS-0001",
    "validFrom": "2026-11-01T00:00:00Z",
    "validTo": "2027-11-01T00:00:00Z",
    "issuedAt": "2026-10-29T00:03:05Z"
  },
  "notEstablished": [
    "that any placement was actually deployed, gated, promoted or scanned, or how many;",
    "that scans ran correctly, that every workload was inspected, or that any finding, policy decision or evidence package is correct or complete;",
    "the security posture of anything the Installation manages, or compliance with any regulation;",
    "that an Installation without an entitlement record, or with an ended one, is unlicensed: the free allowance and the other permissions of the LICENSE apply independently."
  ],
  "advisory": true
}

The same record checked against another Installation, and with no usable pinned set:

$ stella entitlement verify TEST-SOE-0003-r1.dsse.json --installation-id 00000000-0000-4000-8000-000000000003
Entitlement record not authenticated.
  - wrong_installation: the entitlement record names another installation

$ stella entitlement verify TEST-SOE-0003-r1.dsse.json --installation-id 00000000-0000-4000-8000-000000000002
Entitlement record not authenticated: the pinned vendor root set is not usable:
  - vendor_roots_missing:vendor-entitlement
Set STELLAOPS_VENDOR_TRUST_ROOTS to the vendor trust-root set, or install one at <dir>\empty-roots.

Refusal codes

A refusal names one code on stderr, and in the JSON refusal field. The Platform import uses the same codes.

CodeMeaning
malformed_envelopeThe file is not a DSSE envelope, or it is empty or larger than the contract allows.
unsupported_payload_typeThe envelope does not carry an entitlement record.
missing_signatureThe envelope has no signature.
non_canonical_payloadThe payload is not in RFC 8785 canonical form.
schema_violationThe payload is not JSON, or it does not match the record contract.
unknown_keyNo active vendor-entitlement root has the key that the payload names in issuerKeyId.
issuer_key_mismatchNo signature carries the payload’s issuerKeyId.
signature_invalidThe signature does not match the payload, for example after an edit.
wrong_installationThe record names another Installation.
revision_rollbackImport only: the Installation already holds a higher revision of the serial, or this revision with another payload.
no_trust_rootsThe pinned set has no active vendor-entitlement root.

When the pinned set itself is unusable, the command lists the set’s issues instead (for example vendor_roots_missing:vendor-entitlement).

Exit codeMeaning
0The record is authenticated.
2A required option is missing.
5The record is not authenticated, or the pinned set is not usable.
7The file does not exist.

stella entitlement import

Imports an entitlement record into this Installation through the Platform service (POST /api/v1/platform/entitlements). The Platform authenticates the record against its own pinned vendor roots, keeps the revision history of each serial, and records the import in its audit log. The CLI sends the file unchanged and never touches the database.

stella entitlement import <file> [--json]
Argument or optionDescription
<file>The entitlement record (.dsse.json) that the vendor delivered; at most 64 KiB.
--jsonPrint the result as JSON: file, imported, created, refusal, reason, payloadSha256, record, advisory.

The request needs the platform.entitlements.admin scope and a signed-in global administrator of the Installation (a user-delegated login, not a service client). Sign in first, for example with stella auth login --provider standard where Authority has several identity providers (stella auth).

$ stella entitlement import TEST-SOE-LIVE-ENDED-r1.dsse.json
Entitlement record imported.
Serial: TEST-SOE-LIVE-ENDED, revision 1 (current)
  Recorded capacity: 40 managed placements
  Recorded term: 2025-10-01T00:00:00Z until 2026-10-01T00:00:00Z (ended)
  Order reference: TEST-ORD-LIVE-0001
  Imported: 2026-10-29T02:38:39Z by a0000003000000000000000000000001
  Payload SHA-256: sha256:ff32afd5555c610b1d5a5491079edc6c1de2f935b7bc34c3ab71c8aea35702b4

Entitlement status is advisory: nothing is blocked or stopped by it.

$ stella entitlement import TEST-SOE-LIVE-TERM-r1.dsse.json
Entitlement record already imported: this revision is already held, nothing changed.
Serial: TEST-SOE-LIVE-TERM, revision 1 (current)
  Recorded capacity: 40 managed placements
  Recorded term: 2026-10-01T00:00:00Z until 2027-10-01T00:00:00Z (current)
  Order reference: TEST-ORD-LIVE-0002
  Imported: 2026-10-29T02:38:41Z by a0000003000000000000000000000001
  Payload SHA-256: sha256:9a35df2347e2da56cdac97a6ea2622e41b075448cd9348e85939bbd66e164a66

Entitlement status is advisory: nothing is blocked or stopped by it.

$ stella entitlement import TEST-SOE-LIVE-OTHER-r1.dsse.json
Entitlement record not imported.
  - wrong_installation: the entitlement record names another installation

Imported: ... by names the subject of the signed-in user.

Exit codeMeaning
0The record is imported, or this revision was already held.
5The Platform refused the record, or the file is larger than 64 KiB.
7The file does not exist.
8The request failed: no backend, no permission, or the Platform could not be reached.

stella entitlement show

Prints the advisory capacity status of the Installation and the imported entitlement records (GET /api/v1/platform/usage/placements and GET /api/v1/platform/entitlements).

stella entitlement show [--json]
OptionDescription
--jsonPrint usage (the capacity status), usageUnavailable, records and advisory as JSON.

Both requests need the platform.setup.read scope and a signed-in global administrator of the Installation. The status is the first that holds, in this order:

StatusMeaning
overThe managed-placement count is above the effective capacity.
expiredNo record is in its term and the latest one has ended; the count is within the free allowance.
expiringA record in its term ends within the renewal notice period; the count is within capacity.
withinA record is in its term and the count is within capacity.
noneNo record is in its term and none has ended (for example, none is imported), and the count is within the free allowance.

The effective capacity is the recorded capacity of the records in their term, and never less than the free allowance. The placement count is the Release Orchestrator total: the recorded and the declared placements, a pair in both counted once; when declarations add placements, the line says how many (Managed placements: 9 (7 recorded, 2 declared only)). The output also says when the count is not the definitive licence total and which signals it does not count (stella estate placements shows the placements themselves). The status reflects only the records imported into this Installation; it neither extends nor denies contractual rights, and nothing is blocked by it.

After importing an ended, a current and an expiring record into an Installation that manages five placements:

$ stella entitlement show
Entitlement records
===================

Capacity status: expiring (advisory, evaluated 2026-10-29T02:39:07Z)
Managed placements: 5
  The count is not the definitive licence total.
  Not counted: agent-observed-container, gate-or-promotion, node-change
    gate-or-promotion keeps an already recorded placement active but creates none; declare a workload that is only gated or promoted.
Recorded capacity: 50 managed placements, free allowance 20, effective capacity 50
Recorded term ends: 2026-11-15T00:00:00Z (renewal notice 30 days)

Records:
- TEST-SOE-LIVE-ENDED revision 1 (current)
    Recorded capacity: 40 managed placements
    Recorded term: 2025-10-01T00:00:00Z until 2026-10-01T00:00:00Z (ended)
    Order reference: TEST-ORD-LIVE-0001
    Imported: 2026-10-29T02:38:39Z by a0000003000000000000000000000001
    Payload SHA-256: sha256:ff32afd5555c610b1d5a5491079edc6c1de2f935b7bc34c3ab71c8aea35702b4
- TEST-SOE-LIVE-EXPIRING revision 1 (current)
    Recorded capacity: 10 managed placements
    Recorded term: 2026-10-01T00:00:00Z until 2026-11-15T00:00:00Z (current)
    Order reference: TEST-ORD-LIVE-0003
    Imported: 2026-10-29T02:38:44Z by a0000003000000000000000000000001
    Payload SHA-256: sha256:f33443652c3dc9fc4044f382d204389c24b22881369141443a827096d3a49f09
- TEST-SOE-LIVE-TERM revision 1 (current)
    Recorded capacity: 40 managed placements
    Recorded term: 2026-10-01T00:00:00Z until 2027-10-01T00:00:00Z (current)
    Order reference: TEST-ORD-LIVE-0002
    Imported: 2026-10-29T02:38:41Z by a0000003000000000000000000000001
    Payload SHA-256: sha256:9a35df2347e2da56cdac97a6ea2622e41b075448cd9348e85939bbd66e164a66

The status reflects only the entitlement records imported here; it neither extends nor denies contractual rights.
Entitlement status is advisory: nothing is blocked or stopped by it.

On the same Installation, show reported none before any import (effective capacity 20, the free allowance), expired after the ended record alone, and within once the current record was added (effective capacity 40, term ending 2027-10-01).

When the placement count cannot be read, the command still lists the records, prints Capacity status unavailable: and the reason on stderr, and exits with 8.

Exit codeMeaning
0The status and the records were printed.
8The records or the capacity status could not be read.