Ana içeriğe atla

RBAC with Domains

Role definition with domains

In Casbin, roles can be domain-scoped: the same user can have different roles in different domains (tenants). That fits multi-tenant and cloud systems where one user works in many tenants.

Use a role definition with three elements; the third is the domain:

[role_definition]
g = _, _, _

The third field is the domain. Example policy:

p, admin, tenant1, data1, read
p, admin, tenant2, data2, read

g, alice, admin, tenant1
g, alice, user, tenant2

So: admin in tenant1 can read data1. Alice is admin in tenant1 and user in tenant2; she can read data1 but not data2 (only admin in tenant2 can read data2).

Matcher: include the domain in g and require it to match:

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

Custom domain token name

By convention the domain is named dom, but you can use any name (tenant, workspace, etc.) in the request and policy definitions:

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

[policy_definition]
p = sub, tenant, obj, act

[role_definition]
g = _, _, _

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

With pattern matching (e.g. keyMatch) for domains, Casbin infers the domain token from the model as long as the domain is at index 1 in both request and policy:

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

For domain APIs (e.g. GetAllUsersByDomain()) with a custom domain token name or position, set the index after creating the enforcer. Full example: rbac_with_domains_model.conf.

Token name and position
# Using `domain` instead of `dom`
[policy_definition]
p = sub, obj, act, domain
e.SetFieldIndex("p", constant.DomainIndex, 3) // index starts from 0
users := e.GetAllUsersByDomain("domain1") // without SetFieldIndex, this will raise an error