Entitlements
In applications with differentiated subscription tiers or paid features users' permissions are determined by the features they have paid for.
Implement the logic
The core part of the entitlements logic is to conditionally grant a user permission based on a combination of their role and attributes of the organization (like the subscription tier they are on).
For example, we can grant users permission to create repositories for an organization if they have the "member" role for that organization and the organization has quota remaining for creating repositories.
actor User { }resource Organization {  roles = ["admin", "member"];  permissions = ["repository.create"];  "member" if "admin";}resource Plan {  roles = ["subscriber"];  relations = { subscribed_organization: Organization };  "subscriber" if role on "subscribed_organization";}resource Feature {  relations = { plan: Plan };}has_permission(user: User, "repository.create", org: Organization) if  has_role(user, "member", org) and  has_quota_remaining(org, Feature{"repository"});has_quota_remaining(org: Organization, feature: Feature) if  quota matches Integer and  has_quota(org, feature, quota) and  used matches Integer and  quota_used(org, feature, used) and  used < quota;has_quota(org: Organization, feature: Feature, quota: Integer) if  plan matches Plan and  has_relation(plan, "subscribed", org) and  plan_quota(plan, feature, quota);
Test the logic
To test this we have:
- A few organizations with different plans and quotas used.
- Users belonging to each of those organizations.
- Tests to check which users can still create repositories.
declare plan_quota(Plan, Feature, Integer);declare quota_used(Organization, Feature, Integer);plan_quota(Plan{"pro"}, Feature{"repository"}, 10);plan_quota(Plan{"basic"}, Feature{"repository"}, 0);test "members can create repositories if they have quota" {  setup {    quota_used(Organization{"apple"}, Feature{"repository"}, 5);    quota_used(Organization{"netflix"}, Feature{"repository"}, 10);    quota_used(Organization{"amazon"}, Feature{"repository"}, 0);    has_relation(Plan{"pro"}, "subscribed", Organization{"apple"});    has_relation(Plan{"pro"}, "subscribed", Organization{"netflix"});    has_relation(Plan{"basic"}, "subscribed", Organization{"amazon"});    has_role(User{"alice"}, "member", Organization{"apple"});    has_role(User{"bob"}, "member", Organization{"netflix"});    has_role(User{"charlie"}, "member", Organization{"amazon"});  }  assert has_quota_remaining(Organization{"apple"}, Feature{"repository"});  # Apple has quota remaining, so all good  assert allow(User{"alice"}, "repository.create", Organization{"apple"});  # Netflix has used all quota  assert_not allow(User{"bob"}, "repository.create", Organization{"netflix"});  # Amazon doesn't have any quota left  assert_not allow(User{"charlie"}, "repository.create", Organization{"amazon"});}