Documentation Index
Fetch the complete documentation index at: https://docs.authforge.cc/llms.txt
Use this file to discover all available pages before exploring further.
Requirements
- Rust 1.70 or later
- Crates used by the SDK:
hmac
sha2
serde
serde_json
ureq
base64
mac_address
hostname
Installation
The crate is published on crates.io/crates/authforge as authforge.
Or set a semver range in Cargo.toml (for example 1.0 for compatible 1.x releases):
[dependencies]
authforge = "1.0"
Git (pre-release)
Path (vendored)
[dependencies]
authforge = { git = "https://github.com/AuthForgeCC/authforge-rust" }
Optional: pin branch, tag, or rev.[dependencies]
authforge = { path = "../authforge-rust" }
Adjust the path to your checkout (for example vendor/authforge-rust).
Quick start
use authforge::{AuthForgeClient, AuthForgeConfig, HeartbeatMode};
fn main() {
let client = AuthForgeClient::new(AuthForgeConfig {
app_id: "your-app-id".into(),
app_secret: "your-app-secret".into(),
public_key: "YOUR_PUBLIC_KEY".into(),
heartbeat_mode: HeartbeatMode::Server,
on_failure: Some(Box::new(|err| {
eprintln!("Auth failed: {}", err);
std::process::exit(1);
})),
..Default::default()
});
match client.login("XXXX-XXXX-XXXX-XXXX") {
Ok(result) => {
println!("Authenticated!");
println!("Session expires at unix time: {}", result.expires_in);
}
Err(err) => {
eprintln!("Login failed: {:?}", err);
std::process::exit(1);
}
}
}
Config struct reference
AuthForgeConfig {
app_id: "your-app-id".into(), // Required
app_secret: "your-app-secret".into(), // Required
public_key: "YOUR_PUBLIC_KEY".into(), // Required - Ed25519 public key from your AuthForge dashboard (base64)
heartbeat_mode: HeartbeatMode::Server, // Local or Server
heartbeat_interval: 900, // Optional, seconds (any value ≥ 1)
api_base_url: "https://auth.authforge.cc".into(), // Optional
on_failure: None, // Optional callback
request_timeout: 15, // Optional, seconds
session_ttl_seconds: None, // Optional - requested session TTL. None = server default (24h). Clamped to [3600, 604800].
hwid_override: None, // Optional - custom identity (for example "tg:123456789")
}
| Field | Type | Default | Description |
|---|
app_id | String | required | Application ID from your AuthForge dashboard |
app_secret | String | required | Application secret from your AuthForge dashboard |
public_key | String | required | Ed25519 public key from your AuthForge dashboard (base64) |
heartbeat_mode | HeartbeatMode | Local | Local or Server heartbeat mode |
heartbeat_interval | u64 | 900 | Seconds between heartbeat checks (any value ≥ 1) |
api_base_url | String | https://auth.authforge.cc | AuthForge API base URL |
on_failure | Option<Box<dyn Fn(&str)+Send+Sync>> | None | Invoked when heartbeat fails |
request_timeout | u64 | 15 | Timeout for API requests |
session_ttl_seconds | Option<u64> | None (server default: 86400) | Requested session token lifetime. Server clamps to [3600, 604800]; preserved across heartbeat refreshes. |
hwid_override | Option<String> | None | Optional custom identity string sent as HWID (for example tg:123456789). |
Validate license (no heartbeat)
validate_license runs the same /auth/validate request and signature checks as login, but does not store a session on the client or start the heartbeat thread. It returns the same LoginResult on success.
match client.validate_license("XXXX-XXXX-XXXX-XXXX") {
Ok(result) => { /* use result.session_token, result.app_variables, … */ }
Err(err) => { /* same AuthForgeError variants as login */ }
}
Billing
- Each successful
login() or validate_license() costs 1 credit (one /auth/validate debit).
- Heartbeats cost 1 credit per 10 successful calls (billed on every 10th heartbeat). Any
heartbeat_interval ≥ 1 is economically safe.
- Revocations take effect on the next heartbeat regardless of interval.
Methods reference
pub fn new(config: AuthForgeConfig) -> Self;
pub fn login(&self, license_key: &str) -> Result<LoginResult, AuthForgeError>;
pub fn validate_license(&self, license_key: &str) -> Result<LoginResult, AuthForgeError>;
pub fn logout(&self);
pub fn is_authenticated(&self) -> bool;
pub fn get_session_data(&self) -> Option<serde_json::Value>;
pub fn get_app_variables(&self) -> Option<std::collections::HashMap<String, serde_json::Value>>;
pub fn get_license_variables(&self) -> Option<std::collections::HashMap<String, serde_json::Value>>;
Error enum reference
AuthForgeError::InvalidApp
AuthForgeError::InvalidKey
AuthForgeError::Expired
AuthForgeError::Revoked
AuthForgeError::HwidMismatch
AuthForgeError::NoCredits
AuthForgeError::Blocked
AuthForgeError::RateLimited // validate only; never returned from heartbeat
AuthForgeError::ReplayDetected // validate only; never returned from heartbeat
AuthForgeError::SignatureMismatch
AuthForgeError::NetworkError(String)
AuthForgeError::Other(String)
Heartbeat modes
// SERVER mode: network heartbeats via /auth/heartbeat
let server_client = AuthForgeClient::new(AuthForgeConfig {
app_id: "...".into(),
app_secret: "...".into(),
public_key: "YOUR_PUBLIC_KEY".into(),
heartbeat_mode: HeartbeatMode::Server,
..Default::default()
});
// LOCAL mode: local expiry checks with no heartbeat network calls
let local_client = AuthForgeClient::new(AuthForgeConfig {
app_id: "...".into(),
app_secret: "...".into(),
public_key: "YOUR_PUBLIC_KEY".into(),
heartbeat_mode: HeartbeatMode::Local,
..Default::default()
});
See Heartbeat Modes for a detailed comparison.