Skip to content
Markdown

Claude Code pentest subagents

Scope: pentest-ai-agents (0xSteph/pentest-ai-agents), an MIT-licensed collection of Claude Code subagents that turn Claude into an offensive-security research assistant for authorized penetration testing. This page covers the prompt-only architecture (no servers, no Python), the two-tier model that separates advisory agents from execution-capable ones, the mandatory scope-guard block, and the hard-refusal list that no user authorization overrides. It sits in the agentic cybersecurity and SysOps index next to the tool-executing engines ptai and GHOSTCREW/TARS, and it is a concrete instance of the agent policy engine and risk-tiered approval patterns.

Examined at commit c8dcc809 (2026-08-08) of 0xSteph/pentest-ai-agents, MIT, VERSION 3.4.0. The scope-guard invariant below was executed against the real agents/ directory: 52 routable agent files (each with name: frontmatter, excluding the shared _scope-guard.md), of which 13 are Bash-capable, and all 13 carry the mandatory scope block. The README markets "50" subagents (and the badge reads Agents-50); the actual routable count at this commit is 52, so read "50" as a rounded headline. These are prompts, not executables: the agents run inside your Claude Code session with the permissions you grant it, so the safety properties are prompt-enforced and session-enforced, not sandboxed by the package.

What it is

pentest-ai-agents is a directory of Markdown agent definitions you copy into Claude Code. Each file carries YAML frontmatter (name, description, tools, model) and a system prompt with deep domain knowledge for one area: recon, web, Active Directory, cloud, mobile, wireless, social engineering, payload crafting, reverse engineering, exploit chaining, detection engineering, forensics, and more. You install the files, open Claude Code, describe your task, and Claude routes to the right specialist based on each agent's description. There are no servers, no Python dependencies, and no setup beyond copying files; it also installs as a Claude Code plugin.

The security model is two-tier. Tier 1 agents are advisory: they analyze output you paste, plan engagements, and reason about findings without a Bash tool, so they cannot execute against a target. Tier 2 agents are execution-capable: they carry Bash and can run commands directly when authorized. Every Tier 2 agent must embed the shared scope-enforcement prompt from agents/_scope-guard.md (the underscore prefix signals Claude Code should not route to it). That block requires the agent to obtain a declared scope before running anything, validate every target against it, tag each command with a noise level (QUIET/MODERATE/LOUD), prefer the least-aggressive option, and refuse a hard list of techniques regardless of claimed authorization.

Why use it

  • Zero-infrastructure specialists. No MCP server or tool installation; the agents are prompts that give Claude domain depth and a disciplined method. Install is two lines as a plugin.
  • Scope discipline is built in. Execution-capable agents refuse to act without a declared scope and validate every target against it, which is the single most important control for an agent that can run nmap or sqlmap.
  • A hard-refusal floor. Denial-of-service, mass internet scanning, self-propagating worms, persistent backdoors, false-flag operations, and safety-of-life exploitation are refused no matter what the user claims is authorized.
  • Detection pairing. Every offensive agent pairs its techniques with the detection they exercise, which makes the toolkit useful to blue teams reading the same files.
  • CI-enforced invariant. A SHA-pinned, least-privilege workflow validates each agent's frontmatter and requires the scope-guard block on every Bash-capable agent; the v3.3 notes record it catching a real gap (cicd-redteam was missing the block).

When to use it (and when not)

Use it inside Claude Code for authorized penetration testing where you want a disciplined specialist for a specific domain and you are comfortable that safety is prompt-enforced within a session you control. It pairs well with a findings database (findings.sh) the agents log to, so work is not duplicated across sessions.

Do not mistake prompt-enforced scope for a sandbox: these agents run with your Claude Code permissions, so the containment is the model following its instructions plus whatever sandboxing and permission gating you place around Claude Code itself. Do not use it without authorization; it is offensive tooling with an explicit legal section. Do not assume the marketed agent count or capability list is exact (the routable count is 52, not 50). Do not rely on it for the actual exploit verification that ptai provides; these agents plan and execute, they do not machine-prove findings.

