aws-ram-share-ou-members-trust

explicit aws emits CrossAccountTrust

match (record)

{ "field": "principals", "resource_type": "AWS::RAM::ResourceShare" }

where

principal_entry matches regex '^arn:aws:organizations::.*:ou/o-.*' share.status == 'ACTIVE' org_member_accounts = list of accounts in the OU (from Organizations adapter)

emit

source typeResourcePolicy
target typeAccount
source<ResourceShare node (ResourcePolicy)>
target<Account node for each member of the OU (emitted per account)>
conditionsresource_policy service_state
state logicACTIVE when share.status == 'ACTIVE' AND the account is confirmed to be a current member of the OU. CONDITIONAL(service_state) for pending invitations or unconfirmed membership. Member accounts added to the OU after the share is created automatically gain access (future members) — surfaces as a collection-time trigger to emit new CrossAccountTrust edges as accounts join.

Narrative

RAM share {share.name} grants access to {resource.name} to OU {ou.name}. Every current and future member account in that OU gains access without an invitation (or with org-internal invite if required).

Raw rule rules/explicit/aws-ram.yaml

id: aws-ram-share-ou-members-trust
emits: CrossAccountTrust
applies_to:
- aws
match_record:
  resource_type: AWS::RAM::ResourceShare
  field: principals
where:
- principal_entry matches regex '^arn:aws:organizations::.*:ou/o-.*'
- share.status == 'ACTIVE'
- org_member_accounts = list of accounts in the OU (from Organizations adapter)
emit:
  source_type: ResourcePolicy
  target_type: Account
  source: <ResourceShare node (ResourcePolicy)>
  target: <Account node for each member of the OU (emitted per account)>
  api_source: ram:GetResourceShares + ram:ListPrincipals; Organizations:ListAccountsForParent
  evidence_field: ResourceShare.principals[] (OU ARN); OU membership from Organizations API
  permissions: []
  conditions:
  - resource_policy
  - service_state
  state_logic: "ACTIVE when share.status == 'ACTIVE' AND the account is confirmed to be a current member\
    \ of the OU. CONDITIONAL(service_state) for pending invitations or unconfirmed membership. Member\
    \ accounts added to the OU after the share is created automatically gain access (future members) \u2014\
    \ surfaces as a collection-time trigger to emit new CrossAccountTrust edges as accounts join."
  false_positive_note: 'OU-wide shares reach only accounts within the specified OU, not the entire org.
    Emit one CrossAccountTrust edge per member account (target_type: Account). For cross-OU visibility
    or blast-radius annotations, emit ExposedToTenant separately with target_type: Organization (or Folder),
    flagging the OU-level reach without violating the CrossAccountTrust schema constraint. Do NOT emit
    CrossAccountTrust with target_type: Folder (OU); always resolve to member Account nodes. If the OU
    membership is dynamic, mark edges CONDITIONAL and set up collection triggers to update as membership
    changes.'
  narrative: RAM share {share.name} grants access to {resource.name} to OU {ou.name}. Every current and
    future member account in that OU gains access without an invitation (or with org-internal invite if
    required).
move · open · esc close