Offline Licensing
Offline Licensing
LicenseSeat provides robust offline licensing that lets your users work without an internet connection while maintaining security and preventing license abuse.
Whether your user is on a 14-hour flight, touring China for a month with unreliable internet, or operating equipment in a remote location—their software keeps working.
Current offline model: machine files are the preferred offline artifact. They are encrypted, activation-bound, and fingerprint-bound. Older SDKs may still use signed offline tokens until they migrate, but new integrations should treat tokens as a legacy compatibility path.
The Mental Model
Think of offline licensing like a boarding pass:
- Check-in (Activation): Your user activates their license online. This "checks them in" and reserves their seat.
- Boarding Pass (Machine File): They receive a cryptographically signed "boarding pass" that proves they're authorized.
- Offline Travel: They can board the plane (use your software) without needing to call the airline (your server) again—the boarding pass is proof enough.
- Expiration: The boarding pass has an expiration. Eventually, they need to check in again.
The key insight: the seat is consumed at activation, not when generating offline credentials. This prevents users from getting unlimited offline artifacts without using their seat allocation.
How It Works
┌──────────────────────────────────────────────────────────────────────────────┐
│ ONLINE (Internet Available) │
├──────────────────────────────────────────────────────────────────────────────┤
│ │
│ 1. User enters license key │
│ │ │
│ ▼ │
│ 2. SDK calls: POST /activate │
│ │ │
│ ▼ │
│ 3. Server validates license, consumes seat, creates activation │
│ │ │
│ ▼ │
│ 4. SDK automatically fetches "machine file" (offline credentials) │
│ │ │
│ ▼ │
│ 5. Machine file stored securely on device │
│ │
└──────────────────────────────────────────────────────────────────────────────┘
│
│ User goes offline
▼
┌──────────────────────────────────────────────────────────────────────────────┐
│ OFFLINE (No Internet) │
├──────────────────────────────────────────────────────────────────────────────┤
│ │
│ 1. App launches, SDK tries online validation → fails (no network) │
│ │ │
│ ▼ │
│ 2. SDK falls back to offline validation │
│ │ │
│ ▼ │
│ 3. Machine file signature verified (Ed25519 cryptography) │
│ │ │
│ ▼ │
│ 4. Machine file decrypted using device fingerprint │
│ (Only works on the ORIGINAL device—not transferable!) │
│ │ │
│ ▼ │
│ 5. Expiry checked → License valid! │
│ │
└──────────────────────────────────────────────────────────────────────────────┘
Why This Is Secure
- Activation required first: You can't skip straight to offline. The seat must be consumed.
- Device-bound: The machine file is encrypted with a key derived from your device's unique fingerprint. Copy it to another computer? It won't decrypt.
- Cryptographically signed: The server signs the machine file. Tamper with it? The signature fails.
- Time-limited: Machine files expire. Users must eventually reconnect.
Real-World Scenarios
Scenario 1: Hustl User on a Flight
Context: Sarah uses Hustl (a macOS productivity app) and is about to board a 14-hour flight to Tokyo.
What happens:
| Timeline | What Sarah Does | What LicenseSeat Does |
|---|---|---|
| Before flight | Opens Hustl, already activated | SDK refreshes machine file in background (valid for 30 days) |
| On the plane | Enables airplane mode, opens Hustl | SDK tries online validation → timeout → falls back to offline |
| During flight | Works for 14 hours | SDK verifies machine file signature locally, checks expiry → valid! |
| Lands in Tokyo | Connects to hotel WiFi | SDK auto-validates online, refreshes machine file |
Sarah's experience: Completely seamless. She didn't even notice the offline/online transitions.
Scenario 2: Music Producer on a China Tour
Context: Alex is a DJ with a $299 music plugin (like a synth or effects processor). He's touring China for 30 days where internet is unreliable and VPNs often get blocked.
What happens:
| Timeline | What Alex Does | What LicenseSeat Does |
|---|---|---|
| Before trip | Opens plugin, clicks "Prepare for Offline" | SDK requests extended machine file (30-day TTL) |
| Day 1-15 | Performs at venues, no reliable internet | Offline validation succeeds every time |
| Day 20 | Plugin shows "Offline license expires in 10 days" | SDK warning based on machine file expiry |
| Day 25 | Finds working VPN for 5 minutes | SDK opportunistically refreshes machine file |
| Day 26-30 | Back to no internet | Continues working with refreshed credentials |
Alex's experience: One minor warning notification. Zero interruption to his performances.
Scenario 3: Industrial Equipment in Remote Location
Context: A robotics company deploys autonomous equipment with your licensed software. The equipment operates in locations with zero internet access for months at a time.
What happens:
| Timeline | What Operator Does | What LicenseSeat Does |
|---|---|---|
| At HQ | Provisions device with license | Standard activation → gets 365-day machine file |
| Deployment | Ships to remote site, no internet | N/A |
| Day 1-180 | Equipment operates autonomously | Offline validation on each startup |
| Day 300 | Equipment shows "License expires in 65 days" | Warning based on machine file expiry |
| Before expiry | Technician visits site with laptop | Repeats the manual air-gapped renewal flow: activate/check machine file from a connected admin system, then transfer the refreshed certificate |
Operator's experience: Set it and forget it for almost a year.
Configuration Options
You control offline behavior per license plan in your LicenseSeat dashboard:
| Setting | Description | Recommended |
|---|---|---|
| Offline TTL | How long the machine file is valid | 30 days for consumer apps, 90-365 days for enterprise |
| Grace Period | Extra time after TTL expires before hard lockout | 7 days (gives users time to reconnect) |
| Require Activation | Must activate online before getting offline credentials | Always enabled for security |
Example Plan Configurations
Consumer App (Hustl-style):
- Offline TTL: 30 days
- Grace Period: 7 days
- Seat Limit: 2 devices
Professional Plugin (Music production):
- Offline TTL: 45 days
- Grace Period: 30 days
- Seat Limit: 2 devices
Enterprise/Industrial:
- Offline TTL: 365 days
- Grace Period: 30 days
- Seat Limit: 10+ devices
SDK Integration
Automatic (Recommended)
The SDK handles everything automatically. Just configure and forget.
Depending on the SDK generation:
- newer SDKs such as C++ cache machine files
- older SDKs may still cache signed offline tokens until they migrate
licenseseat::Config config;
config.api_key = "pk_live_xxxxxxxx";
config.product_slug = "my-app";
config.storage_path = "/path/to/cache";
licenseseat::Client client(config);
auto activation = client.activate("USER-KEY");
Manual Control
For advanced or air-gapped use cases, you can manage the offline artifact manually.
The currently supported manual flow is:
- collect the fingerprint on the target machine
- call
activate - call
machine-file - transfer the returned certificate manually
See Air-Gapped Licensing for the full operator-assisted workflow.
Important: LicenseSeat does not currently ship a built-in challenge-response product flow, QR ceremony, or dedicated offline-activation endpoint. Those are future workflow possibilities, not current product behavior.
What Users See
Normal Operation
Users don't see anything special. The app just works, online or offline.
Near Expiry Warning
When offline credentials are about to expire and the user hasn't connected:
┌─────────────────────────────────────────────────────────────────┐
│ ⚠️ Offline license expires in 3 days │
│ │
│ Connect to the internet to extend your offline access. │
│ │
│ [Remind Me Later] [Connect Now] │
└─────────────────────────────────────────────────────────────────┘
Expired (with Grace Period)
If expired but still in grace period:
┌─────────────────────────────────────────────────────────────────┐
│ ⏰ Offline license expired │
│ │
│ Your offline access has expired. Please connect to the │
│ internet to continue using all features. │
│ │
│ Limited mode: You can still open existing projects. │
│ │
│ [Connect Now] │
└─────────────────────────────────────────────────────────────────┘
Fully Expired
┌─────────────────────────────────────────────────────────────────┐
│ 🔒 License validation required │
│ │
│ Please connect to the internet to validate your license. │
│ │
│ [Try Again] [Enter New Key] │
└─────────────────────────────────────────────────────────────────┘
Security Details
Device Binding
Machine files are encrypted with a key derived from:
encryption_key = SHA256(license_key + device_fingerprint)
This means:
- ✅ Works on the original device
- ❌ Won't decrypt on a different device (different fingerprint = different key)
- ❌ Won't decrypt with a different license key
The device fingerprint is derived from hardware identifiers:
- macOS: IOPlatformUUID (hardware UUID)
- Windows: SMBIOS system UUID
- Linux: /etc/machine-id or DMI system UUID
- iOS: Stable app-scoped identifier
Signature Verification
Every machine file is signed with Ed25519:
signature = Ed25519_Sign("machine/" + encrypted_payload, server_private_key)
The SDK verifies this signature using the public key (embedded in your app or fetched once). If anyone modifies the machine file, the signature check fails.
Clock Tamper Detection
The SDK tracks the last time it successfully validated. If the system clock suddenly jumps backwards (user trying to extend expired license), the SDK detects this and flags it as suspicious.
FAQ
Q: What if a user copies the machine file to another computer?
A: It won't work. The machine file is encrypted with a key that includes the device fingerprint. Different device = different fingerprint = decryption fails.
Q: What if a user never connects after activation?
A: Their offline credentials will eventually expire (based on your configured TTL). After expiry + grace period, they'll need to reconnect. You control how long this window is.
Q: Can I revoke a license while someone is offline?
A: Not immediately—that's the tradeoff of offline support. The machine file is self-contained. However:
- The machine file will expire at its TTL
- When they reconnect, the revocation takes effect immediately
- For high-security needs, use shorter TTLs
Q: What happens if the user's hardware changes (new motherboard)?
A: The fingerprint changes, so the machine file won't decrypt. They'll need to re-activate online. If they're at their seat limit, they may need to deactivate an old device first.
Q: Can users game the system by staying offline forever?
A: No. Machine files have a maximum TTL (you configure this). Even a 365-day TTL eventually expires. Most apps use 30 days.
Q: Does offline validation work in VMs or containers?
A: Yes, but you should ensure stable fingerprints:
- VMs: The fingerprint should remain stable across reboots
- Containers: Use a persistent volume to store the fingerprint, or inject it via environment variable
Next Steps
- Air-Gapped Licensing - For devices that never connect
- Swift SDK - Detailed offline configuration for Apple platforms
- C++ SDK - Offline support for native applications
- Signing Keys API - For advanced integrations