Important
Under active development. Not production-ready.
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("alice@example.com", 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.
Join us on Discord to discuss InferaDB, get help with your projects, and connect with other developers. Whether you have questions, want to share what you're building, or are interested in contributing, we'd love to have you!
Licensed under either of:
at your option.
