grant-at-boundary-controls-descendants
Ability to assign roles/permissions at a boundary scope lets the principal self-grant full control of that boundary and, by inheritance, its whole subtree.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
scope_of(?principal,
CanGrantPermission) is an AdministrativeBoundary # ?boundary
node_class(?principal) == Identity
principal holds a real role-assignment action at ?boundary (see per-provider note)
emit
| source type | Identity |
|---|---|
| target type | * |
| source | ?principal |
| target | ?boundary (the AdministrativeBoundary the grant is scoped at) |
| conditions | iam_permission scp_or_org_policy |
| state logic | ACTIVE when the role-assignment action is unconditionally held at ?boundary; CONDITIONAL(iam_permission) when the assignment is gated (Azure PIM eligible- not-active, an IAM/ABAC condition, a GCP IAM condition) — the principal must first satisfy the condition to self-grant. BLOCKED when an SCP/Org Policy denies the assignment action (e.g. an SCP denying iam:* or organizations:*, a GCP org policy, an Azure deny assignment on roleAssignments/write) — until rule 3 upgrades it. This Controls(?boundary) then feeds admin-inherits-down- contains (rule 1) to reach the entire subtree; do NOT re-enumerate the descendants here. |
Narrative
{principal.name} can assign roles/permissions at {boundary.name} and can therefore grant itself full control of {boundary.name} - and, through inheritance, of everything nested beneath it.
Raw rule rules/derived/hierarchy-chains.yaml
id: grant-at-boundary-controls-descendants
emits: Controls
description: Ability to assign roles/permissions at a boundary scope lets the principal self-grant full
control of that boundary and, by inheritance, its whole subtree.
applies_to:
- '*'
match:
- - principal: null
- CanGrantPermission
- target_principal: null
where:
- 'scope_of(?principal, CanGrantPermission) is an AdministrativeBoundary # ?boundary'
- node_class(?principal) == Identity
- principal holds a real role-assignment action at ?boundary (see per-provider note)
emit:
source_type: Identity
target_type: '*'
source: ?principal
target: ?boundary (the AdministrativeBoundary the grant is scoped at)
permissions: []
conditions:
- iam_permission
- scp_or_org_policy
state_logic: "ACTIVE when the role-assignment action is unconditionally held at ?boundary; CONDITIONAL(iam_permission)\
\ when the assignment is gated (Azure PIM eligible- not-active, an IAM/ABAC condition, a GCP IAM condition)\
\ \u2014 the principal must first satisfy the condition to self-grant. BLOCKED when an SCP/Org Policy\
\ denies the assignment action (e.g. an SCP denying iam:* or organizations:*, a GCP org policy, an\
\ Azure deny assignment on roleAssignments/write) \u2014 until rule 3 upgrades it. This Controls(?boundary)\
\ then feeds admin-inherits-down- contains (rule 1) to reach the entire subtree; do NOT re-enumerate\
\ the descendants here."
confidence: min(contributing_confidences)
derived_from:
- ?principal CanGrantPermission ?target_principal @?boundary
false_positive_note: "Emit ONLY when the grant is boundary-scoped. A CanGrantPermission scoped to a\
\ single principal/resource is an identity-escalation primitive (covered by the identity-escalation\
\ rules), NOT boundary control \u2014 do not emit here. Respect role capability boundaries precisely:\
\ Azure Contributor CANNOT assign roles (no Microsoft.Authorization/roleAssignments/write) \u2014\
\ only Owner and User Access Administrator can; AWS iam:PassRole is NOT a grant; a GCP role lacking\
\ setIamPolicy cannot self-grant. Overlaps can-control's control-boundary-via- iam-admin for the Controls(?boundary)\
\ emit \u2014 dedupe on (Controls, principal, boundary); the value this rule adds is the explicit\
\ chain into subtree descent."
narrative: "{principal.name} can assign roles/permissions at {boundary.name} and can therefore grant\
\ itself full control of {boundary.name} \u2014 and, through inheritance, of everything nested beneath\
\ it."