Design Partner Program
Hayrok/Resources/Blog/Research Notes
HAYROK LABS RESEARCH NOTE · HL-RN-2026-08 Attack path validation

How to find and validate attack paths in your environment.

An attack graph is a hypothesis. Validation makes it a fact. Attackers walk the edges, not the scanner's list of nodes.

This note covers a five-stage method to find every path in your estate, prune the ones that reach nothing, and prove the ones that are real.

Hayrok Labs Nov 2, 2026 @Melly 10 min read
THE PIPELINE WORKED EXAMPLE 1 PROVEN PATH
01
Build one graph
8 edges · scanner, firewall, EDR, IAM, RBAC
02
Prune and rank
2 candidate paths · dead end: dev-sandbox
03
Prove the hops
vpn-gw → jump-01 blocked · 1 path to payments-db
ACTION Break it at svc-deploy: remove one RBAC verb instead of rebuilding a jump host.
TL;DR
01
Only about 10% of privilege escalation techniques are fixed by patching. The rest of the attack graph is permissions, configuration, credentials and trust.
02
Build one graph across every domain, prune the paths that reach nothing, then prove the hops that are left. An unproven hop is a hypothesis.
03
Further down: a small, runnable model of the pipeline, covering graph, candidate paths, pruning and choke point ranking.

Attack paths are built from much more than vulnerabilities. Misconfigurations, excessive permissions, cached credentials, trust relationships and, now, AI agent identities all form edges an attacker can walk. This note lays out a five-stage method to find attack paths across every domain of an estate and validate them: build a single graph, generate candidate paths, prune the dead ends, validate each remaining hop with a safe test, and break the paths that prove real. A path that has not been validated is a hypothesis, and a program built on hypotheses fixes the wrong things.

Key findings

EDGES FIXED BY PATCHING
~10%
Privilege management covers about 65%, configuration 33%, password policy 30%.
IAAS ADMIN WITHOUT MFA
37%
Of organizations. Identity edges are wide open.
THIRD-PARTY BREACHES
48%
Third parties took nearly 8 months to resolve half of their weak password and permission findings.
ACCESS FOR SALE
44% · 35%
VPN and remote desktop, as shares of connection types offered by initial access brokers.
ATT&CK V20 · 13 OCT 2026 New techniques for prompt injection and AI-enabled exfiltration. AI agents and their tool permissions now belong in the graph.
A vulnerability scanner sees the nodes. Attackers walk the edges. Attack path validation has to see both.

Why attack path programs stall

Most teams that try this hit one of four walls.

Single-domain graphs

A graph built only from vulnerability data, or only from Active Directory, misses the paths that cross domains.

Path explosion

A full graph produces thousands of theoretical paths. Without pruning and proof, nobody can tell which ones matter.

Inferred hops

Many tools assume a hop works because a permission or port exists. Controls, segmentation and conditional access often stop it in practice.

Stale graphs

A graph built monthly is wrong by the second day after a busy deploy.

The attack path pipeline

Six data domains feed one graph. Pruning cuts the theoretical paths down, validation proves the rest, and every change event restarts the loop.

SIX DOMAINS IN
Vulns
Identities
Cloud IAM
Network
SaaS + CI/CD
AI agents
↓
01
One graph
02
Candidate paths
thousands
03
Prune
dead ends out
04
Validate hops
proven · blocked · undetermined
05
Score and break
↺ every change event feeds back into 01

The method: five stages from graph to proof

01

Build one graph

Ingest assets, vulnerability findings, identities and group memberships, cloud IAM policies, network reachability, SaaS and CI/CD trust, and AI agent tool permissions. Represent each as nodes and edges with a source and a timestamp.
02

Generate candidate paths

Compute paths from realistic entry points, such as internet-facing services, phishable users and third-party connections, to each crown jewel.
03

Prune dead ends

Drop paths that cannot reach a crown jewel and collapse duplicates. Rank the rest by length, by the value of the target and by how many paths share each node.
04

Validate each hop

For the top-ranked paths, prove every edge with a safe, governed test: trigger the exploit, use the credential in a controlled way, call the permission. Mark each hop proven, blocked or undetermined.
05

Score and break

Fix the choke points on proven paths first, then rerun the hops to confirm each path is broken. Feed every change event back into stage 1.

Worked example: the pipeline in 40 lines

Let's model the pipeline with Python and the open source networkx library. Real estates have millions of edges, but the logic is exactly the same.

Stages 1 to 3: build, generate and prune

Python · networkx
import networkx as nx

