pub struct Client { /* private fields */ }Expand description
Truthlinked Authority Fabric API client
Provides type-safe access to the Truthlinked Authority Fabric API with enterprise-grade security and reliability features.
§Security Features
- HTTPS-only communication (HTTP requests are rejected)
- TLS certificate validation (no self-signed certificates)
- License key memory protection (zeroized on drop)
- Safe error handling (no credential leakage)
- Connection pooling with reasonable limits
- Request timeouts to prevent hanging
§Thread Safety
This client is Send + Sync and can be safely shared across threads.
Consider using Arc<Client> for shared access.
§Example
use truthlinked_sdk::Client;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = Client::new(
"https://api.truthlinked.org",
std::env::var("TRUTHLINKED_LICENSE_KEY")?
)?;
let health = client.health().await?;
println!("Server status: {}", health.status);
Ok(())
}Implementations§
Source§impl Client
impl Client
Sourcepub fn new(
base_url: impl Into<String>,
license_key: impl Into<String>,
) -> Result<Self>
pub fn new( base_url: impl Into<String>, license_key: impl Into<String>, ) -> Result<Self>
Creates a new Truthlinked API client
§Arguments
base_url- API base URL (must be HTTPS)license_key- Your Truthlinked license key
§Security Guarantees
- Enforces HTTPS only (HTTP requests are rejected at client creation)
- Uses rustls TLS implementation (no OpenSSL vulnerabilities)
- Validates TLS certificates (rejects self-signed certificates)
- Configures reasonable timeouts (prevents indefinite hanging)
- Enables connection pooling (improves performance and reliability)
§Errors
Returns TruthlinkedError::InvalidRequest if:
- Base URL does not start with “https://”
- HTTP client cannot be configured
§Example
use truthlinked_sdk::Client;
let client = Client::new(
"https://api.truthlinked.org",
"tl_free_..."
)?;Sourcepub async fn health(&self) -> Result<HealthResponse>
pub async fn health(&self) -> Result<HealthResponse>
Performs a health check against the Truthlinked API
This endpoint does not require authentication and can be used to verify that the API is accessible and responding correctly.
§Returns
Ok(HealthResponse)- Server is healthy and respondingErr(TruthlinkedError)- Network error or server unavailable
§Example
let health = client.health().await?;
assert_eq!(health.status, "healthy");Sourcepub async fn exchange_token(
&self,
sso_token: impl Into<String>,
requested_scope: Vec<String>,
nonce: [u8; 32],
channel_binding: [u8; 32],
) -> Result<TokenResponse>
pub async fn exchange_token( &self, sso_token: impl Into<String>, requested_scope: Vec<String>, nonce: [u8; 32], channel_binding: [u8; 32], ) -> Result<TokenResponse>
Exchanges an SSO token for an Authority Fabric token
This operation requires a Professional tier license or higher. The SSO token is validated and, if successful, an AF token is issued with the requested scope (potentially narrowed based on policy).
§Arguments
sso_token- Valid SSO token from your identity providerrequested_scope- List of permissions requested (e.g., [“read:users”])nonce- 32-byte cryptographic nonce (prevents replay attacks)channel_binding- 32-byte channel binding (prevents MITM attacks)
§Security Notes
- Nonce must be cryptographically random and unique per request
- Channel binding should be derived from the TLS channel
- The granted scope may be narrower than requested based on policy
§Errors
Unauthorized- Invalid license key or SSO tokenForbidden- License tier doesn’t support token exchangeInvalidRequest- Malformed request parameters
§Example
use rand::Rng;
let nonce: [u8; 32] = rand::thread_rng().gen();
let channel_binding: [u8; 32] = rand::thread_rng().gen();
let response = client.exchange_token(
"eyJ0eXAiOiJKV1QiLCJhbGc...",
vec!["read:users".to_string()],
nonce,
channel_binding,
).await?;
println!("AF Token: {}", response.af_token);Sourcepub async fn validate_token(
&self,
token_id: impl Into<String>,
) -> Result<ValidateResponse>
pub async fn validate_token( &self, token_id: impl Into<String>, ) -> Result<ValidateResponse>
Validate AF token
Sourcepub async fn get_shadow_decisions(&self) -> Result<Vec<ShadowDecision>>
pub async fn get_shadow_decisions(&self) -> Result<Vec<ShadowDecision>>
Retrieves shadow decisions showing breach prevention activity
Shadow mode runs your IAM decisions through the Authority Fabric policy engine in parallel, identifying cases where IAM would have allowed access but AF would have denied it (indicating a potential security breach).
This endpoint is available to all license tiers.
§Returns
A list of shadow decisions, where each decision represents a divergence
between IAM and AF policy evaluation. Decisions with breach_prevented: true
indicate cases where AF would have prevented a security breach.
§Example
let decisions = client.get_shadow_decisions().await?;
let breaches_prevented = decisions.iter()
.filter(|d| d.breach_prevented)
.count();
println!("Breaches prevented: {}", breaches_prevented);Sourcepub async fn replay_iam_logs(
&self,
logs: Vec<String>,
adapter: impl Into<String>,
) -> Result<ReplayResponse>
pub async fn replay_iam_logs( &self, logs: Vec<String>, adapter: impl Into<String>, ) -> Result<ReplayResponse>
Replay IAM logs through AF policy engine
Sourcepub async fn get_sox_report(&self) -> Result<SoxReport>
pub async fn get_sox_report(&self) -> Result<SoxReport>
Get SOX compliance report
Sourcepub async fn get_pci_report(&self) -> Result<PciReport>
pub async fn get_pci_report(&self) -> Result<PciReport>
Get PCI-DSS compliance report
Sourcepub async fn get_audit_logs(&self) -> Result<Vec<AuditLog>>
pub async fn get_audit_logs(&self) -> Result<Vec<AuditLog>>
Get audit logs
Sourcepub async fn get_usage(&self) -> Result<UsageResponse>
pub async fn get_usage(&self) -> Result<UsageResponse>
Get usage statistics
Sourcepub async fn submit_witness(
&self,
submission: WitnessSubmission,
) -> Result<WitnessEvent>
pub async fn submit_witness( &self, submission: WitnessSubmission, ) -> Result<WitnessEvent>
Submit event to witness chain
Sourcepub async fn get_witness_event(
&self,
sequence: u64,
include_proof: bool,
) -> Result<WitnessEvent>
pub async fn get_witness_event( &self, sequence: u64, include_proof: bool, ) -> Result<WitnessEvent>
Get witness event by sequence number
Sourcepub async fn get_latest_sth(&self) -> Result<SignedTreeHead>
pub async fn get_latest_sth(&self) -> Result<SignedTreeHead>
Get latest signed tree head
Sourcepub async fn get_sth(&self, tree_size: u64) -> Result<SignedTreeHead>
pub async fn get_sth(&self, tree_size: u64) -> Result<SignedTreeHead>
Get signed tree head at specific tree size
Sourcepub async fn export_witness_chain(
&self,
start_seq: Option<u64>,
end_seq: Option<u64>,
) -> Result<Vec<u8>>
pub async fn export_witness_chain( &self, start_seq: Option<u64>, end_seq: Option<u64>, ) -> Result<Vec<u8>>
Export witness chain segment
Sourcepub async fn witness_health(&self) -> Result<WitnessHealthResponse>
pub async fn witness_health(&self) -> Result<WitnessHealthResponse>
Check witness chain health