admin-inherits-down-contains

Control of a parent administrative boundary inherits transitively to every descendant boundary and resource via Contains*.

match

A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.

{'principal': None} Controls {'parent': None} {'parent': None} Contains {'child': None}

where

node_class(?parent) == AdministrativeBoundary node_class(?principal) == Identity reachable(?parent, ?child, via=Contains, transitive=true)

emit

source typeIdentity
source?principal
target?child
conditionsscp_or_org_policy deny_assignment
state logicinherit_weakest(Controls@parent, descent): the descendant Controls is at best as strong as the parent Controls. If the parent control is CONDITIONAL (e.g. a role assignment gated by a condition_expression / PIM activation) the descendant Controls is CONDITIONAL with the same gate. A guardrail that DENIES the inherited action at a descendant scope (SCP / Org Policy / Azure deny assignment attached at or below ?child) makes the descendant Controls BLOCKED for the denied actions until guardrail-removal-upgrades- blocked (rule 3) lifts it. Otherwise ACTIVE. SECONDARY EMIT (CanEnter*): when node_class(?child) == AdministrativeBoundary, ALSO emit the matching enter edge keyed to the child's subtype — Account->CanEnterAccount, Subscription->CanEnterSubscription, Project->CanEnterProject, Organization->CanEnterOrganization, Tenant->CanEnterTenant — carrying the same inherited state. ManagementGroup / Folder / ResourceGroup have no dedicated CanEnter* edge; they surface only as Controls (and propagate to their own enterable children).

Narrative

{principal.name} controls the boundary {parent.name}; because {child.name} is nested under {parent.name} in the administrative hierarchy, that control inherits down and {principal.name} effectively controls {child.name} (and can operate inside it).

Raw rule rules/derived/hierarchy-chains.yaml

id: admin-inherits-down-contains
emits:
- Controls
- CanEnterAccount
- CanEnterSubscription
- CanEnterProject
- CanEnterOrganization
- CanEnterTenant
description: Control of a parent administrative boundary inherits transitively to every descendant boundary
  and resource via Contains*.
applies_to:
- '*'
match:
- - principal: null
  - Controls
  - parent: null
- - parent: null
  - Contains
  - child: null
where:
- node_class(?parent) == AdministrativeBoundary
- node_class(?principal) == Identity
- reachable(?parent, ?child, via=Contains, transitive=true)
emit:
  source_type: Identity
  source: ?principal
  target: ?child
  permissions: []
  conditions:
  - scp_or_org_policy
  - deny_assignment
  state_logic: "inherit_weakest(Controls@parent, descent): the descendant Controls is at best as strong\
    \ as the parent Controls. If the parent control is CONDITIONAL (e.g. a role assignment gated by a\
    \ condition_expression / PIM activation) the descendant Controls is CONDITIONAL with the same gate.\
    \ A guardrail that DENIES the inherited action at a descendant scope (SCP / Org Policy / Azure deny\
    \ assignment attached at or below ?child) makes the descendant Controls BLOCKED for the denied actions\
    \ until guardrail-removal-upgrades- blocked (rule 3) lifts it. Otherwise ACTIVE. SECONDARY EMIT (CanEnter*):\
    \ when node_class(?child) == AdministrativeBoundary, ALSO emit the matching enter edge keyed to the\
    \ child's subtype \u2014 Account->CanEnterAccount, Subscription->CanEnterSubscription, Project->CanEnterProject,\
    \ Organization->CanEnterOrganization, Tenant->CanEnterTenant \u2014 carrying the same inherited state.\
    \ ManagementGroup / Folder / ResourceGroup have no dedicated CanEnter* edge; they surface only as\
    \ Controls (and propagate to their own enterable children)."
  confidence: min(contributing_confidences)
  derived_from:
  - ?principal Controls ?parent
  - ?parent Contains+ ?child (transitive)
  false_positive_note: "Inheritance is real only for control that is genuinely scope-inheriting. Management-plane\
    \ RBAC/IAM assigned at a boundary DOES flow down (AWS OrganizationAccountAccessRole into member accounts,\
    \ Azure roles at MG/sub/RG inherit to children, GCP roles at org/folder/project inherit to descendants).\
    \ Do NOT inherit: (a) data-plane-only grants that the provider does not cascade (e.g. an Azure role\
    \ scoped with a DataActions condition, an S3 bucket policy \u2014 those are resource-local); (b) grants\
    \ explicitly scoped to a single resource via a condition (Azure ABAC condition, IAM resource ARN,\
    \ GCP IAM condition) \u2014 respect the condition and do not widen it to siblings; (c) a descendant\
    \ where a deny guardrail actually blocks the action (keep BLOCKED \u2014 rule 3, not this rule, decides\
    \ upgrades). Contains must be a real administrative-hierarchy edge, not a soft grouping (tags, folders-as-labels).\
    \ When the parent Controls is itself CONDITIONAL/BLOCKED, never emit a stronger descendant edge."
  narrative: '{principal.name} controls the boundary {parent.name}; because {child.name} is nested under
    {parent.name} in the administrative hierarchy, that control inherits down and {principal.name} effectively
    controls {child.name} (and can operate inside it).'
move · open · esc close