Offline verification
The offline artifact is a signed v3 lease issued by the Keylight API. The SDK reconstructs the exact signed payload (entitlements sorted, pipe-delimited) and verifies it with Ed25519 against the tenant’s trusted keyset, applying a 300-second clock-skew tolerance.
Pin or fetch the trusted keyset
Section titled “Pin or fetch the trusted keyset”use keylight::KeylightConfig;
let cfg = KeylightConfig::builder("your-tenant", "your-product", "sdk_live_…") // Pin trusted keys explicitly instead of fetching them: .trusted_key("k1", "<raw ed25519 public key, base64>") .max_offline_days(7) // omit to run offline as long as the lease itself is current .build();The trusted keyset can be fetched once from GET /{tenant}/.well-known/keylight-keys (keylight::keyset::fetch_keyset) or pinned at build time with .trusted_key(kid, pub_b64).
How the cached lease is gated
Section titled “How the cached lease is gated”cached_lease() returns the lease only when it is kid-known, signature-valid, unexpired, and (if set) within max_offline_days of the last online validation. Entitlement checks read that gated lease, so they work with no network call:
if kl.has_entitlement("pro") { // reads the gated cached lease — offline, synchronous}A forged or hand-edited lease cannot pass verification without the tenant’s private key — the security boundary is the signature, not at-rest secrecy.
state() additionally forces Invalid if the system clock has been rolled back past tolerance since the last server contact, closing the offline path to reviving an expired lease. The check is UTC-based (timezone changes don’t trip it) and self-heals on the next successful validate().
At-rest storage
Section titled “At-rest storage”Encrypted lease and key material is stored device-bound with ChaCha20-Poly1305 (the key is derived from a per-device identity via BLAKE3) — copying the files to another machine won’t decrypt them.
- Install — add the SDK and activate a license.
- How offline leases work