Casbin

Casbin

  • Docs
  • API
  • Editor
  • IDE Plugins
  • Single Sign-On (SSO)
  • Forum
  • Help
  • Blog
  • Pricing
  • Contact Sales
  • Languages iconEnglish
    • 中文
    • 한국어
    • Русский
    • Français
    • Deutsch
    • 日本語
    • Help Translate
  • GitHub

›The Basics

The Basics

  • Overview
  • Get Started
  • How it Works
  • Tutorials

Model

  • Supported Models
  • Syntax for Models
  • Effector
  • Function
  • RBAC
  • RBAC with Pattern
  • RBAC with Domains
  • Casbin RBAC v.s. RBAC96
  • ABAC
  • Priority Model
  • Super Admin

Storage

  • Model Storage
  • Policy Storage
  • Policy Subset Loading

Extensions

  • Enforcers
  • Adapters
  • Watchers
  • Dispatchers
  • Role Managers
  • Middlewares
  • GraphQL Middlewares
  • Cloud Native Middlewares

API

  • API Overview
  • Management API
  • RBAC API
  • RBAC with Domains API
  • RoleManager API
  • Data Permissions

Advanced Usage

  • Multi-threading
  • Benchmarks
  • Performance Optimization
  • Authorization of Kubernetes
  • Authorization of Service Mesh through Envoy

Management

  • Admin Portal
  • Casbin Service
  • Log & Error Handling
  • Frontend Usage

Editor

  • Online Editor
  • IDE Plugins

More

  • Our Adopters
  • Contributing
  • Privacy Policy
  • Terms of Service
Edit

Get Started

Installation

Go
Java
Node.js
PHP
Python
.NET
Rust
Delphi
Lua
go get github.com/casbin/casbin/v2

For Maven:

<!-- https://mvnrepository.com/artifact/org.casbin/jcasbin -->
<dependency>
<groupId>org.casbin</groupId>
<artifactId>jcasbin</artifactId>
<version>1.x.y</version>
</dependency>
# NPM
npm install casbin --save

# Yarn
yarn add casbin

Require this package in the composer.json of your project. This will download the package:

composer require casbin/casbin
pip install casbin
dotnet add package Casbin.NET
cargo install cargo-edit
cargo add casbin

// If you use async-std as async executor
cargo add async-std

// If you use tokio as async executor
cargo add tokio // make sure you activate its `macros` feature

Casbin4D comes in a package (currently for Delphi 10.3 Rio) and you can install it in the IDE. However, there are no visual components which means that you can use the units independently of packages. Just import the units in your project (assuming you do not mind the number of them).

luarocks install casbin  

If report Error: Your user does not have write permissions in /usr/local/lib/luarocks/rocks -- you may want to run as a privileged user or use your local tree with --local. you can add --local behind your command like this to fix:

luarocks install casbin  --local

New a Casbin enforcer

Casbin uses configuration files to set the access control model.

It has two configuration files, model.conf and policy.csv. Among them, model.conf stores our access model, and policy.csv stores our specific user permission configuration. The use of Casbin is very refined. Basically, we just need one main structure: enforcer. When constructing this structure, model.conf and policy.csv will be loaded.

In another word, to new a Casbin enforcer, you must provide a Model and an Adapter.

Casbin has a FileAdapter, see Adapter from more Adapter.

  • Use the Model file and default FileAdapter:
Go
Java
Node.js
PHP
Python
.NET
Delphi
Rust
Lua
import "github.com/casbin/casbin/v2"

e, err := casbin.NewEnforcer("path/to/model.conf", "path/to/policy.csv")
import org.casbin.jcasbin.main.Enforcer;

Enforcer e = new Enforcer("path/to/model.conf", "path/to/policy.csv");
import { newEnforcer } from 'casbin';

const e = await newEnforcer('path/to/model.conf', 'path/to/policy.csv');
require_once './vendor/autoload.php';

use Casbin\Enforcer;

$e = new Enforcer("path/to/model.conf", "path/to/policy.csv");
import casbin

e = casbin.Enforcer("path/to/model.conf", "path/to/policy.csv")
using NetCasbin; 

var e = new Enforcer("path/to/model.conf", "path/to/policy.csv");
var
casbin: ICasbin;
begin
casbin := TCasbin.Create('path/to/model.conf', 'path/to/policy.csv');
...
end
use casbin::prelude::*;

// If you use async_td as async executor
#[cfg(feature = "runtime-async-std")]
#[async_std::main]
async fn main() -> Result<()> {
let mut e = Enforcer::new("path/to/model.conf", "path/to/policy.csv").await?;
Ok(())
}

// If you use tokio as async executor
#[cfg(feature = "runtime-tokio")]
#[tokio::main]
async fn main() -> Result<()> {
let mut e = Enforcer::new("path/to/model.conf", "path/to/policy.csv").await?;
Ok(())
}
local Enforcer = require("casbin")
local e = Enforcer:new("path/to/model.conf", "path/to/policy.csv") -- The Casbin Enforcer
  • Use the Model text with other Adapter:
