Rust SDK
Quickstart for the Lattix Rust SDK — the canonical core for embedded enforcement, exposing the full /v1/sdk/* control-plane surface.
The Rust SDK is the canonical core of the Lattix SDK family. It owns the HTTP behavior, typed request/response models, and the C ABI consumed by the Go and Python bindings. Applications can use it directly, or they can use a higher-level language binding that wraps it.
This page is a conceptual quickstart. Full API reference — every public type, every field, every example — lives with the crate itself at docs.rs/sdk-rust and in the crate's README.md.
Install
cargo add sdk-rustThe crate publishes to crates.io. Tagged GitHub releases additionally attach version-matched native artifacts (Linux x86_64, macOS x86_64, macOS aarch64, Windows x86_64) for non-Cargo consumers and the Go/Python bindings.
Construct a client
The SDK uses a builder pattern rooted at Client::builder(base_url).
use sdk_rust::Client;
let client = Client::builder("https://api.lattix.io")
.with_bearer_token("<your-token>")
.with_tenant_id("<your-tenant>")
.with_user_id("<your-user>")
.build()?;Supported builder options:
| Method | Purpose |
|---|---|
.with_bearer_token(token) | Attach a pre-issued bearer token to every request. |
.with_client_id(id) / .with_client_secret(secret) | Use SDK client credentials; the SDK will exchange them for a short-lived token on first use and cache it. |
.with_tenant_id(tenant) | Attach the tenant identity for this client instance. Required in client-credentials mode. |
.with_user_id(user) | Attach the user/principal identity (used in trusted-headers deployments). |
.with_timeout_secs(n) | Set the HTTP request timeout. |
.with_token_exchange_path(path) | Override the default session-exchange endpoint path. |
.with_requested_scopes(scopes) | Request specific scopes during session exchange. |
.with_header(name, value) | Attach an arbitrary header to every request. |
A built client is thread-safe and reusable across operations.
Make a call
Every operation on the Client is a blocking method that returns Result<T, SdkError>.
use sdk_rust::{
ArtifactProfile, ProtectionOperation, ResourceDescriptor, SdkProtectionPlanRequest,
WorkloadDescriptor,
};
use std::collections::BTreeMap;
// 1. Discovery: confirm connectivity and capabilities.
let bootstrap = client.bootstrap()?;
println!("enforcement model: {}", bootstrap.enforcement_model);
// 2. Metadata-only planning: ask the platform for a protection plan.
let plan = client.protection_plan(&SdkProtectionPlanRequest {
operation: ProtectionOperation::Protect,
workload: WorkloadDescriptor {
application: "example-app".to_string(),
environment: Some("prod".to_string()),
component: Some("ingest".to_string()),
},
resource: ResourceDescriptor {
kind: "document".to_string(),
id: Some("doc-123".to_string()),
mime_type: Some("application/pdf".to_string()),
},
preferred_artifact_profile: Some(ArtifactProfile::Tdf),
content_digest: Some("sha256:...".to_string()),
content_size_bytes: Some(1024),
purpose: Some("store".to_string()),
labels: vec!["confidential".to_string()],
attributes: BTreeMap::new(),
})?;
// 3. Use the plan to enforce locally.
if plan.decision.allow && plan.execution.protect_locally {
// ... perform local protection using the indicated artifact profile
}The SDK returns a SdkProtectionPlanResponse whose execution block tells the caller how to protect the object locally. The platform does not receive plaintext at any point.
The eight operations
Every method on Client maps to a single /v1/sdk/* route.
client.capabilities()?; // GET /v1/sdk/capabilities
client.whoami()?; // GET /v1/sdk/whoami
client.bootstrap()?; // GET /v1/sdk/bootstrap
client.exchange_session()?; // POST /v1/sdk/session (client-credentials mode only)
client.protection_plan(&req)?; // POST /v1/sdk/protection-plan
client.policy_resolve(&req)?; // POST /v1/sdk/policy-resolve
client.key_access_plan(&req)?; // POST /v1/sdk/key-access-plan
client.artifact_register(&req)?; // POST /v1/sdk/artifact-register
client.evidence(&req)?; // POST /v1/sdk/evidenceSee Platform API → Endpoints for the shape of each request and response.
Errors
The single public error type is SdkError, a Debug + Display + std::error::Error enum. Callers typically match on:
| Variant | When |
|---|---|
SdkError::InvalidInput | Builder misconfiguration or a bad request field (client-side). |
SdkError::Connection | Network-level failure reaching the platform. |
SdkError::Server | The platform returned a non-success HTTP status. |
SdkError::Serialization | Request could not be serialized or response could not be decoded. |
SdkError::Io | Underlying I/O error (rare in normal flows). |
Using the native library outside Cargo
Because the crate builds as rlib, cdylib, and staticlib, the same native library can be consumed from any language that can call a C ABI. The canonical header is published at include/lattix_sdk.h in the crate and in each release bundle.
The C ABI contract:
- All exported functions use UTF-8 JSON payloads and JSON string responses.
- Strings returned by the library must be released with
lattix_sdk_string_free(...). - Client handles returned by
lattix_sdk_client_new(...)must be released withlattix_sdk_client_free(...). - Null returns indicate failure; call
lattix_sdk_last_error_message()for a thread-local error string.
The Go and Python bindings in this SDK family are built against that same ABI.
Relationship to other pages
- SDKs overview — the SDK family at a glance.
- Platform API — the HTTP contract the Rust SDK speaks.
- Zero Trust Fabric — where the SDK sits in the broader architecture.
SDKs
The Lattix SDK family — Rust, Go, and Python libraries for embedded enforcement against the platform control plane. Metadata-only, consistent surface across languages.
Go SDK
Quickstart for the Lattix Go SDK — a thin typed wrapper over the Rust core, exposing the /v1/sdk/* control-plane surface with a Go-idiomatic API.