Skip to main content

RBAC

Role definition

The [role_definition] section defines RBAC role (inheritance) relationships. Casbin can run several RBAC systems at once: one for users (with role inheritance) and optionally one for resources. Each is independent.

This section is optional; omit it if you are not using RBAC.

[role_definition]
g = _, _
g2 = _, _

Here g and g2 are two role systems; _, _ means each has two sides (e.g. user and role). Use only g for user roles; add g2 when resources have roles too. Examples: rbac_model.conf, rbac_with_resource_roles_model.conf.

User–role (and resource–role) mappings are stored in the policy, for example:

p, data2_admin, data2, read
g, alice, data2_admin

So alice has role data2_admin. Casbin treats all names as strings (user, resource, or role).

Use the role in a matcher:

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

So the request is allowed only if the request subject has the role given in the policy.

note
  1. Casbin only stores and evaluates user–role (and resource–role) mappings; it does not validate that users or roles exist. That is the job of authentication.
  2. Do not reuse the same name for a user and a role (e.g. user alice and role alice), since Casbin cannot tell them apart. Use a prefix (e.g. role_alice) if needed.
  3. Role inheritance is transitive and unbounded: if A has role B and B has role C, then A effectively has role C.
Token name convention

The subject in the policy is usually named sub and listed first. In Go Casbin you can use other names and order; then you must call e.SetFieldIndex("p", constant.SubjectIndex, index) after creating the enforcer so that APIs like DeleteUser use the correct column.

# `subject` here is for sub
[policy_definition]
p = obj, act, subject
e.SetFieldIndex("p", constant.SubjectIndex, 2) // index starts from 0
ok, err := e.DeleteUser("alice") // without SetFieldIndex, it will raise an error

Role hierarchy

Casbin implements RBAC1-style role hierarchy: if alice has role1 and role1 has role2, then alice effectively has role2 and its permissions.

The hierarchy depth is how many levels of inheritance you allow. The default role manager uses a maximum depth of 10 (configurable), so a user can inherit up to 10 levels of roles.

// NewRoleManager is the constructor for creating an instance of the
// default RoleManager implementation.
func NewRoleManager(maxHierarchyLevel int) rbac.RoleManager {
rm := RoleManager{}
rm.allRoles = &sync.Map{}
rm.maxHierarchyLevel = maxHierarchyLevel
rm.hasPattern = false

return &rm
}

Distinguishing users from roles

In Casbin, users and roles are both strings. In flat RBAC (no role hierarchy), GetAllSubjects() and GetAllRoles() return the left and right sides of g rules (often users and roles). With a hierarchy, the same name can appear as both user and role; if your app does not track which is which, use a naming convention (e.g. prefix role::) and check it when interpreting results.

Implicit roles and permissions

Roles and permissions inherited through the hierarchy (not only direct assignments) are called implicit. Use GetImplicitRolesForUser() and GetImplicitPermissionsForUser() to include them; GetRolesForUser() and GetPermissionsForUser() return only direct assignments. See GitHub #137.

Pattern matching in RBAC

See RBAC with pattern.

Role manager

See Role managers for custom role management.