diff --git a/docs/auth/permissions.md b/docs/auth/permissions.md index 62abd16..e4f2bd8 100644 --- a/docs/auth/permissions.md +++ b/docs/auth/permissions.md @@ -61,7 +61,7 @@ Readme link: [@epilot/permissions](https://www.npmjs.com/package/@epilot/permiss ## Grants Evaluation Logic -A lot of this will be familiar to AWS IAM users. This is “heavily inspired” by their design +A lot of this will be familiar to AWS IAM users. This is "heavily inspired" by their design - **Rule 1**: Tenants are isolated into Organizations. Roles may only grant access to resources within the tenant Organization. - **Rule 2**: The owner role inherits all grants from the organization. (hardcoded role, present in all orgs) @@ -69,6 +69,7 @@ A lot of this will be familiar to AWS IAM users. This is “heavily inspired” - **Rule 4**: When evaluating all role and organization grants are added to the grant pool. - **Rule 5**: At least one organization role grant and at least one user role grant must be matched to pass the evaluation. Neither must contain a matched explicit deny. - **Rule 6**: An evaluation will try to match all available grants where a given action and resource matches. Wildcard expressions are supported. +- **Rule 7**: Role hierarchies can be defined where child roles are constrained by parent roles. Both parent and child must grant permission for access to be allowed. Parent roles that are not directly assigned to a user are not evaluated independently. ## Organization Root Role @@ -78,6 +79,49 @@ The organization root role defines the maximum set of grants any user in that or This role is only accessible to epilot admins and is controlled by the pricing tier of that organization. +## Role Hierarchies + +Roles can form hierarchies where a role may have a **parent role**. This enables more sophisticated permission management by allowing child roles to be constrained by their parent roles. + +### Parent-Child Role Relationships + +When a role has a parent role defined: +- The **child role** defines the specific permissions granted to the user +- The **parent role** acts as a constraint, defining the maximum permissions the child can have +- **Both the parent AND child must grant permission** for access to be allowed +- If either the parent or child denies access, the entire role pair denies access + +This prevents permission escalation and ensures that child roles cannot exceed the scope defined by their parent roles. + +### Use Cases + +**Example: Department Manager with Limited Scope** +```json +{ + "id": "66:sales-manager", + "name": "Sales Manager", + "slug": "sales-manager", + "type": "user_role", + "organization_id": "66", + "parent_role": "66:manager", + "grants": [ + { + "action": "entity:view", + "resource": "opportunity:*" + }, + { + "action": "entity:edit", + "resource": "opportunity:*" + } + ] +} +``` + +In this example: +- The parent role (`manager`) defines broad permissions +- The child role (`sales-manager`) narrows access to only opportunities +- The user can only view/edit opportunities that the parent role also permits + ## Links - Permissions package: https://www.npmjs.com/package/@epilot/permissions