Inheriting roles from other resources
Using the relations
feature
If two resources have a hierarchical relationship (e.g. parent-child), users commonly inherit roles or permissions on the subordinate resource from their role on the superior resource.
In this case, users often rely on Polar's relations
feature, which often
expresses the relationship between the resources in the subordinate resource's
definition.
A common example of this is files and folders; granting access to a folder typically grants access to the folder's contents.
In this example, anyone with a role on a folder also has the same role on any file/folder it contains.
Oso Policy
actor User { }resource Repository { roles = ["reader", "maintainer"];}resource Folder { roles = ["reader", "writer"]; relations = { repository: Repository, folder: Folder, }; "reader" if "reader" on "repository"; "writer" if "maintainer" on "repository"; role if role on "folder";}resource File { permissions = ["read", "write"]; roles = ["reader", "writer"]; relations = { folder: Folder, }; role if role on "folder"; "read" if "reader"; "write" if "writer";}test "folder roles apply to files" { setup { has_role(User{"alice"}, "reader", Repository{"anvil"}); has_relation(Folder{"python"}, "repository", Repository{"anvil"}); has_relation(Folder{"tests"}, "folder", Folder{"python"}); has_relation(File{"test.py"}, "folder", Folder{"tests"}); } assert allow(User{"alice"}, "read", File{"test.py"});}
Using longhand rules
If two types of resources have any kind of relationship (hierarchical or otherwise), you can inherit roles on one resource from the other. For example, in a parent-child relationship, users can inherit roles from the child on the parent.
This essentially uses the same convention as the relations
feature (relying on
has_relation
facts in your authorization data), but requires writing out the
rule in longhand.
Oso Policy
actor User {}resource ParentResource { roles = ["admin", "member"]; permissions = ["read", "write"]; "read" if "member"; "write" if "admin"; "member" if "admin";}resource ChildResource { roles = ["admin", "member"]; permissions = ["read", "write"]; relations = { parent: ParentResource }; "read" if "member"; "write" if "admin"; "member" if "admin"; # ChildResource inherits admin from ParentResource "admin" if "admin" on "parent";}# ParentResource inherits member from ChildResourcehas_role(user: User, "member", parent_resource: ParentResource) if child_resource matches ChildResource and has_role(user, "member", child_resource) and has_relation(child_resource, "parent", parent_resource);test "inherit role on parent from child" { setup { has_relation(ChildResource{"anvil"}, "parent", ParentResource{"acme"}); has_role(User{"alice"}, "member", ChildResource{"anvil"}); } assert allow(User{"alice"}, "read", ParentResource{"acme"});}