LicenseSeat Rust SDK
Official Rust SDK for LicenseSeat — simple, secure software licensing for desktop apps, games, CLI tools, and plugins.
Table of Contents
- Installation
- Quick Start
- License Lifecycle
- Entitlements
- Offline Validation
- Heartbeat & Seat Tracking
- Event System
- Configuration
- Error Handling
- Telemetry & Privacy
- Examples
- Feature Flags
- API Reference
Installation
Add to your Cargo.toml:
Or manually:
[]
= "0.5.3"
Offline support is included in the default build. If you disable default features
and still want machine-file / offline-token verification, add offline back explicitly:
Quick Start
Use a pk_* publishable API key in client applications.
Keep sk_* secret keys server-side only.
use ;
async
License Lifecycle
Activation
Activation binds a license key to this device and consumes a seat:
use ;
let sdk = new;
// Simple activation
let license = sdk.activate.await?;
println!;
println!;
// Activation with options
let license = sdk.activate_with_options.await?;
When to activate:
- First app launch with a new license key
- When the user enters a different license key
- After a deactivation (switching devices)
Validation
Validation checks the license status without consuming a new seat:
let result = sdk.validate.await?;
if result.valid else
// Check for warnings (e.g., expiring soon)
if let Some = &result.warnings
When to validate:
- On app launch (after initial activation)
- Periodically in the background (SDK does this automatically)
- Before performing license-gated operations
Deactivation
Deactivation releases the seat, allowing activation on another device:
// Deactivate current device
sdk.deactivate.await?;
println!;
When to deactivate:
- User clicks "Deactivate" in settings
- During app uninstall (if you have an uninstaller)
- When switching to a different license key
Entitlements
Entitlements provide fine-grained feature gating beyond simple license validity.
Quick Check
// Simple boolean check
if sdk.has_entitlement
if sdk.has_entitlement
Detailed Status
use EntitlementReason;
let status = sdk.check_entitlement;
println!;
println!;
match status.reason
List All Entitlements
if let Some = sdk.current_license
Offline Validation
The Rust SDK now matches the C++ SDK's machine-file-first offline flow.
use ;
let config = Config ;
let sdk = new;
Fallback Modes
| Mode | Behavior |
|---|---|
NetworkOnly |
Always require network. Fail if offline. (Default) |
Always |
Try online first, then fall back to a cached machine file or legacy offline token |
How It Works
- Activation binds the license to a canonical device fingerprint.
- The SDK checks out a machine file from
/machine-fileafter activation. - The machine file is Ed25519-signed and AES-256-GCM encrypted using a key derived from
license_key || fingerprint. - When offline, the SDK verifies the signature, decrypts the payload, and enforces expiry / grace / fingerprint binding locally.
- Legacy offline tokens remain available only as an optional compatibility fallback via
enable_legacy_offline_tokens.
Clock Tampering Protection
The SDK includes safeguards against clock manipulation:
- Offline artifacts include
nbf(not before) andexp(expiration) timestamps - Significant clock jumps are detected and flagged
- Backward clock movement invalidates offline validation
Heartbeat & Seat Tracking
Heartbeats enable real-time seat tracking for concurrent user limits:
use Duration;
let config = Config ;
let sdk = new;
// Manual heartbeat
let response = sdk.heartbeat.await?;
println!;
Seat Release
If heartbeats stop (app crash, network loss, user closes app), the seat is released after the grace period configured in your LicenseSeat dashboard.
Continuous Heartbeat Loop
use interval;
let sdk = new;
let sdk_clone = sdk.clone;
spawn;
Event System
Subscribe to SDK events for reactive UI updates:
use ;
let sdk = new;
// Get event receiver
let mut events = sdk.subscribe;
// Spawn event handler
spawn;
Event Types
| Event | Description |
|---|---|
ActivationSuccess |
License successfully activated |
ActivationError |
Activation failed (invalid key, limit exceeded, etc.) |
ValidationSuccess |
License validated successfully |
ValidationFailed |
Validation failed (expired, suspended, etc.) |
DeactivationSuccess |
License deactivated, seat released |
DeactivationError |
Deactivation failed |
HeartbeatSuccess |
Server acknowledged heartbeat |
HeartbeatError |
Heartbeat failed (network error, etc.) |
Configuration
Full Configuration Example
use ;
use Duration;
let config = Config ;
let sdk = new;
Configuration Reference
| Option | Type | Default | Description |
|---|---|---|---|
api_key |
String |
— | Your publishable LicenseSeat API key (pk_*, required). Keep sk_* server-side only. |
product_slug |
String |
— | Your product slug (required) |
api_base_url |
String |
https://licenseseat.com/api/v1 |
API base URL |
auto_validate_interval |
Duration |
1 hour | Background validation interval |
heartbeat_interval |
Duration |
5 minutes | Heartbeat interval |
offline_fallback_mode |
OfflineFallbackMode |
NetworkOnly |
Offline validation behavior |
max_offline_days |
u32 |
0 |
Grace period for offline mode (days) |
telemetry_enabled |
bool |
true |
Send device telemetry |
app_version |
Option<String> |
None |
Your app version (for analytics) |
debug |
bool |
false |
Enable debug logging |
Error Handling
The SDK uses a unified Error type:
use ;
async
Error Types
| Error | Description |
|---|---|
InvalidLicenseKey |
The license key is invalid or doesn't exist |
LicenseExpired |
The license has expired |
LicenseSuspended |
The license has been suspended |
DeviceLimitExceeded |
Maximum device limit reached |
NotActivated |
Tried to validate/deactivate without activation |
NetworkError |
Network request failed |
OfflineValidationFailed |
Offline token invalid or expired |
InvalidSignature |
Ed25519 signature verification failed |
Telemetry & Privacy
The SDK collects minimal telemetry to help you understand your user base:
Collected automatically:
- Device ID (hardware-based, stable identifier)
- OS name and version
- Platform (e.g., "macos-arm64")
- SDK version
You can add:
- App version via
config.app_version
Not collected:
- Personal information
- File system data
- Network information beyond API calls
- User behavior or analytics
Disabling Telemetry
let config = Config ;
Examples
DevHeartbeat
Simple demo showing the full license lifecycle:
LICENSESEAT_API_KEY=your_key \
LICENSESEAT_PRODUCT_SLUG=your_product \
LICENSESEAT_LICENSE_KEY=your_license \
Stress Test
Comprehensive test covering 12 scenarios:
Scenarios tested:
- Activation with valid key
- Validation after activation
- Heartbeat functionality
- Telemetry collection
- Entitlement checking
- Non-existent entitlement handling
- Offline configuration
- Event subscription
- Multiple subscriptions
- Concurrent operations
- Full lifecycle
- SDK cloning
Feature Flags
| Feature | Description | Dependencies Added |
|---|---|---|
default |
Uses rustls for TLS and enables offline machine-file support | reqwest/rustls-tls, ed25519-dalek, sha2, base64, aes-gcm |
native-tls |
Use system TLS instead | reqwest/native-tls |
offline |
Enable offline support when using --no-default-features |
ed25519-dalek, sha2, base64, aes-gcm |
API Reference
Full API documentation is available at docs.rs/licenseseat.
Key Types
// Main SDK instance
// Configuration
// License data
// Entitlements
// Events
// Responses
// Errors
pub type Result<T> = Result;
License
MIT License. See LICENSE for details.