aws-ram-shared-subnet-network-reach
A shared subnet collapses the inter-account network boundary: consumer workloads launched into the shared subnet are on-link with owner-account resources, yielding on-subnet network reachability.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
node_type(?share) ==
ResourcePolicy # the RAM ResourceShare node
node_type(?consumer_account) == Account
?share.resourceArns contains at least one Subnet ARN (shared_resource_type == Subnet)
?share.status == 'ACTIVE' # invitation accepted, or org-wide (no invitation needed)
?share.allowExternalPrincipals == true OR consumer_account is in the same AWS Organization as the owner
optional
Present → upgrade the emitted state; absent → downgrade (not a hard requirement).
{'consumer_account': None}
CanNetworkReach {'owner_subnet': None}
emit
| source type | Network |
|---|---|
| target type | Network |
| source | <consumer VPC / workloads in ?consumer_account (Network or Compute)> |
| target | <Subnet node shared by ?share (owner-account subnet, subtype Subnet)> |
| conditions | network_reachability resource_policy |
| state logic | ACTIVE when the share is accepted (status==ACTIVE) and the consumer account is a valid principal (allowExternalPrincipals==true for cross-org accounts, or same-org). CONDITIONAL(service_state) when the share is PENDING (invitation not yet accepted — cross-account, non-org). CONDITIONAL(network_reachability) because security groups on owner-account ENIs still gate the reachability at L4; the CanNetworkReach edge represents on-subnet L2 reachability, which is a prerequisite for L4 access. BLOCKED when an SCP denies ram:AcceptResourceShareInvitation on the consumer or ram:CreateResourceShare on the owner. Never stronger than the weakest contributing CrossAccountTrust state. NOTE: 'on-link' reachability is CONDITIONAL(network_reachability) — the owner's SGs are the gating condition the analyst must evaluate for each owner-side service. |
Narrative
RAM share {share.name} in account {owner_account.name} grants account {consumer_account.name} access to shared subnet {subnet.name}. Workloads launched by {consumer_account.name} into that subnet (consumer VPC) are on-link with owner-account resources on the same subnet, collapsing the inter-account network boundary at L2 (subject to owner-side security group evaluation at L4).
Raw rule rules/derived/aws/ram.yaml
id: aws-ram-shared-subnet-network-reach
emits: CanNetworkReach
description: 'A shared subnet collapses the inter-account network boundary: consumer workloads launched
into the shared subnet are on-link with owner-account resources, yielding on-subnet network reachability.'
match:
- - share: null
- CrossAccountTrust
- consumer_account: null
where:
- 'node_type(?share) == ResourcePolicy # the RAM ResourceShare node'
- node_type(?consumer_account) == Account
- ?share.resourceArns contains at least one Subnet ARN (shared_resource_type == Subnet)
- '?share.status == ''ACTIVE'' # invitation accepted, or org-wide (no invitation needed)'
- ?share.allowExternalPrincipals == true OR consumer_account is in the same AWS Organization as the owner
optional:
- - consumer_account: null
- CanNetworkReach
- owner_subnet: null
emit:
source_type: Network
target_type: Network
source: <consumer VPC / workloads in ?consumer_account (Network or Compute)>
target: <Subnet node shared by ?share (owner-account subnet, subtype Subnet)>
permissions: []
conditions:
- network_reachability
- resource_policy
state_logic: "ACTIVE when the share is accepted (status==ACTIVE) and the consumer account is a valid\
\ principal (allowExternalPrincipals==true for cross-org accounts, or same-org). CONDITIONAL(service_state)\
\ when the share is PENDING (invitation not yet accepted \u2014 cross-account, non-org). CONDITIONAL(network_reachability)\
\ because security groups on owner-account ENIs still gate the reachability at L4; the CanNetworkReach\
\ edge represents on-subnet L2 reachability, which is a prerequisite for L4 access. BLOCKED when an\
\ SCP denies ram:AcceptResourceShareInvitation on the consumer or ram:CreateResourceShare on the owner.\
\ Never stronger than the weakest contributing CrossAccountTrust state. NOTE: 'on-link' reachability\
\ is CONDITIONAL(network_reachability) \u2014 the owner's SGs are the gating condition the analyst\
\ must evaluate for each owner-side service."
confidence: min(contributing_confidences) * 0.85
derived_from:
- <CrossAccountTrust edge_id (share -> consumer_account)>
- <shared subnet resource_type == Subnet>
- <share.status == ACTIVE>
false_positive_note: "Consumer workloads in the shared subnet are co-located on the owner's L2 but are\
\ still governed by OWNER-ACCOUNT security groups on the owner's ENIs. Consumer CANNOT modify owner-account\
\ SGs. CanNetworkReach here means the consumer VPC / its workloads are ON-SUBNET (L2 reachability)\
\ and MAY reach owner-account services if the SG allows the subnet CIDR \u2014 not that every resource\
\ is reachable. Emit CONDITIONAL(network_reachability) and note the SG gate. Do NOT emit ACTIVE without\
\ confirming the relevant SG rules admit traffic from the shared subnet CIDR (leave CONDITIONAL for\
\ analyst evaluation). Source type is Network (consumer VPC) because Account is not in CanNetworkReach.source\
\ \u2014 the reachability is realized by the consumer VPC's workloads, not the account boundary node.\
\ For pending-invitation shares (status==PENDING_ACCEPTANCE), emit only CONDITIONAL(service_state)\
\ \u2014 no access until accepted. For org-wide shares (principals == org/OU ARN), the consumer does\
\ not need to accept, so emit ACTIVE once the org membership is confirmed."
narrative: RAM share {share.name} in account {owner_account.name} grants account {consumer_account.name}
access to shared subnet {subnet.name}. Workloads launched by {consumer_account.name} into that subnet
(consumer VPC) are on-link with owner-account resources on the same subnet, collapsing the inter-account
network boundary at L2 (subject to owner-side security group evaluation at L4).