ABAC
What is ABAC?
Attribute-Based Access Control (ABAC) decides access by evaluating attributes of the subject, object, and action (e.g. resource.Owner, user.Role), not just by identity strings. Casbin keeps this simple: you pass structs or objects into Enforce() and reference their fields in the matcher.
Minimal example:
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = r.sub == r.obj.Owner
So r.obj must be an object with an Owner field; Casbin reads it via reflection. In Go you might define:
type testResource struct {
Name string
Owner string
}
You can also pass JSON strings; enable JSON handling and Casbin will parse them:
e, _ := NewEnforcer("examples/abac_model.conf")
e.EnableAcceptJsonRequest(true)
data1Json := `{ "Name": "data1", "Owner": "bob"}`
ok, err := e.Enforce("alice", data1Json, "read")
if err != nil {
// Handle JSON parsing errors
fmt.Printf("Enforcement failed: %v\n", err)
return
}
When enabled, any parameter that starts with { or [ is parsed as JSON. Invalid JSON produces a clear error; other strings are left as-is.
// Valid JSON - automatically parsed
validJSON := `{"Name": "alice", "Age": 25}`
ok, err := e.Enforce(validJSON, "data1", "read") // Works correctly
// Invalid JSON - returns descriptive error
invalidJSON := `{"Name": "alice",}` // Trailing comma is invalid in JSON
ok, err := e.Enforce(invalidJSON, "data1", "read")
// Returns: "failed to parse JSON parameter at index 0: ..."
// Plain string - no parsing attempted
plainString := "alice"
ok, err := e.Enforce(plainString, "data1", "read") // Treated as plain string
Enabling JSON parameter support introduces a performance overhead of approximately 1.1 to 1.5x.
Using ABAC
- Reference attributes in the matcher (e.g.
r.sub.Role,r.obj.Owner). - Pass struct or class instances (or JSON) into
Enforce().
ABAC attribute access works only for request elements (r.sub, r.obj, r.act). Policy elements like p.sub cannot use ABAC since policies cannot store struct or class definitions.
Matchers can reference multiple attributes simultaneously. Example: m = r.sub.Domain == r.obj.Domain.
When policies require commas that would conflict with CSV parsing, wrap the expression in quotation marks. Example: "keyMatch("bob", r.sub.Role)" prevents unwanted splitting.
Complex rules with eval()
For more complex conditions, put expressions in policy and evaluate them with eval() so the model stays small and policies stay flexible.
Model configuration with eval():
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub_rule, obj, act
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = eval(p.sub_rule) && r.obj == p.obj && r.act == p.act
p.sub_rule is an expression over request attributes, evaluated at enforce time. Example policy:
p, r.sub.Age > 18, /data1, read
p, r.sub.Age < 60, /data2, write