Skip to content
Security
Skill

/prowler-attack-paths-query

Creates Prowler Attack Paths openCypher queries using the Cartography schema as the source of truth for node labels, properties, and relationships. Covers Prowler-specific additions (Internet node, ProwlerFinding, internal isolation labels), $provider_uid scoping, and

From plugin
prowler
15k39 skills1 MCP

Claude Code

$ npx -y skills add prowler-cloud/prowler --skill prowler-attack-paths-query --agent claude-code

SKILL.md

prowler-attack-paths-query.SKILL.md
name: prowler-attack-paths-query
description: >
  Creates Prowler Attack Paths openCypher queries using the Cartography schema as the source of truth
  for node labels, properties, and relationships. Covers Prowler-specific additions (Internet node,
  ProwlerFinding, internal isolation labels), $provider_uid scoping, and list-property item nodes
  with typed `HAS_*` edges that run efficiently on both Neo4j and Amazon Neptune sinks.
  Trigger: When creating or updating Attack Paths queries.
license: Apache-2.0
metadata:
  author: prowler-cloud
  version: "3.2"
  scope: [root, api]
  auto_invoke:
    - "Creating Attack Paths queries"
    - "Updating existing Attack Paths queries"
    - "Adding privilege escalation detection queries"
allowed-tools: Read, Edit, Write, Glob, Grep, Bash, WebFetch, Task

Overview

Attack Paths queries are read-only openCypher queries over a Cartography-ingested cloud graph that detect privilege escalation chains, network exposure, and other graph-shaped security risks. Queries are written in openCypher Version 9 so they run on both Neo4j and Amazon Neptune sinks.

This skill is the concise, action-oriented reference for building queries. For the complete human-readable reference (graph model, list-typed and JSON-encoded properties, compatibility, and worked examples), see `docs/developer-guide/attack-paths-queries.mdx`.

---

Two query audiences

| | Predefined queries | Custom queries | | ------------------ | ----------------------------------------------------------- | --------------------------------------------------------------------- | | Where they live | `api/src/backend/api/attack_paths/queries/aws.py` (only provider registered today) | User-supplied via the custom query API endpoint (max 10,000 chars, blocked-pattern check in `validate_custom_query`) | | Provider isolation | `AWSAccount {id: $provider_uid}` anchor + path connectivity | Automatic `_Provider_{uuid}` label injection by `cypher_sanitizer.py` | | What to write | Chain every MATCH from the `aws` variable | Plain Cypher, no isolation boilerplate | | Internal labels | Never use | Never use (system-injected) |

**Predefined queries**: every node must be reachable from the `AWSAccount` root via graph traversal. That is the isolation boundary.

**Custom queries**: write natural Cypher. The runner injects a `_Provider_{uuid}` label into every node pattern, and a post-query filter handles edge cases.

---

Input sources

Two sources for new queries:

1. **pathfinding.cloud ID** (e.g. `ECS-001`, `GLUE-001`), the Datadog research catalogue. The aggregated `paths.json` is too large for WebFetch:

   # Fetch a single path by ID
   curl -s https://raw.githubusercontent.com/DataDog/pathfinding.cloud/main/docs/paths.json \
     | jq '.[] | select(.id == "ecs-002")'

   # List all path IDs and names
   curl -s https://raw.githubusercontent.com/DataDog/pathfinding.cloud/main/docs/paths.json \
     | jq -r '.[] | "\(.id): \(.name)"'

   # Filter by service prefix
   curl -s https://raw.githubusercontent.com/DataDog/pathfinding.cloud/main/docs/paths.json \
     | jq -r '.[] | select(.id | startswith("ecs")) | "\(.id): \(.name)"'

If `jq` is unavailable, use `python3 -c "import json,sys; ..."`.

2. **Natural language description** from the requester.

---

Query structure

Provider scoping parameter

| Parameter | Property | Used on | Purpose | | --------------- | -------- | ------------ | -------------------------------------- | | `$provider_uid` | `id` | `AWSAccount` | Scopes the query to a specific account |

