Skip to content
Markdown

Autonomous web pentesting with Shannon

Scope: Shannon (KeygraphHQ/shannon), the open-source (AGPL-3.0) autonomous AI pentester for web applications and APIs. This page covers its multi-agent, white-box workflow (source analysis feeding live exploitation), the proof-by-exploitation reporting model, the ephemeral-container isolation it runs in, and its stated limits. It sits in the agentic cybersecurity and SysOps index alongside earned-verdict pentesting with ptai, which shares the "only report what you can prove" philosophy through a different mechanism, and it inherits the whole agent security threat model.

Examined at commit 760a1402 (2026-08-07) of KeygraphHQ/shannon, AGPL-3.0. Shannon is a TypeScript worker built on the Pi agent core (@earendil-works/pi-agent-core and pi-ai, both ^0.82.1). The agent graph model below was executed and asserted against the exact AGENTS map in apps/worker/src/session-manager.ts. No pentest was run here: Shannon executes real exploits inside a Docker worker against a live target and needs an LLM key, so every coverage and timing figure is the project's own, read from its README and sample reports, not measured on this host. This is Shannon Open Source, the standalone CLI; the same engine powers the commercial Keygraph platform, which is out of scope.

What it is

Shannon is an autonomous pentester that combines white-box source analysis with live exploitation. You point it at a running application and its source repository; it reads the code to identify likely attack surfaces, then uses browser automation and command-line tools to attempt real exploits against the running app and its APIs. The defining rule is that only vulnerabilities with a working proof-of-concept reach the final report: speculative or static-only findings are discarded. A run produces a Markdown report of proven findings with reproducible steps.

Internally it is a fixed multi-agent pipeline. apps/worker/src/session-manager.ts defines an AGENTS map with explicit prerequisites: a pre-recon agent (source scan), a recon agent (live attack-surface mapping), five vulnerability-analysis agents (Injection, XSS, Auth, SSRF, Authz), five matching exploitation agents, and a report agent that depends on all five exploits. Each phase is a specialized prompt template (prompts/vuln-injection.txt, prompts/exploit-xss.txt, and so on) run by the Pi agent core, writing a deliverable file that the next phase consumes.

Why use it

  • Proof by exploitation. The report contains validated findings with reproducible proof-of-concept steps, not a scanner's list of maybes. That is the single most valuable property for a security team drowning in false positives.
  • White-box attack planning. Source analysis focuses the dynamic testing on realistic attack paths rather than blind fuzzing.
  • On-demand cadence. Teams ship code daily but pentest annually; Shannon closes that gap by running against every build or release.
  • Runs on your own credentials. Bring an Anthropic, OpenAI, xAI, or Bedrock key; the shannon-v1 branch even accepts a Claude Code OAuth token so a run costs nothing beyond an existing subscription.
  • Authenticated testing. Config files describe login flows, test credentials, TOTP, email-based login, focus areas, and rules of engagement.

When to use it (and when not)

Use it against staging or local instances of applications you own or are explicitly authorized to test, where you have the source, and where you want exploited-and-proven findings for the classes it covers (Injection, XSS, SSRF, Broken Authentication, Broken Authorization). It fits a CI or pre-release gate.

Do not run it against production: its exploitation agents create users, submit forms, mutate application state, and trigger outbound requests. Do not treat it as a full AppSec scanner: Shannon Open Source is exploitation-focused and does not do broad static analysis, dependency, or configuration scanning (the commercial platform does). Do not point it at untrusted or adversarial codebases, since an AI tool that reads source is itself exposed to prompt injection. Do not skip human review: LLM-generated reports can contain weakly supported or incorrect details. Anthropic and OpenAI apply real-time cyber safeguards that can interrupt a scan mid-run, so clear them as a legitimate tester before your first run.

Architecture

flowchart TB
  PRE["pre-recon: source scan"] --> RECON["recon: live attack surface"]
  RECON --> IV["injection-vuln"]
  RECON --> XV["xss-vuln"]
  RECON --> AV["auth-vuln"]
  RECON --> SV["ssrf-vuln"]
  RECON --> ZV["authz-vuln"]
  IV --> IE["injection-exploit"]
  XV --> XE["xss-exploit"]
  AV --> AE["auth-exploit"]
  SV --> SE["ssrf-exploit"]
  ZV --> ZE["authz-exploit"]
  IE --> REP["report: proven findings only"]
  XE --> REP
  AE --> REP
  SE --> REP
  ZE --> REP

The agent graph, executed

Shannon's pipeline is a prerequisite DAG, and reading it as one explains the concurrency: the five vulnerability agents fan out from recon in parallel, each exploitation agent waits only on its own class's vulnerability agent (so injection exploitation can start while SSRF analysis is still running), and the single report sink waits on all five exploits. The model below rebuilds the exact AGENTS map and schedules it in dependency waves.

from collections import deque

CLASSES = ["injection", "xss", "auth", "ssrf", "authz"]
AGENTS = {"pre-recon": [], "recon": ["pre-recon"]}
for c in CLASSES:
    AGENTS[f"{c}-vuln"] = ["recon"]
    AGENTS[f"{c}-exploit"] = [f"{c}-vuln"]
AGENTS["report"] = [f"{c}-exploit" for c in CLASSES]