G = nx.DiGraph()
# Each edge records how the hop works and where the data came from
edges = [
    ("internet",      "vpn-gw",        {"via": "CVE on edge device",     "src": "scanner"}),
    ("phish-user",    "laptop-114",    {"via": "initial access",         "src": "assumed"}),
    ("laptop-114",    "jump-01",       {"via": "RDP allowed",            "src": "firewall"}),
    ("vpn-gw",        "jump-01",       {"via": "flat network",           "src": "firewall"}),
    ("jump-01",       "svc-deploy",    {"via": "cached credential",      "src": "edr"}),
    ("svc-deploy",    "k8s-payments",  {"via": "get secrets",            "src": "k8s rbac"}),
    ("k8s-payments",  "payments-db",   {"via": "role credential",        "src": "cloud iam"}),
    ("laptop-114",    "dev-sandbox",   {"via": "local admin",            "src": "ad"}),
]
G.add_edges_from(edges)

entries = ["internet", "phish-user"]
jewels  = ["payments-db"]

# Stage 2: candidate paths from every entry to every jewel
paths = [p for e in entries for j in jewels
         for p in nx.all_simple_paths(G, e, j, cutoff=8)]

# Stage 3: anything not on a path to a jewel is a dead end
on_path = {n for p in paths for n in p}
dead_ends = set(G.nodes) - on_path
print(len(paths), "paths |", "dead ends:", dead_ends)
# 2 paths | dead ends: {'dev-sandbox'}

Ranking the choke points

Count how many entry-to-jewel paths run through each node. Betweenness restricted to your entries and jewels gives you the same signal at scale.

Python
from collections import Counter

load = Counter(n for p in paths for n in p[1:-1])
print(load.most_common(3))
# [('jump-01', 2), ('svc-deploy', 2), ('k8s-payments', 2)]

choke = nx.betweenness_centrality_subset(G, sources=entries, targets=jewels)
PATHS CARRIED PER NODE
jump-01
2
svc-deploy
2
k8s-payments
2

Three nodes carry both paths. Of those, svc-deploy is the cheapest to fix, because removing one RBAC verb is a lot easier than rebuilding a jump host.

Stage 4: prove the hops that are left

Every edge above has a src. Edges marked assumed, or inferred from a single data source, go to validation first. Prove them with read-only checks, such as kubectl auth can-i for RBAC edges and aws iam simulate-principal-policy for cloud edges. Then write the result back to the edge:

Python
G["svc-deploy"]["k8s-payments"]["proven"] = True   # kubectl auth can-i: yes
G["vpn-gw"]["jump-01"]["proven"] = False          # segmentation blocked the hop
Route via vpn-gw
Dies at the segmentation check. Not a real path.
Route via laptop-114
The single proven path to the payments database.

A path counts as real only when every edge on it is proven.

How to measure the outcome

Five numbers that tell you whether your graph matches reality.

Proven path count
Fully validated paths from an entry point to a crown jewel.
Hop proof rate
The share of inferred hops that held up under validation. A low rate means your model overstates risk.
Domain coverage
The share of graph domains ingested, including identity, cloud, SaaS and AI agents.
Graph freshness
Hours between a change in the environment and its appearance in the graph.
Break verification rate
Fixes confirmed by rerunning the path.

How Hayrok approaches attack path validation

One graph, real edges, proven hops.

AGIE
The Attack Graph Intelligence Engine builds one graph across vulnerabilities, identities, cloud permissions, network reachability and software runtime.
CodeFabrics
Adds which vulnerable code actually runs, so software edges are real rather than packaged.
Validates the hops on the highest-ranked paths through a Private Runner, under governed scope and approval.
Stores each hop's evidence.
Risk Engine
Ranks proven paths by the value of the target and the number of routes each choke point carries.
Hay Assist
Answers plain questions about any path, such as which change opened it.

Prefer to start from the asset and work backward? Read How to Validate an Attack Path Before It Reaches a Crown Jewel.

FAQ

How do I find attack paths in my environment?

Build a single graph from assets, vulnerabilities, identities, cloud permissions and network reachability, then compute paths from realistic entry points to your critical assets.

What is the difference between attack path analysis and attack path validation?

Analysis infers paths from data. Validation proves each hop with a safe test, so the paths you report are paths an attacker could actually walk.

Do attack paths only involve vulnerabilities?

No. Most edges are misconfigurations, permissions, credentials and trust relationships. CVEs are a small share.

Should AI agents be part of the attack graph?

Yes. Agents hold identities and tool permissions. ATT&CK v20 added prompt injection and AI-enabled exfiltration, so agent edges are now part of the threat model.

How often should attack paths be revalidated?

Continuously for change events that touch a proven path, and on a regular cadence for the full graph.

Find the paths that are real

We will build a graph across your domains, prune it to the paths that matter and prove the top routes hop by hop.

KEEP READING