network-peered-reach
A source reaches a destination across a SINGLE VPC/VNet peering when the destination's ingress admits it - peering is non-transitive, so exactly one direct hop.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
{'sg': None}
CanReachPort {'dst': None}
{'src': None} LocatedIn {'vnetA': None}
{'dst': None} LocatedIn {'vnetB': None}
{'vnetA': None} PeeredWith {'vnetB': None}
where
node_class(?src) in [Compute, Network]
node_class(?dst) in [Compute, Data, Storage]
node_type(?sg) in [
SecurityGroup, Firewall]
?vnetA != ?vnetB
is_direct_edge(?vnetA, PeeredWith, ?vnetB)
emit
| source type | Compute Network |
|---|---|
| target type | Compute Data Storage |
| source | ?src |
| target | ?dst |
| conditions | network_reachability |
| state logic | ACTIVE when the peering is Connected on both sides, a route to the peer CIDR is present on both sides, and the destination ingress admits the source. CONDITIONAL(network_reachability) if the remote side or its route table is uncollected. BLOCKED on a NACL/firewall DENY. Inherit the weakest of CanReachPort and the PeeredWith edge. NOTE: the state_logic includes a route-to-peer-CIDR check (both sides must have route table entries for the peer CIDR) even though the match clause does not include an explicit RoutesTo fact — this is because a Connected peering with no route entry is not an active path. The engine must evaluate the route-table check as a CONDITIONAL gate when scoring the emitted edge. |
Narrative
{src.name} in {vnetA.name} reaches {dst.name} in {vnetB.name} across their direct peering; a foothold in {vnetA.name} therefore has a network path into {vnetB.name} subject to the destination's ingress rules.
Raw rule rules/derived/network-chains.yaml
id: network-peered-reach
emits: CanNetworkReach
description: "A source reaches a destination across a SINGLE VPC/VNet peering when the destination's ingress\
\ admits it \u2014 peering is non-transitive, so exactly one direct hop."
applies_to:
- '*'
match:
- - sg: null
- CanReachPort
- dst: null
- - src: null
- LocatedIn
- vnetA: null
- - dst: null
- LocatedIn
- vnetB: null
- - vnetA: null
- PeeredWith
- vnetB: null
where:
- node_class(?src) in [Compute, Network]
- node_class(?dst) in [Compute, Data, Storage]
- node_type(?sg) in [SecurityGroup, Firewall]
- ?vnetA != ?vnetB
- is_direct_edge(?vnetA, PeeredWith, ?vnetB)
emit:
source_type:
- Compute
- Network
target_type:
- Compute
- Data
- Storage
source: ?src
target: ?dst
permissions: []
conditions:
- network_reachability
derived_via:
- PeeredWith
state_logic: "ACTIVE when the peering is Connected on both sides, a route to the peer CIDR is present\
\ on both sides, and the destination ingress admits the source. CONDITIONAL(network_reachability)\
\ if the remote side or its route table is uncollected. BLOCKED on a NACL/firewall DENY. Inherit the\
\ weakest of CanReachPort and the PeeredWith edge. NOTE: the state_logic includes a route-to-peer-CIDR\
\ check (both sides must have route table entries for the peer CIDR) even though the match clause\
\ does not include an explicit RoutesTo fact \u2014 this is because a Connected peering with no route\
\ entry is not an active path. The engine must evaluate the route-table check as a CONDITIONAL gate\
\ when scoring the emitted edge."
confidence: min(contributing_confidences)
derived_from:
- ?sg CanReachPort ?dst
- ?vnetA PeeredWith ?vnetB
false_positive_note: "THE non-transitivity trap: do not emit reach to a VNet that is only reachable\
\ via a SECOND peering hop \u2014 peering does not forward transitively. A peering also needs a route-table\
\ entry for the peer CIDR on BOTH sides to be live (a Connected peering with no route is not a path).\
\ Cross-account/subscription peering additionally requires the remote SG/NSG to admit the source.\
\ NACL/firewall DENY => BLOCKED. The derived_via: [PeeredWith] annotation on the emitted edge allows\
\ the engine to identify peered-reach edges and prevent using them as a CanReachPort surrogate for\
\ further hop composition (which would silently create peering-of-peering paths)."
narrative: '{src.name} in {vnetA.name} reaches {dst.name} in {vnetB.name} across their direct peering;
a foothold in {vnetA.name} therefore has a network path into {vnetB.name} subject to the destination''s
ingress rules.'