Licensing · Fundamentals
Software License Keys Explained
How license keys are generated, delivered, validated, and revoked — and how to add them to your app without building the infrastructure yourself.
Start FreeUpdated March 2026
Software license keys have been around for decades, but what happens under the hood has changed dramatically. The “XXXXX-XXXXX-XXXXX” string you copy from a confirmation email looks simple. The machinery that makes it secure — so that your app can trust it without calling home every time — is more interesting.
This guide explains how license keys work at every stage: generation, delivery, validation, and revocation. It also covers the practical question most developers run into: how do you add all of this to an app without spending a month building your own licensing backend?
What a software license key actually is
At its most basic, a license key is a unique string that the customer receives after paying and that the application checks to decide whether to unlock paid functionality. Early license keys were little more than carefully checksummed sequences of characters — valid if the digits summed to the right remainder, invalid otherwise. A pirated copy only needed one person to figure out a valid string and post it online.
Modern license keys are fundamentally different. Instead of encoding validity in a pattern, they carry a cryptographic signature: proof that a server you control minted this specific key for this specific entitlement. The server signs with a private key it keeps secret; the app verifies with the corresponding public key it ships in the binary.
The public/private keypair is the core security model. Knowing the public key — which is fine to embed in your app and ship to every customer — tells an attacker nothing about how to forge a valid signature. Only the server that holds the private key can produce signatures the app will accept.
The result is a license key that cannot be guessed, cannot be trivially forged, and does not require the app to phone home on every launch just to know whether it’s legitimate.
How license keys are generated
When a customer completes a purchase, the licensing backend receives a signal — typically a payment webhook from your payment processor — and mints a license.
Minting means assembling an entitlement payload: a structured blob that says who the license belongs to, what product and plan it covers, when it was issued, when it expires (if ever), and how many device activations it permits. That payload is then signed using an asymmetric algorithm. Ed25519 is the standard choice today: it produces compact 64-byte signatures, is extremely fast to verify, and has well-reviewed security properties.
The signed result is the license key. In Keylight’s implementation, the key is a signed lease — a small JSON-like structure that travels as a base64-encoded string to the customer. The payload looks roughly like this:
{
"keyId": "kl_live_abc123",
"customerId": "cus_stripe_xyz",
"productId": "prod_myapp_pro",
"plan": "pro",
"activationLimit": 2,
"issuedAt": "2026-05-15T10:00:00Z",
"expiresAt": null,
"signature": "base64(ed25519_signature_over_above_fields)"
}
The signature covers every field above it, so changing even a single character — bumping activationLimit from 2 to 99, for instance — invalidates the signature. The app will detect the tampering and reject the key.
The license is typically delivered via email immediately after payment and is also available in the customer’s dashboard. Some licensing systems also return it in the API response to the checkout session, so the app can receive it directly without the customer manually entering anything.
How keys are validated — online vs offline
There are two broad validation strategies, and they are not mutually exclusive.
Online validation means the app sends the key to a server, which looks it up in a database and returns a yes/no. This gives you real-time revocation — the moment you mark a key revoked, the next app launch is rejected. The downside is a hard dependency on your server being reachable. A user on a plane, behind a restrictive corporate firewall, or in a spotty network zone cannot validate their license. For desktop apps in particular, this is a significant usability problem.
Offline validation flips the model. Instead of asking the server, the app verifies the cryptographic signature locally using the public key it already has. No network call, no latency, no dependency on your server’s uptime. The app can validate the license instantly on launch, even with no internet access at all.
This is why offline license validation has become the standard for desktop apps. The tradeoff is revocation latency: a revoked key is rejected on the next online revalidation, not immediately. Most licensing systems handle this by requiring a periodic re-check — for example, once every seven days the app connects and reconfirms the lease is still valid. If it cannot reach the server within that window, it can continue operating on the cached valid lease. When it does connect and finds the lease revoked, it locks.
This architecture is robust: customers in normal use never notice the validation happening, and revocation propagates within days rather than never.
Revocation, refunds, and device limits
Two events typically trigger revocation: a refund and a chargeback.
When a customer requests a refund, your payment processor issues a refund event. A well-designed licensing backend listens for this webhook and immediately marks the associated license key revoked in its database. The physical key string the customer holds becomes invalid. The next time the app performs an online revalidation, it receives a rejection response and presents the user with a message explaining their license is no longer active.
Chargebacks — where the customer disputes the charge with their bank — are handled the same way, though typically faster: the key is revoked as soon as the chargeback is filed, not after resolution, because the outcome is often adverse for the merchant.
Device activation limits are a separate but related concept. A license key might be valid for two devices: the customer can activate it on their MacBook and their iMac, but not a third machine. The backend tracks each activation — a fingerprint of the device, typically a combination of hardware identifiers — against the key’s activationLimit. When the limit is reached, new activation attempts fail until one existing activation is deactivated.
Activation limits exist to prevent a single customer’s key from being shared across an organization. They’re also what makes the “household sharing” model common in consumer software: a key for up to five devices is reasonable; a key for unlimited devices is closer to a site license and priced accordingly.
Adding license keys without building the infrastructure
If the sections above made you think “this is a lot of work,” you are correct. Building your own licensing infrastructure means:
- A key generation and signing service with secure private key management
- A database that tracks licenses, activations, and revocation status
- Webhook listeners for payment events (refunds, chargebacks, new sales)
- An API the app calls for activation and revalidation
- A customer portal for key retrieval and device management
- Email delivery of keys after purchase
Most indie developers and small teams do not have the bandwidth to build and maintain all of this. That is the gap Keylight fills.
Keylight is a licensing layer that sits on top of Stripe. Stripe handles the payment; Keylight handles everything that comes after it. When a Stripe payment completes, Keylight automatically mints an Ed25519-signed license key, delivers it to the customer, and tracks it in its dashboard. Your app integrates via a Swift SDK:
import KeylightSDK
// Create the manager once at app startup (e.g. in your @main type)
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)
)
// At app launch, resolve the stored license
await licensing.checkOnLaunch()
switch licensing.state {
case .licensed:
// Unlock paid features
enablePaidFeatures()
case .trial(let daysLeft):
showTrialBanner(daysLeft: daysLeft)
case .expired:
showRenewalPrompt()
case .invalid:
showActivationSheet()
}
The SDK handles the local Ed25519 signature verification, the periodic online revalidation, and device activation bookkeeping. You write the UI; Keylight provides the licensing logic.
Refund revocation, activation limits, and the customer dashboard for managing devices all come included. You do not write webhook handlers or build a license database. The license keys feature page covers the full capability set and how it integrates with Stripe’s checkout flow.
Plans start at $19/month, which makes Keylight cost-effective from the first sale. For most developers, the time saved not maintaining licensing infrastructure — plus the customer-facing polish of a proper dashboard and key management experience — justifies the fee many times over.
If you are selling a macOS, iOS, or other Apple platform app outside the App Store, licensing infrastructure is not optional: it is the mechanism by which your paid product stays paid. The question is only whether you build it yourself or use something purpose-built for the job.
Frequently asked
What is a software license key?+
A software license key is a unique string issued to a customer that unlocks a paid app or specific features. Modern keys are cryptographically signed so the app can verify them without contacting a server.
How are license keys validated offline?+
The app ships with a public key. The license is signed with the matching private key on the server, so the app can verify the signature locally — no network call required.
Can a license key be revoked after a refund?+
Yes. When a payment is refunded the key is marked revoked server-side; the next time the app revalidates, the lease is rejected.
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