aws-account-leave-org-escapes-scp

explicit aws emits CanModifyConfiguration

match

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

{'principal': None} HasPermission {'account': None} {'account': None} HasPolicy {'scp': None}

where

node_class(?account) == AdministrativeBoundary and node_type(?account) == Account node_type(?scp) == ServiceControlPolicy # an SCP is actually attached to ?account (or its OU) ?principal has EFFECTIVE organizations:LeaveOrganization (member-side) OR organizations:RemoveAccountFromOrganization (management-side) for ?account no SCP denies the leave/remove action itself at ?account scope

emit

source typeIdentity
target type*
source<principal>
target<scope-binding of ?scp on ?account>
permissionsorganizations:LeaveOrganization organizations:RemoveAccountFromOrganization
conditionsscp_or_org_policy service_state
state logicACTIVE when the leave/remove action is effectively held and NOT itself SCP-denied and the account is standalone-ready. CONDITIONAL(service_state) when RemoveAccountFromOrganization would fail because the member is not standalone-ready (billing/contact info incomplete). BLOCKED(scp_or_org_policy) when an SCP denies organizations:LeaveOrganization (standard landing-zone hardening) -- and note the circularity: you cannot leave to escape an SCP that denies leaving, so this edge cannot self-upgrade the very SCP blocking it.

Narrative

{principal.name} can pull account {account.name} out of the organization (organizations:LeaveOrganization / RemoveAccountFromOrganization), detaching it from SCP {scp.name} and every guardrail that SCP imposes.

Raw rule rules/explicit/aws-account.yaml

id: aws-account-leave-org-escapes-scp
emits: CanModifyConfiguration
applies_to:
- aws
match:
- - principal: null
  - HasPermission
  - account: null
- - account: null
  - HasPolicy
  - scp: null
where:
- node_class(?account) == AdministrativeBoundary and node_type(?account) == Account
- 'node_type(?scp) == ServiceControlPolicy   # an SCP is actually attached to ?account (or its OU)'
- ?principal has EFFECTIVE organizations:LeaveOrganization (member-side) OR organizations:RemoveAccountFromOrganization
  (management-side) for ?account
- no SCP denies the leave/remove action itself at ?account scope
emit:
  source_type: Identity
  target_type: '*'
  source: <principal>
  target: <scope-binding of ?scp on ?account>
  api_source: iam:SimulatePrincipalPolicy | policy evaluation
  permissions:
  - organizations:LeaveOrganization
  - organizations:RemoveAccountFromOrganization
  conditions:
  - scp_or_org_policy
  - service_state
  state_logic: 'ACTIVE when the leave/remove action is effectively held and NOT itself SCP-denied and
    the account is standalone-ready. CONDITIONAL(service_state) when RemoveAccountFromOrganization would
    fail because the member is not standalone-ready (billing/contact info incomplete). BLOCKED(scp_or_org_policy)
    when an SCP denies organizations:LeaveOrganization (standard landing-zone hardening) -- and note the
    circularity: you cannot leave to escape an SCP that denies leaving, so this edge cannot self-upgrade
    the very SCP blocking it.'
  false_positive_note: Fire ONLY when an SCP is genuinely attached to ?account (else there is no guardrail
    to escape and this is mere availability impact -- model as CanDelete, not a path). LeaveOrganization
    is member-side and very commonly SCP-denied in hardened orgs -> BLOCKED. RemoveAccountFromOrganization
    is management-side and requires the member to be standalone-ready (complete billing/contact) or the
    API fails -> CONDITIONAL(service_state). Do not emit for the management account itself (it cannot
    leave its own org). The BLOCKED->ACTIVE upgrade of the suppressed edges is owned by hierarchy-chains
    rule 3, NOT here. The complementary POLICY-EDIT branch (organizations:UpdatePolicy/DetachPolicy/DeletePolicy/DisablePolicyType,
    organizations:MoveAccount to an OU without the SCP) is emitted by the organizations adapter as CanModifyPolicy
    over ?scp -- CITED, not here.
  narrative: '{principal.name} can pull account {account.name} out of the organization (organizations:LeaveOrganization
    / RemoveAccountFromOrganization), detaching it from SCP {scp.name} and every guardrail that SCP imposes.'
move · open · esc close