InferaDB is a distributed, Google Zanzibar‑inspired authorization engine that replaces ad‑hoc database lookups and scattered logic with a unified, millisecond‑latency source of truth. With this SDK, you define permissions as policy‑as‑code and wire up a type‑safe client in just a few lines.
- Rust‑Native & Async: Fully integrated with the ecosystem (Tokio, Tracing) so you don't have to adapt generic policy engines to your runtime.
- Compile‑Time Safety: Catch permission model mistakes in your build pipeline and tests, preventing surprises in production.
- Standards‑Based & Audit‑Ready: Built on AuthZen with automatic multi‑tenant isolation and cryptographically verifiable audit trails out of the box.
-
Sign up for an account at InferaDB and create a new organization and vault.
-
Run the following Cargo command in your project directory:
cargo add inferadb
-
In your project, create and configure a client instance:
use inferadb::prelude::*; #[tokio::main] async fn main() -> Result<(), Error> { let client = Client::builder() .url("https://api.inferadb.com") .credentials(ClientCredentialsConfig { client_id: "my_service".into(), private_key: Ed25519PrivateKey::from_pem_file("private-key.pem")?, }) .build() .await?; let vault = client.organization("org_...").vault("vlt_..."); let allowed = vault.check("user:alice", "view", "document:readme").await?; println!("Allowed: {allowed}"); Ok(()) }
The most common question in any app. One line:
if vault.check("user:alice", "edit", "document:readme").await? {
// allow the edit
}Building a share dialog or audit view? List everyone with access:
let viewers = vault.subjects()
.with_permission("view")
.on_resource("document:readme")
.collect()
.await?;
// ["user:alice", "user:bob", "team:engineering"]Filtering a dashboard or search results by what the user can actually access:
let docs = vault.resources()
.accessible_by("user:alice")
.with_permission("view")
.of_type("document")
.collect()
.await?;When Alice shares a folder with her team, everyone on that team gets access:
vault.relationships()
.write(Relationship::new("folder:designs", "viewer", "team:engineering"))
.await?;Documents inside a folder should inherit the folder's permissions:
vault.relationships()
.write(Relationship::new("document:spec", "parent", "folder:designs"))
.await?;
// Now anyone who can view the folder can view the documentRendering a UI with edit, delete, and share buttons? Check them all in one round-trip:
let [can_edit, can_delete, can_share] = vault.batch_check(&[
("user:alice", "edit", "document:readme"),
("user:alice", "delete", "document:readme"),
("user:alice", "share", "document:readme"),
]).await?[..] else { unreachable!() };let vault = client.organization("org_...").vault("vlt_...");let allowed = vault.check("user:alice", "view", "doc:1").await?;vault.relationships()
.write(Relationship::new("document:readme", "viewer", "user:alice"))
.await?;let docs = vault.resources()
.accessible_by("user:alice")
.with_permission("view")
.collect()
.await?;See the Authorization API Guide for ABAC context, batch checks, explain, simulate, watch, and more.
let org = client.organization("org_...");let vault = org.vaults()
.create(CreateVaultRequest::new("production"))
.await?;vault.schemas().push(r#"
type user {}
type document {
relation viewer: user
permission view = viewer
}
"#).await?;org.members()
.invite(InviteMemberRequest::new("[email protected]", OrgRole::Admin))
.await?;
org.teams()
.create(CreateTeamRequest::new("Engineering"))
.await?;let events = org.audit().list().collect().await?;See the Management API Guide for organizations, API clients, schema versioning, and more.
Deploy a local instance of InferaDB, then configure your client to connect to it.
let client = Client::builder()
.url("http://localhost:8080")
.insecure() // Disables TLS verification for local development
.credentials(BearerCredentialsConfig {
token: "dev-token".into(),
})
.build()
.await?;Use MockClient for unit tests:
use inferadb::testing::{AuthorizationClient, MockClient};
#[tokio::test]
async fn test_authorization() {
let mock = MockClient::builder()
.check("user:alice", "view", "document:readme", true)
.check("user:bob", "delete", "document:readme", false)
.build();
assert!(mock
.check("user:alice", "view", "document:readme")
.await
.unwrap());
}See the Testing Guide for InMemoryClient (full policy evaluation) and integration testing patterns.
- API Reference - Full rustdoc documentation
| Topic | Description |
|---|---|
| Installation | Feature flags, optimized builds, TLS, MSRV |
| Authentication | Client credentials, bearer tokens, key management |
| Authorization API | Permission checks, relationships, lookups, watch |
| Integration Patterns | Axum, Actix-web, GraphQL, gRPC middleware |
| Error Handling | Error types, retries, graceful degradation |
| Testing | MockClient, InMemoryClient, TestVault |
| Schema Design | ReBAC patterns, role hierarchy, anti-patterns |
| Production Checklist | Deployment readiness |
| Troubleshooting | Common issues and solutions |
See docs/README.md for the complete documentation index.
cargo run -p inferadb-examples --bin basic_check
cargo run -p inferadb-examples --bin batch_operations
cargo run -p inferadb-examples --bin axum_middlewareSee CONTRIBUTING.md for development setup and guidelines.
Licensed under the Apache License, Version 2.0. See LICENSE for details.
