Skip to main content

Verify trust (JWKS)

How a product locally verifies signed licensing material — our answer to “embed an RSA key like Cryptolens”.

Two different secrets

MaterialRoleEmbed in app?
License key (v1 XXXX-XXXX-XXXX-XXXX / v2 XXXX-XXXX-XXXX-XXXX-XXXX)Human secret for Runtime activate/validateOnly as config/secret — treat like a password
Platform verify keysPublic keys that validate JWS leases / offline responsesYes — via JWKS URL and/or pinned public JWK set

The license key is not a signing key. Signed rights travel in Compact JWS (MH-LEASE-V1, offline responses, …) under ES256 (ECDSA P-256). RSA (RS*) is not part of Crypto Profile v1.

  1. Call Runtime activate / validate / refresh with the license key (and device identity as required).
  2. Receive a signed lease (or offline response).
  3. Load trust material:
    • Online: fetch Runtime JWKS, cache with TTL, refresh on unknown kid once, then fail closed.
    • Offline / air-gap: ship an offline trust bundle (public keys only) with the build or via operator package.
  4. Verify JWS (alg, kid, signature, typ, expiry, audience). Reject alg=none and unknown algorithms.
  5. Enforce claims: match tenantId, licenseId, productId, customerOrganizationId, policySnapshotVersion, and policySnapshotHash to the expected license context; then apply entitlements, validity, and optional custom data. A missing or mismatched identity claim fails closed.

SDK packages already expose lease refresh + JWKS verify helpers — see the SDK matrix (verify API table) and Developer Quick Start (snippets).

SDK verify helpers

LanguageAPI
.NETVerifyLeaseAsync
JavaScript / TypeScriptverifyLease
Pythonverify_lease
JavaverifyLease
GoVerifyLease
Rustverify_lease
C++VerifyLease

Each public SDK Quick Start under examples/ demonstrates register → activate → validate → refresh → verify.

What never goes in the product binary

  • Platform private signing keys
  • Management session cookies / service credentials
  • Raw PSP / webhook HMAC secrets

Next steps