Default roles
In this example, organizations want members to automatically inherit a role on all repositories. Different organizations choose different default roles: some grant “viewer”, others grant “admin”. Without conditional roles, you’d synchas_role(User{"Alice"}, <default role>, Repository{"Anvils"})
for every user-repository combination. That’s a lot of facts.
Instead, send one fact like has_default_role(Organization{"acme"}, "editor")
to set a default role for their members to inherit on all of their repositories.
Implementation
Add a customhas_role
rule that grants the organization-configured default role on repositories to all members of the repository’s organization.
Toggles
You can conditionally inherit roles by specifying attributes on the resource itself instead of on a related resource. A common example is a toggle on the resource. For example, a setting that specifies if the resource is “protected” and restricts access accordingly.Implement the logic
Instead of inheriting all roles unconditionally (role if role on "organization"
) or a default role on all repositories, only allow users to inherit roles on repositories that aren’t marked as “protected”.
- As an organization member, Alice can read unprotected repositories.
- As an organization member, Alice can not read protected repositories.
- As an organization member, Alice can read a protected repository if she’s explicitly invited to it.
- As an organization admin, Alice can read and delete all repositories regardless of protected status.
Combine default roles and toggles
The two pieces of logic combine together perfectly:Next steps
Conditional roles enable advanced authorization patterns while minimizing fact management. Consider these approaches for your application:- Default roles when you need organization-wide permissions with minimal data sync
- Toggles when resources need protection levels or feature flags
- Combinations when you need both default inheritance and conditional access