Important
Under active development. Not production-ready.
InferaDB is a Zanzibar-inspired authorization engine. Define permissions as policy-as-code; integrate in a few lines.
- Async-first: Built on Tokio and Tracing
- Compile-time safety: Catch permission model mistakes before production
- Standards-based: AuthZEN compliant with multi-tenant isolation
-
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 authorization question. One line:
if vault.check("user:alice", "edit", "document:readme").await? {
// allow the edit
}Building a share dialog or audit view? List all subjects with access:
let viewers = vault.subjects()
.with_permission("view")
.on_resource("document:readme")
.collect()
.await?;
// ["user:alice", "user:bob", "team:engineering"]Filter a dashboard or search results by accessible resources:
let docs = vault.resources()
.accessible_by("user:alice")
.with_permission("view")
.of_type("document")
.collect()
.await?;When Alice shares a folder with her team, all team members gain access:
vault.relationships()
.write(Relationship::new("folder:designs", "viewer", "team:engineering"))
.await?;Documents inherit their parent 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 edit, delete, and share buttons? Check all permissions in one call:
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, and watch.
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 InferaDB locally, then configure your client:
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_middleware# Setup (one-time)
mise trust && mise install
rustup component add rustfmt clippy
rustup toolchain install nightly --component rustfmt
# Build
cargo build --workspace --all-features
# Run tests
cargo test --lib
# Format and lint
cargo +nightly fmt --all
cargo clippy --workspace --all-targets -- -D warnings
# Generate documentation
cargo doc --workspace --no-deps --open
# Code coverage
cargo llvm-cov --lib --ignore-filename-regex 'proto|inferadb\.authorization\.v1'See CONTRIBUTING.md for development setup and guidelines.
Join us on Discord for questions, discussions, and contributions.
Dual-licensed under MIT or Apache 2.0.
