Ana içeriğe atla

What is ABAC? Attribute-Based Access Control with Examples

What is ABAC?​

Attribute-based access control (ABAC) grants or denies a request by evaluating attributes against rules, instead of looking up who the user is or which role they hold. NIST, which published the reference definition in SP 800-162, groups the inputs into four kinds:

Attributes ofExamples
The subject (user or service)department, clearance level, employment type, age
The object (resource)owner, department, classification, status
The actionread, edit, approve, delete
The environmenttime of day, IP address or network, device, location

A rule is a condition over these attributes, for example "a user may read a document if they are in the same department as the document, during business hours". Because the rule refers to attributes rather than to named users or roles, new users and new documents are covered without adding any rule.

Casbin keeps ABAC simple: you pass structs or objects into Enforce() and reference their fields in the matcher. Complete applications are in the ABAC tutorials for Go, Node.js with Express, and Python with Flask.

ABAC vs RBAC​

RBAC decides on the user's roles: "editors may edit documents". ABAC decides on attributes: "the owner may edit the document". Roles are easy to audit, because you can list what a role allows and who holds it; attributes express rules about specific records and context, such as ownership, department or time, which roles alone cannot express without creating one role per record. Most applications combine them: roles decide which features a user can reach, and attribute conditions narrow that down to the records they may touch. Choosing an access control model compares ACL, RBAC, ABAC and ReBAC on one example and shows how to combine RBAC with ABAC in a single Casbin model.

Strengths and weaknesses​

  • Good at: ownership ("only their own"), context (business hours, office network), and data that carries its own labels (department, region, sensitivity). One rule can replace many role grants.
  • Weak at: auditing. "Who can read this document?" has no direct answer; you have to evaluate the rule against every user. Rules also need the attributes at hand, so the application usually loads the record before the check.

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
not

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

Environment attributes​

The request can carry more than sub, obj and act. Add a field for the environment and pass it to Enforce() like any other object. This model lets the owner edit their document at any time, and lets people from the same department read it between 9:00 and 18:00:

[request_definition]
r = sub, obj, act, env

[policy_definition]
p = sub, obj, act

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

[matchers]
m = r.sub.Name == r.obj.Owner || (r.act == "read" && r.sub.Department == r.obj.Department && r.env.Hour >= 9 && r.env.Hour < 18)
type User struct{ Name, Department string }
type Doc struct{ Name, Owner, Department string }
type Env struct{ Hour int }

doc := Doc{Name: "design.md", Owner: "alice", Department: "design"}
bob := User{Name: "bob", Department: "design"}

ok, _ := e.Enforce(bob, doc, "read", Env{Hour: 10}) // true
ok, _ = e.Enforce(bob, doc, "read", Env{Hour: 22}) // false: outside business hours
ok, _ = e.Enforce(bob, doc, "edit", Env{Hour: 10}) // false: bob is not the owner

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.

ipucu

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

ipucu

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

FAQ​

Is ABAC better than RBAC? Neither is better in general. ABAC expresses finer rules; RBAC is easier to review. Start with roles and add attribute conditions where roles stop fitting, such as ownership or time windows.

What is the difference between ABAC and PBAC? ABAC says what decisions are based on (attributes). PBAC says how the rules are managed: as policy data evaluated at run time. The eval() pattern above is both: attribute conditions stored as policy.

Is ABAC the same as XACML? No. XACML is an OASIS standard language for writing ABAC policies. Casbin does not use XACML; rules are written in the model's matcher or stored as policy rows.

Can I try ABAC without writing code? Yes. Pick an ABAC example in the online editor and edit the matcher and the request.

Comments are powered by giscus and GitHub Discussions. They load from giscus.app and GitHub only after you click the button below.