Architecture

flowchart TB
  USER["Operator in Claude Code"] --> ROUTE["Claude routes by agent description"]
  ROUTE --> T1["Tier 1: advisory (no Bash)"]
  ROUTE --> T2["Tier 2: execution-capable (Bash)"]
  T2 --> GUARD["_scope-guard.md block (mandatory)"]
  GUARD --> SCOPE{"Target in declared scope?"}
  SCOPE -->|"no"| REFUSE["Refuse and explain"]
  SCOPE -->|"yes"| HARD{"Hard-refusal category?"}
  HARD -->|"yes"| REFUSE
  HARD -->|"no"| RUN["Run, tag noise level, log to findings.sh"]

The scope-guard invariant, executed

The safety property that matters is structural: no execution-capable agent may exist without the scope block. That is checkable, and the model below both models the runtime decision (declare scope, then allow in-scope, refuse out-of-scope, refuse the hard list) and asserts the registry-level invariant that every Bash-capable agent carries the guard.

# A small faithful registry: (name, tools, has_scope_guard_block).
REGISTRY = [
    ("ad-attacker",        {"Bash", "Read", "Write"}, True),
    ("exploit-chainer",    {"Bash", "Read"},          True),
    ("threat-modeler",     {"Read"},                  False),  # Tier 1: advisory, no Bash
    ("engagement-planner", {"Read", "Write"},         False),  # Tier 1
]

HARD_REFUSAL = {"volumetric_dos", "mass_internet_scan", "self_propagating_worm",
                "persistent_backdoor", "false_flag", "safety_of_life"}


def tier(tools):
    return 2 if "Bash" in tools else 1


def may_execute(agent_tools, has_guard, declared_scope, target, category):
    """Runtime gate for a Tier 2 agent composing a command."""
    if tier(agent_tools) == 1:
        return False, "advisory agent: cannot execute"
    if not has_guard:
        return False, "Tier 2 agent without scope guard: refuse to run"
    if not declared_scope:
        return False, "no scope declared: advisory mode only"
    if category in HARD_REFUSAL:
        return False, f"hard-refusal category '{category}': no authorization overrides"
    if target not in declared_scope:
        return False, f"target {target} outside declared scope"
    return True, "in scope, permitted category: run and tag noise level"


scope = {"10.0.0.5", "app.staging.example.com"}

# 1. In-scope, permitted category -> allowed.
ok, why = may_execute({"Bash"}, True, scope, "10.0.0.5", "port_scan")
print("in-scope tcp scan   :", ok, "-", why)
assert ok

# 2. Out-of-scope target -> refused.
ok, why = may_execute({"Bash"}, True, scope, "8.8.8.8", "port_scan")
print("out-of-scope target :", ok, "-", why)
assert not ok

# 3. Hard-refusal category -> refused even in scope.
ok, why = may_execute({"Bash"}, True, scope, "10.0.0.5", "volumetric_dos")
print("in-scope DoS request:", ok, "-", why)
assert not ok

# 4. No scope declared -> advisory only.
ok, why = may_execute({"Bash"}, True, set(), "10.0.0.5", "port_scan")
print("no scope declared   :", ok, "-", why)
assert not ok

# 5. THE INVARIANT: every Bash-capable agent in the registry carries the guard.
tier2 = [(n, g) for (n, t, g) in REGISTRY if tier(t) == 2]
missing = [n for (n, g) in tier2 if not g]
print(f"tier2 agents: {len(tier2)}, missing scope guard: {missing}")
assert missing == []
print("OK: scope is declared-then-validated, the hard list is absolute, and no "
      "execution-capable agent exists without the guard")

Executed output:

in-scope tcp scan   : True - in scope, permitted category: run and tag noise level
out-of-scope target : False - target 8.8.8.8 outside declared scope
in-scope DoS request: False - hard-refusal category 'volumetric_dos': no authorization overrides
no scope declared   : False - no scope declared: advisory mode only
tier2 agents: 2, missing scope guard: []
OK: scope is declared-then-validated, the hard list is absolute, and no execution-capable agent exists without the guard

