Zum Hauptinhalt springen

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
notiz

Enabling JSON parameter support introduces a performance overhead of approximately 1.1 to 1.5x.

Using ABAC

  1. Reference attributes in the matcher (e.g. r.sub.Role, r.obj.Owner).
  2. Pass struct or class instances (or JSON) into Enforce().
warning

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.

tip

Matchers can reference multiple attributes simultaneously. Example: m = r.sub.Domain == r.obj.Domain.

tip

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