04

Decide

rust
typescript

Decide is a local-first and scriptable permission engine built in Rust available to use in both Rust (crates.io) and JS/TS (NPM).

The Reason

I was wondering about role-based and attribute-based access controls and how big systems managed permissions. While exploring these, I decided to dive deeper by building a small lightweight permission engine myself.

What It Does

Example (JS/TS)

import { Decide } from "decide-core/core";

const decide = new Decide({
  editor: {
    name: "editor",
    permissions: [
      { action: "edit_post", condition: "user_id == resource_owner" }
    ]
  }
});

const canEdit = decide.can({
    id: "123",
    roles: ["editor"]
}, "edit_post", {
    owner_id: "123",
    resource_name: "post-123",
    resource_type: "post"
});

console.log(canEdit);  // true

Example (Rust)

use decide_core::types::*;
use decide_core::evaluator::Decide;

fn main() {
    let user = User {
        id: "123".to_string(),
        roles: vec!["editor".to_string()]
    };

    let resource = Resource {
        owner_id: "123".to_string(),
        resource_name: "post-123".to_string(),
        resource_type: "post".to_string()
    };

    let decide = Decide::default().unwrap();
    let result = match decide.can(&user, "edit_post", &resource) {
        Ok(res) => res,
        Err(_) => false,
    };

    println!("Can edit: {}", result);  // true
}

Technical Design

Challenges

Links

GitHub

Packages

Images

JavaScript: Javascript code

Rust: Rust code

JSON (role definitions): JSON role definitions