Run against the real repository, the same invariant holds at full scale: of 52 routable agents, 13 are Bash-capable and all 13 embed the Scope Enforcement (MANDATORY) block. That is the property the CI workflow enforces on every change, and it is why a drive-by contribution cannot add an executing agent that skips the guard.

How to use it

Install as a plugin or via the installer:

# Plugin path (two lines inside Claude Code):
/plugin marketplace add 0xSteph/pentest-ai-agents
/plugin install pentest-ai-agents@pentest-ai-agents

# Or the curl installer (also installs slash commands):
curl -fsSL https://raw.githubusercontent.com/0xSteph/pentest-ai-agents/main/install.sh | bash

Then open Claude Code, describe the authorized task, and Claude routes to a specialist. The first thing a Tier 2 agent does is ask you to declare scope and engagement type; until you do, it stays in advisory mode and will only analyze output you paste. If findings.sh is on PATH, agents log hosts, services, vulnerabilities, and credentials to a shared findings database and check it to avoid duplicate work.

How to develop with it

An agent is one Markdown file: frontmatter plus a system prompt. To add an execution-capable specialist, give it Bash in tools and paste the scope-enforcement block from _scope-guard.md into its prompt (or the CI validator will reject it). Keep advisory agents out of Bash entirely. The v3.3 changelog documents the CI validator that checks frontmatter, requires the guard on Bash agents, validates the plugin manifests, and smoke-tests the installer; run it before opening a PR. A minimal offline Docker bundle with a digest-pinned base and non-root user ships for packaging, though it bakes in no tooling.

How to maintain it

Pin to a VERSION (3.4.0 here) or a commit; the agent set grows across releases (35 to 50 in v3.3, and 52 files at this commit), and the findings-database schema has migrated (db/migrate.sh moves existing engagements forward). Re-diff _scope-guard.md on update, since it is the single source of the safety block every Tier 2 agent inlines; a change there does not propagate automatically to agents that already copied it.

How to run it in production

"Production" is an authorized engagement driven from a Claude Code session you control. The real containment is the layer around Claude Code, not the package: run it under a permission profile that gates shell execution, put the whole session behind a sandbox and egress controls, and use the risk-tiered approval gate for anything that mutates a target. Declare scope explicitly and narrowly; the guard validates against exactly what you declared. Preserve the evidence files the guard writes (timestamped per tool and target) and secure or transfer them at session end.

Failure modes

  • Prompt-enforced, not sandboxed. Scope and the hard list live in the agent's prompt. A capable model follows them, but the package does not sandbox execution; your Claude Code permission setup is the real boundary.
  • Copied guard drift. Each Tier 2 agent inlines the guard text. If _scope-guard.md changes, already-shipped agents keep the old copy until edited.
  • Marketing count. The routable agent count (52) exceeds the headline "50"; do not treat the README's counts or capability bullets as an exact contract.
  • Domain breadth includes dual-use. The set includes C2 profile tuning, container breakout, and evasion agents. They pair techniques with detection, but they are offensive; authorization and the hard-refusal list are what keep use legitimate.

References

  • pentest-ai-agents repository (0xSteph), pinned commit c8dcc809: https://github.com/0xSteph/pentest-ai-agents
  • Scope-guard block (agents/_scope-guard.md): https://github.com/0xSteph/pentest-ai-agents/blob/main/agents/_scope-guard.md
  • Installer and plugin manifests: https://github.com/0xSteph/pentest-ai-agents/blob/main/install.sh
  • Companion tool-executing engine (ptai): https://github.com/0xSteph/pentest-ai

Related: Agentic cybersecurity and SysOps index · Earned-verdict pentesting with ptai · Agentic pentest orchestration: PTT and CrewAI · Agent policy engine · Risk-tiered human approval gates · Agent sandboxing and isolation