Skip to main content

Casbin Concepts

A brief introduction to Casbin concepts used throughout this library. If you are already familiar with Casbin, you can skip this page.

The enforce call​

At its core, Casbin answers one question:

Can subject perform action on object?

enforcer.enforce(subject, object, action)  # returns True or False

This library calls enforcer.enforce(user, *args) where user comes from your user_provider dependency and *args are the arguments you pass to require_permission.

Model and policy​

Casbin uses two files:

Model (model.conf)​

Defines how authorization rules are structured. A typical RBAC model looks like this:

[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act

[role_definition]
g = _, _

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

[matchers]
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act

Policy (policy.csv)​

Defines the actual rules:

# Roles
g, admin, editor
g, editor, viewer

# Permissions
p, viewer, post, read
p, editor, post, write
p, admin, post, delete

Subject, Object, Action​

These map directly to require_permission arguments:

@guard.require_permission("post", "read")
# ^^^^^^ ^^^^^^
# object action
# subject = current user (from user_provider)

The enforcer call becomes:

enforcer.enforce(current_user, "post", "read")

RBAC vs ABAC​

RBAC (Role-Based Access Control) — permissions are assigned to roles, users get roles:

g, alice, admin       # alice has admin role
p, admin, post, write # admin can write posts

ABAC (Attribute-Based Access Control) — permissions are based on attributes of the user or resource:

# matcher in model.conf
m = r.sub.department == r.obj.owner

This library supports both — the model and policy files determine the access control model, not the library itself.

Further reading​