License Keys
A license key is a human-facing secret for Runtime validation. Vendors issue and rotate keys in Management; products present the key to the Runtime plane.
A license key is not a Compact JWS or signed lease/license artifact (MH-LEASE-V1, MH-LICENSE-V1, …). Vocabulary and other non-goals: Core Concepts.
Formats (v1 and v2)
The platform supports two human key shapes. Version is metadata (formatVersion) — it is not embedded in the string.
| Version | Canonical form | Significant chars | Entropy | Status |
|---|---|---|---|---|
| v1 | XXXX-XXXX-XXXX-XXXX | 16 (4×4) | ~80 bit | Retained forever for existing material |
| v2 | XXXX-XXXX-XXXX-XXXX-XXXX | 20 (5×4) | ~100 bit | Default for new issue / rotate |
Shared rules:
- Alphabet: Crockford Base32 without
I,L,O,U—0123456789ABCDEFGHJKMNPQRSTVWXYZ - Canonical = uppercase; no product prefix in the string
v1 example (illustrative)
7K3M-9NPQ-2RST-WXYZ
v2 example (illustrative)
7K3M-9NPQ-2RST-WXYZ-ABCD
Normalization (before validate)
- Trim whitespace.
- Strip spaces/optional separators; collect significant characters.
- Uppercase.
- On input only, map confusable chars:
I/L→1,O→0(generators never emitI,L,O,U). - If significant length = 16 → treat as v1; if 20 → treat as v2; otherwise reject.
- Reject any character outside the alphabet after mapping.
Hashing always uses the dashed uppercase canonical form for the detected version.
Storage and AuthN
- At rest: SHA-256 hex of canonical UTF-8 plaintext only — plaintext is never stored.
- Issue / rotate: full plaintext shown once; cannot be retrieved again. New keys default to v2.
- Support handles: first group (
XXXX) public prefix; last group (YYYY) public suffix. - UI mask: v1
XXXX-••••-••••-YYYY; v2XXXX-••••-••••-••••-YYYY. - Runtime: normalize (length branch) → hash → look up under the trusted tenant. Both v1 and v2 are accepted.
- Logging: never log the full key — prefix/mask only.
Safe handling
Treat the full key like a password (secret manager / vault; not source control or chat). Apps may use env/secret stores (see MYHORECA_LICENSE_KEY in the SDK matrix). On compromise: rotate in Management and update Runtime clients. Entropy is for online Runtime validation with tenant scope and rate limiting — not a platform signing key.
Durable rotation and retry
Use the customer-scoped Customer License actions API with an exact current-material precondition and a stable Idempotency-Key. A successful rotation invalidates the old Runtime credential immediately, but it does not revoke the License or invalidate already signed leases.
Store the plaintext before dismissing the first successful response. A network or audit recovery retry cannot reveal it again: the durable replay returns the same operation/material references and mask with explicit null plaintext. Rotation responses are non-cacheable, and safe audit contains only typed identifiers, state, mask, format, and timestamps.