Go
Python
import (
"log"

"github.com/casbin/casbin/v2"
"github.com/casbin/casbin/v2/model"
xormadapter "github.com/casbin/xorm-adapter/v2"
_ "github.com/go-sql-driver/mysql"
)

// Initialize a Xorm adapter with MySQL database.
a, err := xormadapter.NewAdapter("mysql", "mysql_username:mysql_password@tcp(127.0.0.1:3306)/casbin")
if err != nil {
log.Fatalf("error: adapter: %s", err)
}

m, err := model.NewModelFromString(`
[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
`
)
if err != nil {
log.Fatalf("error: model: %s", err)
}

e, err := casbin.NewEnforcer(m, a)
if err != nil {
log.Fatalf("error: enforcer: %s", err)
}
import casbin
import casbin_sqlalchemy_adapter


# Use SQLAlchemy Casbin adapter with SQLLite DB
adapter = casbin_sqlalchemy_adapter.Adapter('sqlite:///test.db')

# Create a config model policy
with open("rbac_example_model.conf", "w") as f:
f.write("""
[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
"""
)

# Create enforcer from adapter and config policy
e = casbin.Enforcer('rbac_example_model.conf', adapter)

Check permissions

Add an enforcement hook into your code right before the access happens:

Go
Java
Node.js
PHP
Python
.NET
Delphi
Rust
Lua
sub := "alice" // the user that wants to access a resource.
obj := "data1" // the resource that is going to be accessed.
act := "read" // the operation that the user performs on the resource.

ok, err := e.Enforce(sub, obj, act)

if err != nil {
// handle err
}

if ok == true {
// permit alice to read data1
} else {
// deny the request, show an error
}

// You could use BatchEnforce() to enforce some requests in batches.
// This method returns a bool slice, and this slice's index corresponds to the row index of the two-dimensional array.
// e.g. results[0] is the result of {"alice", "data1", "read"}
results, err := e.BatchEnforce([][]interface{}{{"alice", "data1", "read"}, {"bob", "data2", "write"}, {"jack", "data3", "read"}})
String sub = "alice"; // the user that wants to access a resource.
String obj = "data1"; // the resource that is going to be accessed.
String act = "read"; // the operation that the user performs on the resource.

if (e.enforce(sub, obj, act) == true) {
// permit alice to read data1
} else {
// deny the request, show an error
}
const sub = 'alice'; // the user that wants to access a resource.
const obj = 'data1'; // the resource that is going to be accessed.
const act = 'read'; // the operation that the user performs on the resource.

if ((await e.enforce(sub, obj, act)) === true) {
// permit alice to read data1
} else {
// deny the request, show an error
}
$sub = "alice"; // the user that wants to access a resource.
$obj = "data1"; // the resource that is going to be accessed.
$act = "read"; // the operation that the user performs on the resource.

if ($e->enforce($sub, $obj, $act) === true) {
// permit alice to read data1
} else {
// deny the request, show an error
}
sub = "alice"  # the user that wants to access a resource.
obj = "data1" # the resource that is going to be accessed.
act = "read" # the operation that the user performs on the resource.

if e.enforce(sub, obj, act):
# permit alice to read data1
pass
else:
# deny the request, show an error
pass
var sub = "alice";  # the user that wants to access a resource.
var obj = "data1"; # the resource that is going to be accessed.
var act = "read"; # the operation that the user performs on the resource.

if (await e.EnforceAsync(sub, obj, act))
{
// permit alice to read data1
}
else
{
// deny the request, show an error
}
if casbin.enforce(['alice,data1,read']) then
// Alice is super happy as she can read data1
else
// Alice is sad
  let sub = "alice"; // the user that wants to access a resource.
let obj = "data1"; // the resource that is going to be accessed.
let act = "read"; // the operation that the user performs on the resource.

if e.enforce((sub, obj, act)).await? {
// permit alice to read data1
} else {
// error occurs
}
if e:enforce("alice", "data1", "read") then
-- permit alice to read data1
else
-- deny the request, show an error
end

Casbin also provides API for permission management at run-time. For example, You can get all the roles assigned to a user as below:

Go
Java
Node.js
PHP
Python
.NET
Delphi
Rust
Lua
roles, err := e.GetRolesForUser("alice")
Roles roles = e.getRolesForUser("alice");
const roles = await e.getRolesForUser('alice');
$roles = $e->getRolesForUser("alice");
roles = e.get_roles_for_user("alice")
var roles = e.GetRolesForUser("alice");
roles = e.rolesForEntity("alice")
let roles = e.get_roles_for_user("alice");
local roles = e:GetRolesForUser("alice")

See Management API and RBAC API for more usage.

Please refer to the test cases for more usage.

Last updated on 11/28/2022
← OverviewHow it Works →
  • Installation
  • New a Casbin enforcer
    • Check permissions
Casbin
Docs
Getting StartedManagement APIRBAC APIMiddlewares
Community
Who's using Casbin?Stack Overflow
Casbin          jCasbin
Node-Casbin   PHP-CasbinPyCasbin          Casbin.NETCasbin-CPP        Casbin-RS
Follow @casbinHQ
Copyright © 2022 Casbin Organization