Skip to content

attack_paths

Graph · From docs/MCP_TOOLS.md on GitHub

Category graph · sensitivity confidential · capabilities read_state · readOnly true, destructive false, idempotent true, openWorld false · outputSchema yes · timeout: layer default (300 s)

Shortest routes from the internet to sensitive assets over the flow graph, ranked. A virtual entry node is linked to every internet entry point (the 0.0.0.0/0 and ::/0 nodes and the sources of internet-sourced ingress rules, Azure Internet, Any and * included) and to every asset flagged internet-exposed, and Dijkstra from it (unweighted, so hop counts) finds one shortest path to each target within max_depth hops. Without target, the targets are all crown-jewel assets (see Risk scores for the weights); with target, only that asset, at weight 10.

Argument Type Default Constraints Description
target string "" Asset to reach; empty = every crown-jewel asset (databases, buckets, secrets, keys, roles).
max_depth integer 8 1..12 Longest path from the entry point, in hops.
max_paths integer 20 1..100 Maximum paths returned after ranking.
dataset string "" Dataset name (see list_datasets). Empty = the active dataset.

Each path is a find_paths-style path (the virtual entry node is dropped, so it starts at the exposed asset or at an entry point such as 0.0.0.0/0) plus entry (internet-exposed asset or internet-sourced rule), target_weight, findings_on_path (open findings on every hop) and score. The result has paths (at most max_paths), total_found, truncated and targets_considered. When nothing is exposed it returns no paths and a hint.

Called with the arguments below, attack_paths returned this structuredContent.

{"max_paths": 3}
{
  "dataset": "sample",
  "paths": [
    {
      "length": 4,
      "nodes": [
        {
          "id": "alb-web",
          "name": "web-alb",
          "type": "LOAD_BALANCER",
          "account_id": "111111111111",
          "internet_exposed": true,
          "open_findings": 0
        },
        {
          "id": "tg-web",
          "name": "web-tg",
          "type": "TARGET_GROUP",
          "account_id": "111111111111",
          "internet_exposed": false,
          "open_findings": 0
        },
        "... 3 more"
      ],
      "edge_types": [
        "LOAD_BALANCER_TARGET",
        "LOAD_BALANCER_TARGET",
        "ASSUMES_ROLE",
        "... 1 more"
      ],
      "summary": "web-alb -> web-tg -> web-1 -> app-role -> orders-db",
      "entry": "internet-exposed asset",
      "target_weight": 10,
      "findings_on_path": 2,
      "score": 9.8
    },
    {
      "length": 2,
      "nodes": [
        {
          "id": "bastion",
          "name": "bastion",
          "type": "EC2",
          "account_id": "111111111111",
          "internet_exposed": true,
          "open_findings": 1,
          "max_severity": "HIGH"
        },
        {
          "id": "admin-role",
          "name": "bastion-admin",
          "type": "IAM_ROLE",
          "account_id": "111111111111",
          "internet_exposed": false,
          "open_findings": 0
        },
        {
          "id": "db-secret",
          "name": "orders-db-credentials",
          "type": "SECRET",
          "account_id": "111111111111",
          "internet_exposed": false,
          "open_findings": 0
        }
      ],
      "edge_types": [
        "ASSUMES_ROLE",
        "GRANTS_ACCESS"
      ],
      "summary": "bastion -> bastion-admin -> orders-db-credentials",
      "entry": "internet-exposed asset",
      "target_weight": 9,
      "findings_on_path": 1,
      "score": 8.9
    },
    {
      "length": 1,
      "nodes": [
        {
          "id": "az-vm",
          "name": "jump-vm",
          "type": "VIRTUAL_MACHINE",
          "account_id": "00000000-aaaa-bbbb-cccc-000000000001",
          "internet_exposed": true,
          "open_findings": 0
        },
        {
          "id": "az-kv",
          "name": "hub-kv",
          "type": "KEY_VAULT",
          "account_id": "00000000-aaaa-bbbb-cccc-000000000001",
          "internet_exposed": false,
          "open_findings": 0
        }
      ],
      "edge_types": [
        "GRANTS_ACCESS"
      ],
      "summary": "jump-vm -> hub-kv",
      "entry": "internet-exposed asset",
      "target_weight": 9,
      "findings_on_path": 0,
      "score": 8.7
    }
  ],
  "total_found": 11,
  "truncated": true,
  "targets_considered": 14
}

One target:

Called with the arguments below, attack_paths returned this structuredContent.

{"target": "db-secret"}
{
  "dataset": "sample",
  "paths": [
    {
      "length": 2,
      "nodes": [
        {
          "id": "bastion",
          "name": "bastion",
          "type": "EC2",
          "account_id": "111111111111",
          "internet_exposed": true,
          "open_findings": 1,
          "max_severity": "HIGH"
        },
        {
          "id": "admin-role",
          "name": "bastion-admin",
          "type": "IAM_ROLE",
          "account_id": "111111111111",
          "internet_exposed": false,
          "open_findings": 0
        },
        {
          "id": "db-secret",
          "name": "orders-db-credentials",
          "type": "SECRET",
          "account_id": "111111111111",
          "internet_exposed": false,
          "open_findings": 0
        }
      ],
      "edge_types": [
        "ASSUMES_ROLE",
        "GRANTS_ACCESS"
      ],
      "summary": "bastion -> bastion-admin -> orders-db-credentials",
      "entry": "internet-exposed asset",
      "target_weight": 10,
      "findings_on_path": 1,
      "score": 9.9
    }
  ],
  "total_found": 1,
  "truncated": false,
  "targets_considered": 1
}

Related: find_paths(source="internet", target=...) for alternative routes to one target, findings_for_asset on each hop, the attack_surface_report prompt.