How it works
Keylight has three moving parts: the Keylight backend (activation, validation, lease signing), the Swift SDK (embedded in your app), and the dashboard (where you configure products and mint keys).
The players
Section titled “The players”- Swift SDK - a small Swift Package you embed. Exposes
LicenseManager.manager, gates features via@Publishedstate, signs activations with an ephemeral instance ID it generates and persists in the Keychain. - Keylight backend - owns your license records, serves the dashboard, signs Ed25519 leases, and enforces per-license activation caps.
- Dashboard - where you configure apps, key types, and manage issued licenses.
- Stripe - where payments happen. Either linked via Connect (zero-config) or plumbed through a manual webhook.
The path a license takes
Section titled “The path a license takes”Once a license exists, the app takes over:
Subsequent launches:
- SDK reads the cached lease from the Keychain.
- SDK verifies the lease signature locally using the embedded Ed25519 public key.
- If the lease is still fresh, state is
.licensedand no network call happens. - If the lease is near expiry or older than ~6h, the SDK calls
/validateto refresh it.
This is the offline-first part: the app can stay entitled for days without a network. See Offline leases for the exact rules.
Why Ed25519 leases?
Section titled “Why Ed25519 leases?”- Keylight signs; the app verifies. The app never needs a network to know whether a lease is valid.
- Ed25519 keys are short, signatures are 64 bytes, and verification is cheap enough to run on launch.
- If Keylight has an outage, already-activated apps keep working until their lease expires. New activations fail; existing users don’t notice.
Full wire format: Ed25519 leases.
What the SDK does locally
Section titled “What the SDK does locally”- Verifies Ed25519 lease signatures.
- Persists the license key + lease + instance ID in the Keychain.
- Runs a 5-minute debounced refresh, plus a 24-hour near-expiry window and a 6-hour staleness check.
- Publishes
LicenseStatechanges on the main actor so SwiftUI can react.
Full state machine: License lifecycle.