Skip to main content
Version: Next

Licensing

Licensing in opscotch uses time-limited issued licenses and a delegated license hierarchy.

Licensing Model

Issued licenses form this hierarchy:

  • ROOT
  • ISSUER
  • VENDOR
  • ORG
  • PLATFORM
  • RUNTIME

Licenses can be split into child licenses down the hierarchy.

In practice:

  • end user organisations are issued at the ORG level
  • the runtime will only accept RUNTIME or PLATFORM licenses
  • ISSUER, VENDOR, and ORG parties can use the opscotch licensing service to manage and split licenses
  • all issued licenses are created through https://licensing.opscotch.co

An organisation will create PLATFORM licenses. This may be one platform license for a whole environment, or one license per development user.

The previous embedded-license model still works, but it is now the legacy path and is planned for removal in the next release.

All issued licenses have an expiry date. After the expiry date:

  • the license becomes invalid
  • workflows or apps using that license will stop
  • the license must be renewed or replaced before the workload can continue

Roles and Flow

The delegated licensing flow is:

  • ISSUER and VENDOR parties can hold large parent licenses and issue child licenses downstream
  • ORG parties can create PLATFORM licenses for departments, environments, or individual development users
  • PLATFORM licenses can be installed into the opscotch licensing app and used to serve runtime licensing
  • RUNTIME licenses are the licenses consumed by the runtime when workloads start

This model supports reseller, managed-service, and customer-managed operations without requiring each package to carry its own long-lived embedded license.

License Attributes

License metadata is attribute-based. Attributes are inherited by child licenses unless changed subject to the attribute rules.

Attributes can be:

  • string values
  • numeric values
  • boolean values
  • constrained values

Constraint examples include:

  • read-only attributes
  • directional attributes that only allow values to move in one direction downstream

For example:

  • issuedDateUTC is a read-only string attribute
  • expiryDateUTC can only be decreased when issuing a child license
  • credits is numeric when present and can only be reduced in child licenses

Not all licenses use credits. Some licenses are open and do not carry a credit balance.

Issuing Child Licenses

Child licenses are issued through the licensing service at https://licensing.opscotch.co.

Request Preconditions

The request must satisfy these preconditions:

  • Request body: parentLicenseId, ownerKeyHex, and licenseTo are required.
  • Request headers: idempotencyKey is required.
  • Conditional request body: metaData.credits is required only when the parent license is constrained by credits.
  • Retry rule: if the request outcome is uncertain, retry the same request with the same idempotencyKey.

idempotencyKey must be unique to the transaction.

Request Example

IK="$(date +%s)"

curl https://licensing.opscotch.co/licensing/child \
-v \
-H "idempotencyKey:${IK}" \
-H "Content-Type: application/json" \
-X POST \
-d '{
"licenseTo": "<name>",
"parentLicenseId": "<id>",
"ownerKeyHex": "<key>",
"metaData": {
"platform": "<name>:r:",
"expiryDateUTC": "2030-03-13T22:41:27.014Z!i!"
}
}' | jq

Response Example

An issued license response looks like this:

{
"status": 200,
"replay": false,
"license": "AwJhAR+LC...DLlGGtQK",
"licenseId": "6EC7...FA36",
"licenseTo": "acme ltd non-prod",
"ownerKeyHex": "739D550F...9B4D276",
"type": "ORG",
"metadata": {
"env": "non-prod:r:CF06EC1DA6FAA54E23F7:",
"issuedDateUTC": "2026-03-23T21:05:48.094Z!d!6EC70AFFE6054B4DFA36!",
"expiryDateUTC": "2027-03-24T00:00:00.000Z!i!6EC70AFFE6054B4DFA36!",
"service": "opscotch non-prod!r!CF06EC1DA6FAA54E23F7!",
"rootDomain": "opscotch non-prod!r!CF06EC1DA6FAA54E23F7!",
"realm": "prod!r!CF06EC1DA6FAA54E23F7!",
"issuer": "opscotch issuer non-prod:r:E06721004043FF257667:",
"vendor": "opscotch non-prod:r:EF8B05899445AAA66075:",
"org": "acme ltd non-prod:r:6EC7...A36:"
}
}

Retained Response Values

After issuing a child license, store these response values:

  • license
  • licenseId
  • metadata.expiryDateUTC
  • ownerKeyHex

licenseId and ownerKeyHex are required for later license-management operations, including reading authorised descendants, issuing further child licenses, and deactivating licenses.

The licensing service returns ownerKeyHex only on the first successful issuance response. Completed replays with the same idempotencyKey do not return it again, so store it securely when the license is first issued.

Using Licenses

There are two common ways to use issued licenses in opscotch:

  • configure a runtime to obtain runtime licensing from a licensing service
  • embed a PLATFORM license into a packaged application so the package ships with its own runtime license

Licenses are runtime-dependent. opscotch non-prod licenses are valid only on non-production runtimes, and opscotch prod licenses are valid only on production runtimes.

When a package includes an embedded PLATFORM license, a runtime using that package does not need to obtain a separate license to run it.

When packaging opscotch apps, you can add multiple licenses so the package is licensed for multiple environments.

For packaging details, see Packaging.

Operational Benefits

  • licensing can be changed without rebuilding packages
  • issuers and vendors can delegate licenses downstream without manual repackaging
  • organisations can split and manage their own platform allocations
  • runtime licensing can be centralised in the licensing app
  • attribute-based metadata allows policy and constraints to flow with the license hierarchy
  • packages can still embed licenses when that deployment model is preferable

Licensing App

The opscotch licensing app is one deployment pattern for centralised license management.

This app can be added to any opscotch runtime and configured with PLATFORM licenses. Other runtimes can then be configured to obtain runtime licenses from it.

You can install the licensing app:

  • in the same runtime
  • in a separate opscotch runtime that hosts the organisation's licensing server

The licensing app can be configured with multiple licenses using licensePools.

Implementation reference:

Development Runtime

Using the opscotch development runtime does not require a registered license.

When the runtime starts in development mode, it will automatically provision a temporary development license with a 1 hour expiry. This means:

  • Workflows or apps running for longer than 1 hour will stop when that license expires.
  • Restarting the runtime provisions a fresh 1 hour development license.
  • Secret redaction is disabled on the automatically provisioned development license.
  • Secrets written to logs will be tagged as <THIS WILL BE REDACTED>secret</THIS WILL BE REDACTED>.

Users can register on the website for a free development license. When using that license, the metadata forceRedaction=true can be applied to enable full redaction behavior.