Skip to main content

Format

A self-hosted license is an Ed25519-signed JWT:
  • Signature scheme: EdDSA (RFC 8037 Ed25519).
  • The radar-hub binary embeds the Skyhook-controlled public key at build time. The matching private key never leaves Skyhook’s secret store.
  • Verified offline at boot - no network call required for the signature check itself.

Claims

Skyhook issues and signs the license; you supply the JWT verbatim as license.key. max_clusters and exp drive the in-app cluster-cap and expiry banners.

How verification works

At boot

The control plane reads the JWT from one of:
  1. RADAR_HUB_LICENSE_KEY env var (preferred).
  2. /etc/radar-hub/license file (Helm Secret mount).
Boot logs report one of (all prefixed with radar-hub: in the log line - grep for these strings): License-set path (the most common case):
  • radar-hub: license verified - happy path. Same log line carries license id, org, tier, max_clusters, expiry.
  • radar-hub: license expired (warn-only - hub keeps serving) - signature OK, past exp. An already-bootstrapped hub keeps serving behind the banner.
  • radar-hub: license is invalid (bad signature or claims) - signature mismatch or a missing/invalid claim. A not-yet-bootstrapped hub stays blocked at the license-required screen until a valid license.key is set; an already-bootstrapped hub keeps serving. Investigate immediately - this almost always means the wrong build talking to a real key, or vice versa.
License-not-set path (a separate log line earlier in boot):
  • radar-hub: no license configured - the JWT env/file wasn’t supplied. A not-yet-bootstrapped hub stays blocked until license.key is set; an already-bootstrapped hub keeps serving. Set license.key in your Helm values or mount a Secret to /etc/radar-hub/license.
Placeholder-key build (won’t appear on official ghcr.io/skyhook-dev/radar-hub images):
  • radar-hub: embedded license public key is the all-zero placeholder; rebuild with the real key before shipping to a customer - the build wasn’t cut against the real Skyhook public key, so license verification cannot succeed against any real customer JWT. Only happens on a locally-built image - the official ghcr.io/skyhook-dev/radar-hub:<version> images embed the production public key. If you see this in production, you’re running an unofficial build; pull the published tag instead.

Warn-only enforcement

The control plane does NOT block writes when a license that was present later expires or fails verification. Enforcement is contractual via the Subscription Agreement, not technical. The user-visible behavior is:
  • A persistent yellow banner in the web app when verification has failed.
  • Boot log lines visible to the operator.
In current releases verification is warn-only as a fail-safe, so a license blip doesn’t compound a real outage by locking your team out mid-incident. Treat it as grace, not an entitlement: the Subscription Agreement is explicit that warn-only operation is not a license to keep running past the subscription term, and future releases may enforce expiry more strictly. Keep the license current - see Rotation. There is one exception: a fresh unlicensed hub - one that has never had a valid license - is gated at the UI. It boots and installs, but the web app shows a full-screen license-required screen until a license is supplied. Once a hub is bootstrapped with a valid license, a later expiry or verification failure falls back to the warn-only banner above rather than re-gating. There is no phone-home, no heartbeat, and no auto-renewal. The license is verified offline against the public key embedded in the image; changing or renewing it is manual.

Rotation

Licenses are issued for a fixed term (typically 12 months) matching the contract. Renewal is always manual: your account team emails a new JWT; you update the Helm value or Secret and roll the radar-hub Deployment.

Key rotation (Skyhook-side)

The embedded public key is append-only. Skyhook will publish a new chart appVersion with both the old and new public keys when the signing key rotates; existing deployments keep working until they upgrade past the cutover release. You don’t need to do anything for a public-key rotation - just stay on supported chart versions and run helm upgrade at your normal cadence.

What you control

  • The license JWT itself (rotate by upgrading the chart with a new value).
  • Cookie sealing key (hub.cookiePassword) - independent from the license; rotating it just signs everyone out.
  • The break-glass admin (always available, regardless of license state).

What Skyhook controls

  • The signing private key.
  • The terms of the Subscription Agreement that backs warn-only enforcement.