def waves(graph):
    """Kahn layering: each wave is the set runnable once prior waves finish."""
    indeg = {n: len(deps) for n, deps in graph.items()}
    dependents = {n: [] for n in graph}
    for n, deps in graph.items():
        for d in deps:
            dependents[d].append(n)
    ready = deque(sorted(n for n, k in indeg.items() if k == 0))
    out, seen = [], 0
    while ready:
        layer = list(ready)
        ready.clear()
        out.append(layer)
        for n in layer:
            seen += 1
            for m in dependents[n]:
                indeg[m] -= 1
                if indeg[m] == 0:
                    ready.append(m)
        ready = deque(sorted(ready))
    assert seen == len(graph), "graph must be a DAG (no cycles)"
    return out


w = waves(AGENTS)
for i, layer in enumerate(w):
    print(f"wave {i}: {layer}")

assert w[0] == ["pre-recon"] and w[-1] == ["report"]
assert set(w[2]) == {f"{c}-vuln" for c in CLASSES}
assert set(w[3]) == {f"{c}-exploit" for c in CLASSES}
order = {n: i for i, layer in enumerate(w) for n in layer}
for c in CLASSES:
    assert order[f"{c}-exploit"] > order[f"{c}-vuln"]
print("OK: 12 agents across 5 waves; each exploit waits on its own vuln analysis, "
      "and only proven findings reach the single report sink")

Executed output:

wave 0: ['pre-recon']
wave 1: ['recon']
wave 2: ['auth-vuln', 'authz-vuln', 'injection-vuln', 'ssrf-vuln', 'xss-vuln']
wave 3: ['auth-exploit', 'authz-exploit', 'injection-exploit', 'ssrf-exploit', 'xss-exploit']
wave 4: ['report']
OK: 12 agents across 5 waves; each exploit waits on its own vuln analysis, and only proven findings reach the single report sink

How to use it

The recommended path is npx:

# Configure credentials interactively.
npx @keygraph/shannon setup

# Run a pentest against a source-available target you own.
npx @keygraph/shannon start -u https://your-app.com -r /path/to/your-repo

Shannon pulls the worker image from Docker Hub, starts local infrastructure, mounts the target repository read-only inside an ephemeral worker container, and writes results to a local workspace. Prerequisites are Docker, Node.js 18-plus, and an AI provider key (Claude models are officially supported and recommended). To run on a Claude Code subscription instead of API credits, use the shannon-v1 branch, which is built on the Claude Agent SDK and accepts an OAuth token from claude setup-token.

How to develop with it

The repo is a pnpm/Turbo monorepo (apps/cli, apps/worker). The agent graph, phase names, and validators are the single source of truth in session-manager.ts; the prompts that give each phase its behavior are plain text under apps/worker/prompts (one per phase, plus shared and pipeline-testing). To change what an agent looks for, edit its prompt template; to change the pipeline shape, edit the AGENTS map and its prerequisites. Note the project is not accepting external code contributions at this time, though it welcomes issues.

How to maintain it

Pin the npx version or the worker image tag for reproducible runs; Shannon 2.0 changed the provider substrate (it moved off the Claude Agent SDK, which now lives on the shannon-v1 branch), so a version bump can change how credentials are supplied. Keep the worker image current for tool and dependency fixes. Because runs cost real LLM spend and take roughly 1 to 1.5 hours, budget accordingly and use focus areas and rules-of-engagement config to bound scope.

How to run it in production

Production here means a CI or pre-release security gate against non-production targets, never against live systems. Each scan runs in an ephemeral Docker container with an isolated workspace and per-invocation orchestration, which is the isolation boundary you rely on. Use sandboxed, staging, or local environments with disposable data; provide authenticated-testing config so the agent can reach the real attack surface; and route the worker's egress through the same runtime enforcement and sandboxing you would apply to any tool that executes model-generated actions. Treat every report as input to human review, since the findings are exploited but the writeup is model-generated.

Failure modes

  • It mutates the target. Exploitation agents create users, submit forms, and change state. Against production or shared environments this is damage, not testing.
  • Coverage is the exploited classes only. Injection, XSS, SSRF, Broken Auth, and Broken Authz. Vulnerable dependencies and insecure configuration are out of scope for the open-source engine.
  • Prompt injection through source. Shannon reads the target's code; a malicious or adversarial codebase can attempt to steer the agent. The docs explicitly warn against scanning untrusted code.
  • Model-dependent quality. Officially supported on Claude models; smaller, alternative, or proxied models "may be incomplete or unstable," and reports can carry weakly supported claims.
  • Safeguard interruptions. Provider cyber safeguards can halt a scan mid-run until you have completed their legitimate-tester process.

References

  • Shannon repository (Keygraph), pinned commit 760a1402: https://github.com/KeygraphHQ/shannon
  • Agent graph (apps/worker/src/session-manager.ts): https://github.com/KeygraphHQ/shannon/blob/main/apps/worker/src/session-manager.ts
  • Safety and limitations: https://github.com/KeygraphHQ/shannon/blob/main/docs/safety.md
  • Sample reports (Juice Shop, crAPI, c{api}tal): https://github.com/KeygraphHQ/shannon/tree/main/sample-reports
  • Pi agent core (the underlying harness): https://github.com/badlogic/pi-mono

Related: Agentic cybersecurity and SysOps index · Earned-verdict pentesting with ptai · Agentic pentest orchestration: PTT and CrewAI · Agentic vulnerability scanning · Agent sandboxing and isolation · Cybersecurity agent evaluation