Rust SDK (auris)
The auris crate is the official Rust client library for Auris IAM. It is fully async, built on tokio and reqwest, and provides idiomatic Rust APIs for authentication, user management, and fine-grained authorization.
Edition: 2021
Async runtime: tokio
Dependencies: reqwest, tokio, serde, serde_json
Installation
Add to Cargo.toml:
[dependencies]
auris = "0.1"
tokio = { version = "1", features = ["full"] }AurisClient
AurisClient is the main entry point for end-user authentication flows.
Quick Start
use auris::AurisClient;
#[tokio::main]
async fn main() -> auris::Result<()> {
let client = AurisClient::new("https://auth.yourdomain.com", "your-client-id");
let result = client.login("[email protected]", "password").await?;
println!("Logged in as {}", result.user.email);
println!("Access token: {}", result.access_token);
Ok(())
}login / logout
let result = client.login("[email protected]", "password").await?;
// result.access_token String
// result.refresh_token Option<String>
// result.user UserInfo
client.logout().await?;get_user
Returns the currently authenticated user. Returns None if not authenticated.
if let Some(user) = client.get_user().await? {
println!("{} {} {:?}", user.id, user.email, user.roles);
}get_access_token
let token: Option<String> = client.get_access_token().await;
// Use in Authorization: Bearer <token> headersrefresh_token
let result = client.refresh_token(refresh_token).await?;get_m2m_token
Obtains a machine-to-machine access token via the OAuth2 client_credentials grant. Never call from browser or client-side code.
let token = client.get_m2m_token("client-secret", &["read:users", "manage:roles"]).await?;
// token.access_token String
// token.expires_in u64login_with_magic_link / verify_magic_link
// Send magic link email
client.login_with_magic_link("[email protected]").await?;
// Verify the token from the link URL
let result = client.verify_magic_link("token-from-url").await?;ManagementClient
ManagementClient is for server-side tenant management using M2M credentials.
Only use ManagementClient in server-side code. The client secret must never be exposed to browsers or end users.
use auris::ManagementClient;
let mgmt = ManagementClient::new(
"https://auth.yourdomain.com",
"your-client-id",
"your-client-secret",
).await?;Users
// List users
let users = mgmt.list_users().await?;
// Get a single user
let user = mgmt.get_user("user-id").await?;
// Create a user
let user = mgmt.create_user(serde_json::json!({
"email": "[email protected]",
"name": "New User",
})).await?;
// Delete a user
mgmt.delete_user("user-id").await?;
// Assign roles
mgmt.assign_roles("user-id", &["role-id-1", "role-id-2"]).await?;
// Remove roles
mgmt.remove_roles("user-id", &["role-id-1"]).await?;Organizations
// List organizations
let orgs = mgmt.list_organizations().await?;
// Get an organization
let org = mgmt.get_organization("org-id").await?;
// Create an organization
let org = mgmt.create_organization(serde_json::json!({
"name": "Acme Corp",
})).await?;
// Delete an organization
mgmt.delete_organization("org-id").await?;
// List members
let members = mgmt.list_members("org-id").await?;
// Add a member
mgmt.add_member("org-id", "user-id", "member").await?;
// Remove a member
mgmt.remove_member("org-id", "user-id").await?;Roles
let roles = mgmt.list_roles().await?;FgaClient
FgaClient implements Zanzibar-style fine-grained authorization. Requires the FGA feature to be enabled on your tenant.
use auris::FgaClient;
let fga = FgaClient::new(
"https://auth.yourdomain.com",
"your-client-id",
"your-client-secret",
).await?;check_permission
let allowed = fga.check_permission("user:alice", "read", "document:budget").await?;
println!("Allowed: {}", allowed);check_permissions
let checks = vec![
auris::PermissionCheck {
user: "user:alice".into(),
relation: "read".into(),
object: "document:budget".into(),
},
auris::PermissionCheck {
user: "user:alice".into(),
relation: "write".into(),
object: "document:budget".into(),
},
];
let results = fga.check_permissions(&checks).await?;tuple_write
fga.tuple_write(&[auris::PermissionCheck {
user: "user:bob".into(),
relation: "viewer".into(),
object: "document:report".into(),
}]).await?;Webhook Verification
use auris::verify_webhook_signature;
use axum::{
body::Bytes,
http::{HeaderMap, StatusCode},
};
async fn webhook_handler(headers: HeaderMap, body: Bytes) -> StatusCode {
let signature = headers
.get("X-Auris-Signature")
.and_then(|v| v.to_str().ok())
.unwrap_or("");
if !verify_webhook_signature(&body, signature, "your-webhook-secret") {
return StatusCode::UNAUTHORIZED;
}
// Process webhook event...
StatusCode::OK
}Error Handling
All async methods return auris::Result<T>, which is an alias for Result<T, AurisError>. Use pattern matching to handle specific error variants.
use auris::{AurisClient, AurisError};
match client.login("[email protected]", "wrong-password").await {
Ok(result) => {
println!("Token: {}", result.access_token);
}
Err(AurisError::Http { status, message }) => {
eprintln!("HTTP {status}: {message}");
}
Err(AurisError::Network(e)) => {
eprintln!("Network error: {e}");
}
Err(e) => {
eprintln!("Unexpected error: {e}");
}
}Common error codes:
| Code | Status | Description |
|---|---|---|
invalid_credentials | 401 | Wrong email or password |
invalid_token | 401 | Token is expired or malformed |
permission_denied | 403 | User lacks the required permission |
not_found | 404 | Resource does not exist |
rate_limited | 429 | Too many requests |
Related Pages
- JavaScript SDK — Browser, Node.js, and edge runtimes
- Go SDK — Idiomatic Go bindings
- Python SDK — Python 3.8+ with httpx
- Fine-Grained Authorization — FGA model and tuple management
- Webhooks — Webhook delivery and HMAC verification