The runner binds `$provider_uid` automatically. Every other node is isolated by path connectivity from the `AWSAccount` anchor.

Imports

from api.attack_paths.queries.types import (
    AttackPathsQueryAttribution,
    AttackPathsQueryDefinition,
    AttackPathsQueryOutcome,
    AttackPathsQueryParameterDefinition,
)
from tasks.jobs.attack_paths.config import PROWLER_FINDING_LABEL

Always use `PROWLER_FINDING_LABEL` via f-string interpolation, never hardcode `"ProwlerFinding"`.

Definition fields

  • **id**: kebab-case `{provider}-{description}`, e.g. `aws-ec2-privesc-passrole-iam`.
  • **name**: short, human-friendly label. Sourced queries append the reference ID: `"EC2 Instance Launch with Privileged Role (EC2-001)"`.
  • **short_description**: one sentence, no technical permissions.
  • **description**: full technical explanation, plain text.
  • **provider**: `aws`. `registry.py` only registers `AWS_QUERIES`, and only AWS has Cartography ingestion today (`tasks/jobs/attack_paths/scan.py`).
  • **outcome**: required in practice (`test_every_query_has_an_outcome`). One of `AttackPathsQueryOutcome.CODE_EXECUTION`, `PRIVILEGE_ESCALATION`, `PUBLIC_EXPOSURE`, `RESOURCE_INVENTORY` (partial/latent). The UI renders it as the terminal node.
  • **cypher**: f-string Cypher body. Literal `{` / `}` are escaped as `{{` / `}}`.
  • **parameters**: `parameters=[]` if none.
  • **attribution**: optional `AttackPathsQueryAttribution(text, link)` for sourced queries. `link` uses the lowercase ID.

Append the constant to the `{PROVIDER}_QUERIES` list at the bottom of the provider file.

---

Predefined query template

The canonical shape combines a principal walk, an optional target walk, deduplicated nodes, and a typed finding overlay:

AWS_{QUERY_NAME} = AttackPathsQueryDefinition(
    id="aws-{kebab-case-name}",
    name="{Label} ({REFERENCE_ID})",
    short_description="{One sentence.}",
    description="{Full technical explanation.}",
    attribution=AttackPathsQueryAttribution(
        text="pathfinding.cloud - {REFERENCE_ID} - {permission}",
Read more
@prowler-cloud
Ships withprowler

Prowler is the world’s most widely used Open-Source Cloud Security Platform that automates security and compliance across any cloud environment.

15k39 skills1 MCP
Get the whole plugin

Stars on GitHub

Momentum

stars in total
15.2k
Star history of prowler-cloud/prowler on GitHub, a chart by star-history.com

Other skills on prowler.

ai-sdk-5

ai-sdk-5

Vercel AI SDK patterns for the installed major (ui/package.json: `ai` 6.x, `@ai-sdk/react` 3.x). The skill name is historical;…

django-drf

django-drf

Django REST Framework patterns. Trigger: When implementing generic DRF APIs (ViewSets, serializers, routers, permissions,…

gh-aw

gh-aw

Create and maintain GitHub Agentic Workflows (gh-aw) for Prowler. Trigger: When creating agentic workflows, modifying gh-aw…

jsonapi

jsonapi

Strict JSON:API v1.1 specification compliance. Trigger: When creating or modifying API endpoints, reviewing API responses, or…

More skills from other plugins.

api-security

api-security

Use for authorized security assessment of REST, GraphQL, WebSocket, or SOAP APIs, including discovery, authentication,…

@zhaoxuya520@zhaoxuya520Install Skill
nemoclaw-user-guide

nemoclaw-user-guide

Find official NemoClaw documentation for installation, configuration, operation, or troubleshooting. Also handles requested docs…

nemoclaw10d23k
@nvidia@nvidiaInstall Skill

Questions about prowler-attack-paths-query.

Which coding agents can use prowler-attack-paths-query?
prowler-attack-paths-query installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.