Skip to main content

Route-Aware Topology

Build 90 — Route-Aware Topology extends Infracast's asset graph with routing semantics, enabling real network reachability analysis instead of relying on security group approximations alone.

Why This Matters

Prior to Build 90, the path tracer checked Security Groups and NACLs but assumed routing worked. A subnet with no route to an Internet Gateway would still appear "internet-exposed" if its SGs allowed 0.0.0.0/0 — because we never validated the route table.

Build 90 closes this gap:

  • Route tables produce graph edges, not just inventory nodes.
  • Subnets are linked to their effective route table via associated_with edges.
  • The path tracer validates routing before checking SGs — route-blocked paths are distinct from SG-blocked paths.
  • 8 new finding rules fire on routing misconfigurations.
  • A Network Connectivity page shows a subnet × reachability matrix.

New Edge Types

Edge TypeSourceTargetDescription
routes_toRouteTableIGW / NAT / TGW / VGW / Peering / ENIRoute table entry pointing to a gateway
associated_withSubnetRouteTableSubnet is associated with this route table
next_hopNetwork DeviceNetwork Device / InterfaceRIB next-hop resolves to a known device interface

Edge Properties

routes_to

{
"destination_cidr": "0.0.0.0/0",
"target_type": "ec2.internet_gateway",
"state": "active",
"propagated": false,
"blackhole": false
}

associated_with

{
"association_id": "rtbassoc-0abc123",
"main": false
}

next_hop (network devices)

{
"destination": "10.0.0.0/8",
"next_hop_ip": "10.1.0.1",
"protocol": "ospf",
"interface": "GigabitEthernet0/0"
}

Reachability Computation

ComputeSubnetReachability in the reachability engine walks the graph:

Subnet --associated_with--> RouteTable --routes_to--> Target

For each target type it computes:

FlagTrigger
internet_egress: trueRoute table has a route to an Internet Gateway
nat_egress: trueRoute table has a route to a NAT Gateway
tgw_connected: [...]Route table has a route to one or more Transit Gateways
peering_connected: [...]Route table has a route to one or more VPC Peering connections
vgw_connected: trueRoute table has a route to a VPN or Direct Connect gateway

Walk depth is capped at 10 hops to prevent cycles. Blackhole routes are skipped.

Results are cached per-tenant with a 5-minute TTL (matching the DefaultCache in the package).


Path Tracer Integration

The path tracer now validates routing before SG checks:

  1. If the source subnet has a route table association (RouteTableID != ""), route validation runs.
  2. For internet destinations (0.0.0.0/0 or public IPs), the tracer checks internet_egress or nat_egress.
  3. If no internet route exists, the result is route_blocked = true and the summary explains why.
  4. Backward compatible: if no route data is present, the tracer proceeds as before.

Result Fields (new in Build 90)

type PathResult struct {
RouteBlocked bool // true = blocked at routing layer, not SG
// ...
}

type HopResult struct {
RouteDecision string // e.g. "routes_to IGW via rtb-0abc123"
// ...
}

UI Display

The path tracer UI distinguishes three blocked states:

  • 🔒 BLOCKED — blocked by SG/firewall rule
  • 🛣️ ROUTE BLOCKED — no route in route table (shown in orange)
  • 🔓 REACHABLE — all checks pass

Topology Routing Layer

The topology canvas has a Routing toggle in the layer controls. When on:

  • routes_to edges: dashed orange lines with destination CIDR label
  • associated_with edges: dashed amber lines
  • next_hop edges: dashed salmon/coral lines

These edges are hidden by default to avoid visual clutter. Toggle on when debugging routing paths.


Network Connectivity Page

Path: /network-connectivity (Infrastructure sidebar group)

The page shows a subnet reachability matrix:

ColumnMeaning
🌐 InternetDirect IGW route — subnet can egress internet
🔁 NAT EgressRoutes via NAT gateway
🔀 TGWConnected to one or more Transit Gateways
🔗 PeeringConnected to VPC peering connections
🏢 VPN/DXOn-premises connectivity via VGW/DX

Export to CSV is available. The page uses the same 5-minute cached reachability data as the API.


API Endpoints

