aws-ram-share-ou-members-trust
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 type | ResourcePolicy |
|---|---|
| target type | Account |
| source | <ResourceShare node (ResourcePolicy)> |
| target | <Account node for each member of the OU (emitted per account)> |
| 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) — 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).