Install
The Rust SDK licenses native apps, CLIs, and daemons with online activation and offline Ed25519 lease verification. It’s synchronous and runtime-free — no async/Tokio — and verifies licenses identically to the Swift and JavaScript SDKs (proven by cross-SDK conformance vectors).
Install
Section titled “Install”cargo add keylightInitialise
Section titled “Initialise”Fetch the tenant’s trusted keyset so leases verify offline, then build the client. The third argument to builder is your tenant SDK key (sdk_live_…, from the Keylight dashboard) — it’s required and sent as the X-Keylight-SDK-Key header on every call.
use keylight::{Keylight, KeylightConfig};
let mut cfg = KeylightConfig::builder("your-tenant", "your-product", "sdk_live_…") .key_prefix("PROD") // optional client-side key-format check .max_offline_days(7) // optional offline grace window .app_version(env!("CARGO_PKG_VERSION")) // report app version on every call + beacon .build();
// Pull the tenant's trusted Ed25519 keyset (or pin keys with .trusted_key(...)).if let Some((_, keys)) = keylight::keyset::fetch_keyset( &keylight::http::ureq_transport::UreqTransport::default(), &cfg.base_url, &cfg.tenant_id,) { cfg.trusted_keys.extend(keys);}
let kl = Keylight::new(cfg)?;Activate and gate features
Section titled “Activate and gate features”// Activate a license key (online). The returned lease is Ed25519-verified// before anything is persisted.let res = kl.activate("USER-LICENSE-KEY")?;println!("activated: {}", res.activated);
// Gate features on entitlements — works offline from the cached lease.if kl.has_entitlement("pro") { // unlock pro features}
// Release the seat when uninstalling / switching devices.kl.deactivate()?;The API is synchronous — no .await, no async runtime to set up. You drive checks on launch and on events with kl.check_on_launch() and kl.refresh_if_needed().
Dashboard-owned settings
Section titled “Dashboard-owned settings”The Trial length and Free tier set in the dashboard are the values that apply; what you compile in is the seed a fresh install uses first. Read what is in force with kl.effective_trial_duration_days() and kl.effective_free_tier_enabled(); kl.fetch_config() asks the server now instead of waiting for the next validate or beacon.
To verify that those settings really came from your dashboard, pin your key and turn on the check (0.6.0+):
let cfg = KeylightConfig::builder("your-tenant", "your-product", "sdk_live_…") .trusted_key("k1", "<raw ed25519 public key, base64>") .require_signed_config(true) .build();Leave it off until your app has a trial length set in the dashboard. That is what makes Keylight sign an app’s settings; with the switch on, an unsigned app rejects every legitimate response and stays on the value you compiled in. Once it is on, settings that do not verify against the keys you compiled in are never cached, on every route they arrive on. Pin the key in your build rather than fetching it: a keyset fetched over the same connection can be forged by the same attacker. See Verify the signature.
After a purchase
Section titled “After a purchase”Payment webhooks can lag the checkout redirect. refresh_after_upgrade polls validate briefly and returns true as soon as the entitlements or state change, false on timeout or when no license is stored. It blocks for up to timeout, so call it from a background thread:
use std::time::Duration;std::thread::spawn(move || { let changed = kl.refresh_after_upgrade(Duration::from_secs(30), Duration::from_secs(2));});Tauri apps
Section titled “Tauri apps”The SDK ships a first-party Tauri v2 plugin (Rust side) plus typed JS bindings:
cargo add tauri-plugin-keylight # Rust sidenpm add tauri-plugin-keylight-api # JavaScript sideRegister it with a prebuilt KeylightConfig:
use keylight::KeylightConfig;
fn main() { let cfg = KeylightConfig::builder("your-tenant", "your-product", "sdk_live_…") .app_version(env!("CARGO_PKG_VERSION")) .build(); tauri::Builder::default() .plugin(tauri_plugin_keylight::init(cfg)) .run(tauri::generate_context!()) .expect("error while running tauri application");}Grant the plugin’s default permissions in your capability file:
{ "permissions": ["keylight:default"]}keylight:default allows activate, validate, has_entitlement, active_revalidate and refresh_after_upgrade. The JS bindings expose refreshAfterUpgrade() for the post-checkout case; since 0.6.1 every command that touches the network runs off the main thread, so awaiting it never freezes the window.
- Offline verification — verify a signed lease with no network round-trip.
keylighton crates.io · docs.rs · GitHub