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.