surreal-casbin-adapter 3.0.5

A SurrealDB adapter for casbin-rs - an authorization library that supports access control models like ACL, RBAC, ABAC and more
Documentation

SurrealDB Adapter for Casbin

Crates.io Documentation License

A SurrealDB adapter for casbin-rs, an authorization library that supports access control models like ACL, RBAC, ABAC for Rust projects.

Installation

Add this to your Cargo.toml:

[dependencies]
surreal-casbin-adapter = "3.0"
casbin = "2.20"
surrealdb = "3.0"

Quick Start

1. Create an adapter and enforcer

use surreal_casbin_adapter::SurrealAdapter;
use casbin::prelude::*;
use surrealdb::engine::any::connect;
use surrealdb::opt::auth::Root;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Connect to SurrealDB
    let db = connect("ws://127.0.0.1:8000").await?;

    // Sign in
    db.signin(Root {
        username: "root".to_string(),
        password: "secret".to_string(),
    }).await?;

    // Select namespace and database
    db.use_ns("test").use_db("test").await?;

    // Create the adapter and table
    let adapter = SurrealAdapter::new(db);
    adapter.create_table().await?;

    // Create the enforcer with your model
    let model = DefaultModel::from_file("model.conf").await?;
    let mut enforcer = Enforcer::new(model, adapter).await?;

    // Add a policy
    enforcer.add_policy(vec!["alice".into(), "data1".into(), "read".into()]).await?;

    // Check permissions
    let allowed = enforcer.enforce(("alice", "data1", "read"))?;
    println!("Alice can read data1: {}", allowed);

    Ok(())
}

2. Define your Casbin model

Create a model.conf file with your authorization model:

[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act

Advanced Usage

RBAC with Domains

For multi-tenant applications with role-based access control:

[request_definition]
r = sub, dom, obj, act

[policy_definition]
p = sub, dom, obj, act

[role_definition]
g = _, _, _

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
m = g(r.sub, p.sub, r.dom) && r.dom == p.dom && r.obj == p.obj && r.act == p.act
// Add role assignment
enforcer.add_grouping_policy(vec!["alice".into(), "admin".into(), "org1".into()]).await?;

// Add permission for role
enforcer.add_policy(vec!["admin".into(), "org1".into(), "data".into(), "write".into()]).await?;

// Check permission
let allowed = enforcer.enforce(("alice", "org1", "data", "write"))?;

Custom Table Name

By default the adapter uses the casbin_rule table. You can customize it:

let adapter = SurrealAdapter::with_table(db, "my_permissions");
adapter.create_table().await?;

Filtered Policy Loading

Load only specific policies to reduce memory usage:

use casbin::Filter;

let filter = Filter {
    p: vec!["alice"],
    g: vec![],
};

enforcer.load_filtered_policy(filter).await?;

Examples

See examples/ for more details.