winstaan
09/06/2023, 4:28 PMwinstaan
09/06/2023, 4:29 PMdefinition user {}
definition org {
relation parent_org: org
relation manager: user
relation members: user
permission manager_constraint = manager + parent_org->manager_constraint
permission members_constraint = members + parent_org->members_constraint
}
definition resource {
relation parent_org: org
relation task_assignee: user
relation policies: policy_binding
permission manager_constraint = parent_org->manager_constraint
permission members_constraint = parent_org->members_constraint
permission task_assignee_constraint = task_assignee
permission read = policies->read
}
definition policy_binding {
relation satisfied: resource#task_assignee_constraint | resource#members_constraint | resource#manager_constraint
permission read = satisfied
}
The main thing to note is that a resource delegates to policy_bindings for permission calculation - and the policy bindings call back into one of the constraints on the resource itself.winstaan
09/06/2023, 4:29 PMp1 that is constrained to managers, and a policy p2 that is constrained to taskAssignees. Then, for a resource r1 , the following relationships from the resource to policy bindings and back again are written -
resource:r1#policies@policy_binding:r1p1
resource:r1#policies@policy_binding:r1p2
policy_binding:r1p1#satisfied@resource:r1#members_constraint
policy_binding:r1p2#satisfied@resource:r1#task_assignee_constraint
And this seems to work well. (although the policy_bindings need to be redone for all resources when a policy is changed)winstaan
09/06/2023, 4:30 PMcaveat role(expected_role: String, actual_role: String) {
expected_role == actual_role
}
definition org {
relation role_assignee: user with role
permission has_role_constraint = role_assignee + parent_org->has_role_constraint
...
}
definition resource {
permission has_role_constraint = parent_org->has_role_constraint
...
}
definition policy_binding {
relation satisfied: resource#has_role_constraint | ...
}
To represent a role assignment, a relation is written with a partially-bound role caveat where the actual_role is provided. - e.g.
org:o1#role_assignee@user:u1[role{"actual_role":"rolename"}]winstaan
09/06/2023, 4:31 PMexpected_role should be.winstaan
09/06/2023, 4:32 PMdefinition policy_binding {
relation satisfied: resource#has_role_constraint providing expected_role | ...
}
And writing relationships would allow a context to be supplied
policy_binding:r1p3#satisfied@resource:r1#has_role_constraint[{"expected_role":"rolename"}
The parameters in the relationship context would come into scope once the relation is traversed (and mask any previous values for that parameter).winstaan
09/06/2023, 4:32 PMrelation role_assignee: user with role(actual_role)winstaan
09/06/2023, 4:33 PMJoey
09/06/2023, 4:34 PMJoey
09/06/2023, 4:34 PMJoey
09/06/2023, 4:34 PMJoey
09/06/2023, 4:34 PMJoey
09/06/2023, 4:35 PMJoey
09/06/2023, 4:36 PMJoey
09/06/2023, 4:40 PMproviding syntax is an interesting idea thoughJoey
09/06/2023, 4:40 PMJoey
09/06/2023, 4:41 PMJoey
09/06/2023, 4:41 PMwinstaan
09/06/2023, 6:01 PMwinstaan
09/06/2023, 6:02 PMJoey
09/06/2023, 6:40 PMJoey
09/06/2023, 6:40 PMwinstaan
09/07/2023, 10:03 AM