Documentation Index
Fetch the complete documentation index at: https://www.osohq.com/docs/llms.txt
Use this file to discover all available pages before exploring further.
User groups let you assign roles to groups; each user inherits the group’s roles, reducing the need to assign roles individually.
Implementation
The core idea of user groups is that a user inherits all roles from the groups that user belongs to. Assigning a user to a group is sufficient to grant them all roles assigned to that group.
actor User { }
# Model groups as actors to assign roles to them
actor Group { }
resource Repository {
roles = ["reader"];
permissions = ["read"];
"read" if "reader";
}
# Users inherit roles from groups
# `user` has `role` on `resource` if
has_role(user: User, role: String, resource: Resource) if
# there exists a `group`
group matches Group and
# `user` is in the group
has_group(user, group) and
# the `group` has `role` on `resource`
has_role(group, role, resource);
test "group members can read repositories" {
setup {
has_role(Group{"anvil-readers"}, "reader", Repository{"anvil"});
has_group(User{"alice"}, Group{"anvil-readers"});
has_group(User{"bob"}, Group{"anvil-readers"});
has_group(User{"charlie"}, Group{"anvil-readers"});
}
assert allow(User{"alice"}, "read", Repository{"anvil"});
assert allow(User{"bob"}, "read", Repository{"anvil"});
assert allow(User{"charlie"}, "read", Repository{"anvil"});
}
We’ve assigned the reader role to the anvil-readers group, and then added Alice, Bob, and Charlie to that group. Now they can all read the anvil repository.
Nested groups
You can extend this pattern by allowing groups to be members of other groups, forming a hierarchy. Users inherit roles from every group in the hierarchy.
Implement this with a recursive rule: a user is a member of a group if they belong to any subgroup of that group.
has_group(user: User, group: Group) if
g matches Group and
has_group(user, g) and
has_group(g, group);