LicenseKit
Licensing you run yourself, with leases that keep working offline.
A license server, an admin console and an SDK for Electron and Node apps. Your customer types a license key once. The app then holds a short-lived lease signed with Ed25519 and checks it locally.
Three ways to try it without an account: the browser sandbox, an npx quickstart or the desktop demo.
eyJhbGciOiJFZDI1NTE5IiwidHlwIjoibGljZW5zZWtpdC1sZWFzZStqd3QiLCJraWQiOiIyMDI2LTEwIn0.eyJpc3MiOiJodHRwczovL2xpY2Vuc2VraXQuY2FyY2hhbGFicy5jb20iLCJhdWQiOiJleGFtcGxlLWFwcCIsInN1YiI6ImN1c180SDhUUTIiLCJqdGkiOiJsc18zSE5WOFIyQyIsImlhdCI6MTc5MTcyNzIwMCwibmJmIjoxNzkxNzI3MjAwLCJleHAiOjE3OTE4MTM2MDAsImxpZCI6ImxpY183UTJNNEs5WCIsImZwIjoic2hhMjU2OjljMWU0YjdhIiwiZmVhdCI6WyJleHBvcnQiLCJ2ciJdLCJyZXYiOjN9.UWL6wVkF7vvXMxuFudzGs-N5AiOKu57dwO82StMyw24SbVSBx0i6iFeSZd7MrBQCDaIpfd0oj3DvePrapV05Ag
- alg · kid
- Ed25519 · 2026-10
- aud
- example-app
- exp
- 12 Oct 2026, 14:00 UTC
- feat
- export, vr
- valid
- grace
- invalid
- clock_suspect
Online. The signature checks out against key 2026-10. The next server check is due in 24 hours.
How a check works
A revoked license stops working within the revocation window
The app checks its lease locally and asks the server again when the revalidation interval ends, every 72 hours on the default policy. If the server cannot be reached, a grace period starts.
Timeline from the last successful check on the default policy: the lease is valid for 72 hours, then a grace period of up to 7 days runs while offline, and after day 10 the lease is invalid.
Revocation windowLast successful check, plus the revalidation interval, plus the grace period: up to 10 days on the default policy. Both are set per policy.
Why short leasesThe same reasoning as short-lived certificates in RFC 9608: a credential that expires soon needs no revocation list.
Clock rollbackIf the device clock reads more than 24 hours earlier than the last time seen, the SDK reports clock_suspect until the next online check.
Integration
Ten lines in your app
The SDK runs in the Electron main process and in plain Node. It verifies leases offline with the public keys your server publishes at /v1/keys.
const { LicenseKit } = require('@carchalabs/licensekit-electron');const kit = new LicenseKit({ serverUrl: 'https://licenses.example.com', product: 'example-app', publicKey: [currentKeyPem, nextKeyPem], storageDir: app.getPath('userData')});let state = await kit.check();if (state.status === 'unlicensed') state = await kit.activate(licenseKey);if (LicenseKit.hasFeature(state, 'export')) enableExport();- 1kit.check()unlicensed, no lease saved yet
- 2kit.activate(licenseKey)valid, lease signed with key 2026-10
- 3LicenseKit.hasFeature(state, 'export')true
Security model
What it protects, and what it cannot
Protects against
Does not protect against
Scope
Not in version 1
Listed so you can rule it out early.
- Floating and concurrent licenses
- Subscriptions and payment integrations
- Customer self-service portal
- Activation by file on air-gapped machines
- Native and C++ SDKs
- Multi-tenant sign-up
- Code signing of the demo app
- Keys held in a KMS or HSM