TaskSultan Docs tasksultan.com

Operations

Licensing

How a TaskSultan deployment proves it is licensed and where the check happens.

A licence is a lease: a signed statement the platform issues for one installation and one runnable copy. The machine that runs automations verifies the lease with a public key and nothing else. It holds no private key and no shared secret and makes no network call. There is nothing on the customer's machine that could mint a lease.

#What a lease says

A lease is JSON with three parts: the claims, the algorithm (ed25519) and the signature over the canonical form of the claims. The claims are:

  • licenceId, the entitlement, stable across renewals.
  • installationId, one per customer installation.
  • instanceKey, one per runnable copy. A fleet of ten robots is one installation and ten instances.
  • leaseNonce, distinct per issued lease, so a renewal is a new artifact and a replay is detectable.
  • tier and capabilities.
  • issuedAt, renewBy, expiresAt and graceUntil.

The claims are serialised with their keys sorted recursively, so the same claims always produce the same bytes and a re-serialised lease still verifies. The verifier checks the signature over the canonical bytes, never over whatever JSON it happened to receive.

#How a lease is verified

The check order is part of the contract: signature, then binding, then time, then capability. A lease that is both forged and expired reports forgery first.

  1. Shape: a malformed lease is a fact about the file, not the licence.
  2. Schema: an unknown schemaVersion is refused before its claims are read.
  3. Signature: the keyId must match the public key the robot holds. The signature must verify.
  4. Binding: the lease must name this installation and this instance.
  5. Time: past graceUntil the right is gone. Between expiresAt and graceUntil the robot runs in grace and says so.
  6. Capability: when a capability is required, the lease must carry it.

Each failure has its own code: LICENCE_MALFORMED, LICENCE_SCHEMA_UNSUPPORTED, LICENCE_SIGNATURE_INVALID, LICENCE_WRONG_INSTALLATION, LICENCE_WRONG_INSTANCE, LICENCE_EXPIRED, LICENCE_CAPABILITY_MISSING and LICENCE_MISSING.

#Where enforcement happens

LicenseManager.canExecute('execution') is the enforcement point. It is asked once before an automation starts and never consulted again during the run. Two rules follow from that.

  • Fail closed on new work. A deployment that declares itself licensed (TS_LICENCE_ENFORCE=1) and cannot prove it refuses to start. A deployment that says nothing runs unenforced and the decision says so.
  • Fail open on in-flight work. A lease that expires mid-run cannot abort a production line. The next start is what refuses.

An unlicensed start is a pre-run refusal, not a retryable exception. LicenceRefusal is deliberately neither a SystemException (which the runner retries) nor a BusinessException (which means your own rule failed). A configured lease that does not verify always refuses, so configuring a broken lease is not a way to run unlicensed.

The licence is configured through the environment, with the same convention as the model adapter:

TS_LICENCE_ENFORCE     1 or true to require a usable lease
TS_LICENCE_LEASE       path to the signed lease
TS_LICENCE_PUBLIC_KEY  path to the issuer's public key
TS_INSTALLATION_ID     this installation
TS_INSTANCE_KEY        this runnable copy

There is no CLI verb for licensing. It is read from the environment when the Robot service starts.

#Tiers and capabilities

Capabilities are authoring, execution, desktop, cloud and managed-oncall. The default tiers are solo, team and managed: solo carries authoring and execution. team adds desktop. managed adds cloud and managed-oncall. The tier names, their capability sets and the lease and grace durations are operator-owned values, not fixed decisions.

The issuing side, runtime/licence-service.ts, holds the private key and is the platform's own administrative edge. A customer's Robot imports the verifier, which needs the public key and nothing else. Renewal is the customer's own explicit act through their tooling. Because verification is offline, a deactivated instance is not stopped instantly: it stops when its lease stops being renewed, which is why leases are short and renewBy exists.