Skip to main content
Migrate Already selling? Move your customers to Keylight without re-issuing a single key.
Keylight

Licensing · Desktop

Desktop App Licensing

Why desktop apps need a different licensing model than web apps — signed keys, offline-first verification, and per-device activation.

Start Free

Updated March 2026

Licensing a desktop app is not the same problem as licensing a web app, and treating it as the same is the most common mistake developers make. A web app controls its own runtime — it lives on a server you operate, always online. A desktop app runs on someone else’s machine, on their network, on their schedule. The licensing model has to respect that.

This guide explains how desktop app licensing works, why it differs from the web, and what a robust implementation looks like on macOS and Windows.

Why desktop licensing is different

A web app validates entitlements trivially: every request already hits your server, so checking whether a user’s plan is active is just a database lookup. There is no separate “licensing problem.”

A desktop app inverts every assumption. It runs locally. It may have no internet connection. It cannot be patched on your schedule — the customer decides when to update. It can be copied between machines. You do not see it run.

That produces three requirements a desktop licensing system must satisfy that a web app never confronts:

  1. It must work offline. The app has to determine whether it is licensed without a guaranteed network connection.
  2. It must resist tampering. The license lives on a machine the customer fully controls, so it cannot be a value the app naively trusts.
  3. It must be bound to devices, not sessions. There is no login session — the unit of licensing is the install, so the system tracks machines.

A licensing approach that ignores any of these will either lock out paying customers or fail to stop casual sharing.

Signed keys, not database lookups

The naive desktop license is a string the app sends to a server, which checks a database and replies. This is just the web model bolted onto a desktop app, and it carries the web model’s fatal flaw here: the app cannot verify anything on its own. With no connection it must either fail closed — leaving a customer who has a valid license unable to use what they paid for — or fail open, in which case the check enforces nothing and is bypassed by blocking the network.

The robust model is a signed key. The license is a small structured document — the entitlement — carrying a cryptographic signature. A server mints it by signing the entitlement with a secret private key. The app ships with the matching public key and verifies the signature itself.

Verification is local computation: parse the document, run the signature check with the public key, inspect the plain fields. No server, no network. And it is tamper-proof — the signature covers every entitlement field, so editing the plan, the expiry, or the device limit invalidates the signature and the app rejects the key. The customer controls the file but cannot forge a valid one without the private key, which never leaves your server.

Ed25519 is the standard signing algorithm: 64-byte signatures, fast verification, well-reviewed. A signed desktop license looks like this:

{
  "id": "lk_01hx9z4bqncktjvx6a2r3p8wy",
  "productId": "prod_myapp_pro",
  "plan": "pro",
  "activationLimit": 3,
  "issuedAt": "2026-05-15T09:12:00Z",
  "expiresAt": null,
  "revoked": false,
  "sig": "base64url(ed25519_signature)"
}

Offline-first, with periodic revalidation

Signed keys make offline validation possible; a good system makes it the default. The app verifies the signature on every launch — instant, local, always works. That is the path the customer experiences.

Separately, on a schedule (commonly every few days, when a connection is available), the app makes one background revalidation call. That call catches anything the offline check cannot see: a license revoked after a refund, a chargeback, an entitlement change. If the app cannot reach the server within the revalidation window, it keeps running on the last known-good license — your outage never punishes a paying customer.

The tradeoff is that revocation is not instant: a refunded customer who stays offline keeps a working app until the next online revalidation. For nearly every desktop app that is the correct tradeoff — instant revocation would require a server call on every launch, breaking the offline guarantee for everyone to lock out a few people slightly sooner. The offline license validation guide covers this balance in depth.

Device activation across machines

Desktop licensing has no login session, so the licensed unit is the device. Each key carries an activationLimit — how many machines it may run on. A personal license might allow two or three; a team license, more.

When a customer installs on a machine, the app generates a stable device fingerprint from hardware identifiers and registers it against the key. The licensing server increments an activation count. When the count reaches the limit, further activations are refused until the customer deactivates an old machine — handled through a customer portal so it never becomes a support ticket.

Activation limits are what keep one purchased key from spreading across an office while still letting an honest customer use their laptop and desktop. The app activation system guide details how fingerprinting and the activation count work.

macOS and Windows specifics

The model above is identical on both platforms; two details differ.

Where the license is stored. On macOS the natural home is the Keychain — encrypted, sandbox-friendly, survives reinstalls. On Windows, the Credential Manager (DPAPI-protected) plays the same role. In both cases you store the signed lease, not a raw secret, and the OS keystore protects it from casual inspection.

Distribution and trust. macOS expects a Developer ID-signed, notarized build; Windows expects an Authenticode-signed binary. Code signing and license signing are separate things — code signing proves the app is from you, license signing proves the entitlement is from you — but customers experience them together as “this software is legitimate.”

Doing it without a backend

Every piece above — Ed25519 signing, key storage, the activation API, the revalidation scheduler, the customer portal, the webhook handlers tying it to payment — is buildable, and is collectively a backend you then own forever.

Keylight provides that backend as a service. It connects to your Stripe account, mints an Ed25519-signed lease whenever a payment completes, and tracks activations and revocations. Your app integrates through an SDK that does the local verification and the periodic revalidation:

import KeylightSDK

let licensing = try! Keylight.manager(
    sdkKey: "sdk_live_...",
    tenantId: "acme",
    productId: "myapp",
    keyPrefix: "ACME",
    trustedPublicKeyBase64: "<your-public-key>",
    trialDurationDays: 14,
    branding: .init(appName: "My App", purchaseURL: URL(string: "https://acme.example.com/buy")!, supportEmail: "[email protected]", tintColor: .blue)
)

await licensing.checkOnLaunch()

switch licensing.state {
case .licensed:
    enablePaidFeatures()
case .trial(let daysLeft):
    showTrialBanner(daysLeft: daysLeft)
case .expired:
    showRenewalPrompt()
case .invalid:
    showActivationSheet()
}

You write the UI; the licensing logic — signing, verification, activation bookkeeping, revocation — is handled. Keylight’s SDK is Swift-first for Apple platforms today; the licensing API and signed-lease format are platform-neutral. Plans start at $19/month with a free tier; see Pricing.

Frequently asked

How does desktop app licensing work?+

A desktop app is licensed with a cryptographically signed key. The app ships with a public key and verifies the signed license locally, with periodic online revalidation to catch revocations.

Why can't desktop apps validate licenses online like web apps?+

Desktop apps run without a guaranteed network connection — on planes, behind firewalls, offline. A licence check that requires a server call will fail for legitimate paying users.

What is a device activation limit?+

A device activation limit caps how many machines one license key may run on. The licensing system records each device and rejects activations once the limit is reached.

Start licensing your app today

Drop in the Swift SDK, point it at your dashboard, and sell paid apps in under a minute. Free forever tier included.

Start Free