All endpoints require nodes:read permission.

GET /api/v1/tenants/{tenantID}/network/reachability

Returns the full subnet reachability matrix. Cached for 5 minutes.

{
"tenant_id": "t-abc123",
"count": 42,
"subnets": {
"aws:us-east-1:ec2.subnet:subnet-0abc": {
"subnet_id": "aws:us-east-1:ec2.subnet:subnet-0abc",
"subnet_name": "my-public-subnet",
"internet_egress": true,
"nat_egress": false,
"vgw_connected": false,
"tgw_connected": [],
"peering_connected": [],
"egress_via": ["aws:us-east-1:ec2.internet_gateway:igw-0abc"],
"route_table_id": "aws:us-east-1:ec2.route_table:rtb-0abc"
}
}
}

GET /api/v1/tenants/{tenantID}/network/reachability/{subnetID}

Returns reachability for a single subnet. URL-encode the subnet ID.

GET /api/v1/tenants/{tenantID}/network/route-tables

Returns all route tables with their routes_to edges.


Finding Rules

Eight rules in rules/network_routing.yaml:

IDSeverityTitle
NETWORK-ROUTE-001HIGHSubnet with default route to IGW
NETWORK-ROUTE-002MEDIUMPublic subnet hosting non-public-facing services
NETWORK-ROUTE-003MEDIUMTGW attached but no route propagation
NETWORK-ROUTE-004HIGHVPC peering missing return route
NETWORK-ROUTE-005MEDIUMBlackhole route present
NETWORK-ROUTE-006LOWRoute to deprecated/deleted gateway
NETWORK-ROUTE-007HIGHCompliance-scoped subnet reachable via TGW from non-scoped subnet
NETWORK-ROUTE-008HIGHOn-premises CIDR reachable from internet-egress subnet (pivot path)

Limitations

  • No BGP path computation. We use installed RIB entries, not simulated best-path selection. BGP path simulation is deferred to Build 90.5.
  • No ECMP flow-hash modeling. Multiple equal-cost next-hops are treated as parallel valid paths.
  • No encrypted overlay tunnel introspection. IPsec/WireGuard/GRE tunnel endpoints are noted but not traced through.
  • Stale between scans. Reachability is recomputed per-scan. Cache TTL is 5 minutes; invalidate on scan completion via reachability.DefaultCache.Invalidate(tenantID).
  • Azure route table subnet associations use the raw ARM resource ID as the subnet node ID. Ensure Azure subnet discovery runs before route table discovery to get full join.

Source Files

ComponentFile
AWS route parserplugins/discovery/aws/ec2.goDiscoverRouteTables
Azure route parserplugins/discovery/azure/network.goDiscoverRouteTables
GCP route parserplugins/discovery/gcp/compute.goDiscoverRoutes
Cisco IOS RIB→edgeplugins/discovery/cisco-ios/ios.gogetRoutingTable
Juniper Junos RIB→edgeplugins/discovery/juniper-junos/junos.gogetRoutingTable
Palo Alto RIB→edgeplugins/discovery/palo-alto/discovery.go
Fortinet RIB→edgeplugins/discovery/fortinet-fortigate/fortigate.goDiscoverRoutes
Reachability engineReachability module
Path tracer integrationPath analysis module
API handlersNetwork routing handlers
API routesRoutes configuration
Finding rulesrules/network_routing.yaml
Topology routing layerui/src/components/TopologyMap.tsx
Subnet reachability tabui/src/components/NodeCard.tsx
Network Connectivity pageui/src/pages/NetworkConnectivity.tsx

Build 90.5 Enhancements

Build 90.5 extends this model with three additional capabilities:

  • BGP Path Modeling — RFC 4271 best-path selection, best vs backup path visibility, route hijack detection
  • ECMP & Flow-Hash Modeling — Deterministic per-flow path prediction using platform-specific hash algorithms
  • Tunnel Introspection — Reachability computation through IPsec, WireGuard, GRE, and VXLAN tunnels

These add 13 new finding rules (5 BGP, 3 ECMP, 5 tunnel) and extend the connectivity matrix with via_tunnel, via_bgp_dynamic, and ecmp_groups columns.