Skip to content
bitzorcas
中EN

Concept

ADR 0503: Signed commercial runtime license

ES256-signed immutable License envelopes, local signature verification, fail-closed states, persistent DeploymentId, offline leases, key rotation, and portability on expiry.

Last updated

Status

Accepted (Revised, 2026-07-25).

Context

A private NuGet feed only limits future downloads; it cannot recall cached packages. Customers run offline, on-prem, in containers, and on Kubernetes, so commercial runtime entitlement needs a trust model independent of package-download rights and tenant Feature entitlement.

Decision

Thirteen decisions define the trust model:

  1. ES256-signed immutable License Envelope — vendor private key signs; customer Runtime public key verifies; private key only in KMS/HSM or the controlled issuing system.
  2. The License constrains Customer, Product, Edition, Feature, Version Range, Environment, Deployment Limit, validity, offline lease, grace period, KeyId, and protocol version.
  3. The request path does not remotely call the License service — online activation issues a short-term lease; Runtime verifies signature + state locally; a background service refreshes safely.
  4. Fail-closed states — never-activated, forged signature, revoked, or over-privileged fail closed. An already-activated instance may enter limited Grace on a brief network failure but must alert and expose readiness.
  5. Unified states: Valid / Grace / Expired / Revoked / Invalid / Unavailable.
  6. License enforcement is not only UI/Host middleware — a commercial module execution entry consumes the License decision via a generated descriptor or the unified Mediator pipeline; a missing Licensing adapter defaults deny.
  7. DeploymentId is a persistent Site/Deployment identity — not PodId/ContainerId/MAC/CPU — shared across multi-instance so scaling does not re-consume authorization.
  8. Offline lease — offline deployments use a time-limited signed License file; immediate revocation is impossible, so revocation lists and renewals arrive via a controlled offline process.
  9. License expiry must not break customer backup/export/migration; write limits and data portability follow the commercial contract.
  10. Strong Name/obfuscation/integrity/Native AOT only raise attack cost — they are not the trust root.
  11. Key rotation and protocol portability on expiry — a shared free strategy cannot be an unsigned bypass. Protocol v2 adds policyId/profile/static composition to the signed payload; protocol v1 canonical signature bytes remain unchanged. A shared DeploymentId is allowed only for the precise combinations activated by ADR 0504.
  12. The base control plane does not depend on customer commercial entitlement — minimum identity sessions, forced password change, password recovery, permission-filtered navigation, and authorized LicenseManagement operations use a compile-time exact message list to bypass the commercial gate. Authentication, authorization, validation, transactions, and audit still execute; registration, invitations, user administration, and business features remain outside the list.
  13. Base readiness and commercial readiness are separate — /health/ready decides whether the instance can receive base traffic, /health/license reports commercial entitlement, and /health remains the aggregate diagnostic. An unavailable License does not remove the bootstrap control plane from the load balancer; normal business operations still fail closed.

Consequences

The License module is a deep module hiding signature, trusted time, cache, online/offline lease, key rotation, and the state machine behind a stable interface. When a customer fully controls the private host, absolute anti-patch is impossible — truly non-leakable capability stays in a vendor-controlled remote service. PlatformBilling may offer in-customer-system tenant plans but cannot issue or decide the vendor Runtime License.

See also

100%

Scroll or use controls to zoom · drag when enlarged · double-click for 100% / 200%