This example demonstrates the core Talos client functionality with a realistic license key entry flow - no recompilation required to change license keys.
License keys are NOT compiled into your application. They are entered at runtime:
- User purchases a license → Receives a key like
LIC-A1B2-C3D4-E5F6-G7H8 - User runs your app → App prompts for the license key (first run only)
- App saves the key → Key is stored locally for future runs
- App calls bind() → Associates the key with the user's hardware
- Done → License is active, no recompilation needed
This example supports multiple ways to provide the license key (in order of priority):
- Environment variable:
- PowerShell:
$env:LICENSE_KEY="LIC-XXXX"; cargo run - bash:
LICENSE_KEY=LIC-XXXX cargo run
- PowerShell:
- Saved file: Reads from
license.keyif it exists - User prompt: Asks the user to enter their key (first run)
# In the main Talos directory
cargo run --bin talos_server --features admin-apiPowerShell:
Invoke-RestMethod -Uri http://127.0.0.1:8080/api/v1/licenses -Method POST -ContentType "application/json" -Body '{"org_id": "example-org", "features": ["basic", "export"], "expires_at": "2030-12-31T23:59:59Z"}'curl (bash/WSL):
curl -X POST http://127.0.0.1:8080/api/v1/licenses \
-H "Content-Type: application/json" \
-d '{"org_id": "example-org", "features": ["basic", "export"], "expires_at": "2030-12-31T23:59:59Z"}'Note the license_key from the response (e.g., LIC-A1B2-C3D4-E5F6-G7H8).
Option A: Let it prompt you
cargo run
# Enter your license key when promptedOption B: Environment variable
PowerShell (Windows):
$env:LICENSE_KEY="LIC-A1B2-C3D4-E5F6-G7H8"; cargo runbash (Mac/Linux):
LICENSE_KEY="LIC-A1B2-C3D4-E5F6-G7H8" cargo runOption C: Config file (for subsequent runs)
PowerShell (Windows):
"LIC-A1B2-C3D4-E5F6-G7H8" | Out-File -Encoding ascii license.key
cargo runbash (Mac/Linux):
echo "LIC-A1B2-C3D4-E5F6-G7H8" > license.key
cargo run=== Talos Basic Client Example ===
Using license key from LICENSE_KEY environment variable
Server URL: http://127.0.0.1:8080
License Key: LIC-A1B2-C3D4...
Step 1: Binding license to this machine...
✓ License bound successfully!
License ID: 550e8400-e29b-41d4-a716-446655440000
Features: ["basic", "export"]
Expires: 2030-12-31T23:59:59Z
Step 2: Validating license...
✓ License is valid!
Features: ["basic", "export"]
Step 3: Checking features...
basic - ✓ Enabled
export - ✓ Enabled
premium - ✗ Disabled
analytics - ✗ Disabled
Step 4: Sending heartbeat...
✓ Heartbeat sent!
Server time: 2024-01-15T10:30:00Z
Step 5: Testing offline validation...
✗ Offline validation failed: Grace period expired
(This is expected - see note below)
Step 6: Releasing license...
✓ License released successfully!
The license can now be used on another machine.
=== Example Complete ===
Step 5 (offline validation) will fail for active licenses because offline validation only works when:
- The license is suspended with an explicit grace period
- The admin has set
grace_period_ends_atvia the Admin API
This is by design - the server controls when offline access is permitted. For applications that need offline validation, see the air-gapped example which demonstrates the full workflow including license suspension with a grace period.
To use a different license key:
PowerShell (Windows):
# Delete the saved key
Remove-Item license.key
# Run again - it will prompt for a new key
cargo runbash (Mac/Linux):
# Delete the saved key
rm license.key
# Run again - it will prompt for a new key
cargo runOr use the environment variable to override:
PowerShell (Windows):
$env:LICENSE_KEY="LIC-NEW-KEY-HERE"; cargo runbash (Mac/Linux):
LICENSE_KEY="LIC-NEW-KEY-HERE" cargo runfn get_license_key() -> io::Result<String> {
// 1. Check environment variable
if let Ok(key) = std::env::var("LICENSE_KEY") {
return Ok(key);
}
// 2. Check saved file
if let Ok(key) = std::fs::read_to_string("license.key") {
return Ok(key.trim().to_string());
}
// 3. Prompt user
print!("Enter license key: ");
let mut key = String::new();
io::stdin().read_line(&mut key)?;
// Save for next time
std::fs::write("license.key", key.trim())?;
Ok(key.trim().to_string())
}// License key is a runtime String, NOT a compile-time constant
let license_key = get_license_key()?;
let server_url = std::env::var("SERVER_URL").unwrap_or("http://localhost:8080".into());
let mut license = License::new(license_key, server_url);- Store keys securely: Use OS keychain, encrypted config, or secure storage
- Use environment variables in containers:
LICENSE_KEYenv var works great for Docker - Implement a license dialog: For GUI apps, show a proper dialog on first run
- Handle key changes: Let users update their key without reinstalling
- See the air-gapped example for offline-first applications
- Read the Client Integration Guide for complete documentation