An autonomous web-application penetration tester that works to get in — and then to get root.
Aamon is an autonomous offensive-security agent for web applications and their APIs (REST, SOAP, GraphQL). Give it an authorized target and a one-page brief, and it does what a human red-teamer does: maps the attack surface, hunts for a way in that needs no credentials, takes that foothold as far as it goes, and writes the whole thing up. It is built on the eve agent framework and runs its tooling inside a disposable sandbox.
It is named after a figure from the Ars Goetia — a spirit said to command forty legions and to preside over life and reproduction. The metaphor earns its keep: Aamon does not work one thread at a time. It splits into background subagents that attack in parallel, each chasing its own lead, and folds their results back into one account of how the application falls. It reproduces to cover ground, and it persists — holding a foothold, deepening it, and climbing — the way a patient attacker does.
Aamon optimizes for access, not for a long list of hygiene nits. Its objectives, in order:
- Break in without credentials. A session that isn't yours, a user you can impersonate, an authenticated state reached with no password — through auth bypass, broken access control, account takeover, SSRF or RCE, token forgery, or a chain of smaller bugs.
- Escalate. Sideways to other users and tenants, upward to admin or superuser.
- Consolidate. Chain the findings, reach the backend, and show how far the compromise actually goes.
Misconfigurations and missing headers still get recorded, but they are footnotes. A proven path in, demonstrated with a deliberately minimal and non-destructive proof, is the headline.
An engagement is a campaign, not a quick scan: a sustained, multi-hour (often multi-day) operation run in one durable session whose sandbox persists across invocations. It moves through five phases, each gated so the next can't start until the current one's exit criteria are met:
- Planning — build a large, concrete attack plan.
- Recon — fan out across up to four parallel subagents, enumerate the whole surface, and run the big scans detached until they finish. The gate won't advance until enough of the surface is mapped and every launched scan has completed, which is what makes a campaign take hours.
- Triage — turn the recon corpus into a ranked exploitation backlog: CVEs (KEV/EPSS-first), weaknesses, and chains.
- Exploitation — a recursive deepening loop, not a single pass. Each lead (and every verified finding)
becomes an area of interest: a node in a tree-structured plan, worked by a fresh-context worker
seeded from a brief file (the originating finding, the relevant slice of recon, the hypothesis, scope).
A shallow area (depth ≤
AAMON_SUBPLAN_DEPTH, default 7) plans itself first — the worker lays out a scoped sub-plan of concrete tests and works it; deeper areas work dynamically. When a worker uncovers a deeper sub-problem it reports it, and the orchestrator opens it as a child area (depth + 1) with its own fresh worker — so an area of interest becomes a new sub-plan and the investigation drills down a thread rather than stopping at the first rung. Depth is capped (AAMON_MAX_AREA_DEPTH, default 15: deep rather than wide). The gate requires every lead resolved and the whole area tree drained. - Reporting — consolidate the chain and deliver.
finalize_engagement only closes from the reporting phase, so the run cannot finish after a shallow
sweep. The phase thresholds are env-tunable (see Configuration).
Aamon is autonomous by default. It does not stop to ask permission for each exploit — within an authorized scope it runs the bypass, fires the injection, forges the token, and escalates on its own, start to finish, and delivers a report at the end.
Exactly two rules constrain it, and it enforces both itself:
- Scope. It records an authorized scope up front and checks every target against it before acting. Anything outside that scope is off-limits, always.
- Do no harm. It never does anything that could take the target down or corrupt its data — no denial-of-service, no destructive or state-changing actions, no mass data theft. Where a technique would cross that line (volume brute-force, request smuggling, cache poisoning), it uses a safe proof instead, or notes it as a follow-up rather than running it.
⚠️ Only point Aamon at systems you own or are explicitly authorized to test. It is an offensive tool that will attempt real exploitation. Unauthorized use is illegal.
Aamon carries the working knowledge of a senior web pentester as a set of skills it loads when a task calls for them, each going a layer deeper than the last:
| Skill | What it brings |
|---|---|
pentest-methodology |
The phased, iterative approach and when to reach for each other skill. |
owasp-reference |
OWASP WSTG test cases, Top 10, API Security Top 10, and ASVS — the baseline checklist. |
test-web-and-webservices |
End-to-end method for testing an app and its APIs. |
initial-access |
The credential-less ways in, as a prioritized playbook. |
privilege-escalation |
Climbing and consolidating once there's a foothold. |
web-attack-techniques |
Each vulnerability class and the sandbox tool that fits it. |
cve-hunting |
Fingerprinting components and verifying their known CVEs against live feeds. |
engagement-briefing · engagement-planning · findings-report |
Intake, the living test plan, and the report. |
Standards it follows: OWASP WSTG, Top 10, API Security Top 10, and ASVS; NIST SP 800-115; MITRE CWE; CVSS 3.1. The checklists are a floor — the findings that matter most are the ones no checklist names.
Requires Node.js 24+. eve is installed as a local dependency.
npm install
npm run dev # launches the eve dev TUI; paste a briefing to beginA briefing is a short scoping document: the authorized in-scope URLs or hosts, anything out of scope,
test accounts per role, the environment, and the rules of engagement. Aamon reads it, confirms the
scope back to you, maps the surface, works its plan over several passes, and compiles the report at
engagement/report.md (and to Slack — see below).
Everything that defines the agent lives under agent/, and eve compiles and runs it.
agent/
├── instructions.md persona, mandate, boundaries, how it runs an engagement
├── agent.ts model selection and per-session cost/time limits
├── sandbox.ts disposable /workspace with a baked web-pentest toolkit
├── channels/ how you reach it: slack, HTTP intake, and the eve session API
├── tools/ scope gate, engagement/plan/recon/lead/finding records, areas (open_area +
│ record_subarea + plan_area for recursive, self-planning deepening), phases, scans, finalize
├── schedules/ campaign heartbeat (resumes a parked campaign on a cadence)
├── skills/ the loadable knowledge above
├── lib/ engagement model, report builder, scope and notify helpers
└── hooks/ audit log of every command, tool, and result
- The sandbox bakes in a web-focused toolkit so runs start instantly:
nmap,nuclei(templates pre-pulled),httpx,katana,subfinder,gau,arjun,ffuf,gobuster,sqlmap,commix,dalfox,jwt_tool,wpscan,wafw00f,nikto,testssl,interactsh, andSecLists— and Aamon installs or writes more on demand. - Everything is recorded. A hook logs every command, tool call, and result to
engagement/audit.log, giving a reproducible trail independent of the model. Engagement artifacts (scope, plan, findings, report, tool scripts, scan output) live under/workspace/engagement/. - The plan is a tree, and a gate. Aamon builds a concrete test backlog first, and
finalize_engagementrefuses to close while any task is open — which forces the second and third passes where depth comes from. The plan is also a tree: a finding or weakness becomes an area of interest (a child node), so the backlog grows itself as the agent learns, and the run can't finish until the whole tree is drained. - Depth lives in the data, not in a stack of agents. Each area of interest is worked by a fresh-context
worker seeded from a brief file (
engagement/areas/<id>/brief.md) carrying the relevant recon; a shallow area plans itself first (an area-scoped sub-plan viaplan_area), and deeper sub-problems it finds are opened as child areas (up toAAMON_MAX_AREA_DEPTH, default 15) with their own fresh workers. The recursion is the growing tree, executed by flat workers — so it drills deep without a nested tree of agent processes or overwhelming a single context. - Long scans don't stall it. A single blocking scan can exceed the per-invocation time limit, so
genuinely long runs are launched detached (
scan_start) and polled (scan_poll), surviving restarts. - It fans out. Independent workstreams run as background subagents across distinct hosts, sharing the sandbox and reconvening into one report.
Deploy to Vercel through eve and reach it over HTTP or from Slack.
npm run deploy # eve deploySlack is how Aamon takes direction and delivers reports. Add the channel with the guided setup (Vercel Connect manages the bot token and verifies inbound events):
eve add channel/slackMention or DM the bot to start and steer an engagement; the finished report is posted to the channel
named by AAMON_SLACK_CHANNEL_ID, with the full document as threaded replies.
Post a briefing to the HTTP intake and it runs to completion on its own, reporting to Slack when done.
curl -u "$OPERATOR" https://<deployment>/intake \
-H 'content-type: application/json' \
-d '{ "name": "ACME Q1 Web-App",
"attended": false,
"briefing": "<scope and rules of engagement here>" }'"attended": false (the default) runs fully unsupervised. Set "attended": true when you want a human
on hand for the destructive-edge actions Aamon otherwise skips; it will then raise those for approval
(in Slack, in the TUI, or via the session API). Follow progress at GET /intake/:sessionId/stream. See
docs/attended-runs.md.
Keep the deployment to your own team with two layers: Vercel Deployment Protection (SSO) at the edge,
and eve route auth, which fails closed in production (agent/channels/eve.ts). Operators on the HTTP
intake authenticate with the credentials in AAMON_OPERATORS; Slack access is restricted with the
allowlist variables below.
| Variable | Purpose |
|---|---|
AAMON_OPERATORS |
user:password pairs for HTTP-intake operators, comma-separated. |
AAMON_SLACK_CHANNEL_ID |
Slack channel that receives finished reports. |
AAMON_SLACK_CONNECTOR |
Vercel Connect connector uid for Slack (default slack/aamon). |
AAMON_SLACK_ALLOWED_USERS |
Slack user ids permitted to drive the agent, comma-separated. |
AAMON_SLACK_ALLOWED_CONVERSATIONS |
Slack conversation ids the agent will act in, comma-separated. |
AAMON_SLACK_TEAM_ID |
Slack workspace id, when a Connect token must select an installation. |
SLACK_BOT_TOKEN |
Only if you manage the Slack app yourself instead of via Vercel Connect. |
NVD_API_KEY |
Optional. Raises the NVD CVE API rate limit for cve-hunting. |
WPSCAN_API_TOKEN |
Optional. Full WordPress vulnerability data for wpscan. |
AAMON_COVERAGE_GATE |
Optional. off disables the finalize coverage gate (default on). |
AAMON_MIN_DONE_TASKS |
Optional. Completed plan tasks required to finalize (default 8). |
AAMON_MIN_CLASSES |
Optional. Distinct vulnerability classes that must be tested (default 5 of 8). |
AAMON_MIN_ENDPOINTS |
Optional. Distinct endpoints that must be exercised (default 5; lower for tiny targets). |
AAMON_MIN_PLAN_TASKS |
Optional. Plan tasks required to leave the planning phase (default 20). |
AAMON_MIN_RECON_ENDPOINTS |
Optional. Distinct endpoints required to leave recon (default 50). |
AAMON_MIN_RECON_SCANS |
Optional. Detached scans that must be launched and finished before triage (default 3). |
AAMON_MIN_LEADS |
Optional. Ranked exploitation leads required to leave triage (default 8). |
AAMON_MAX_AREA_DEPTH |
Optional. Max depth of the recursive area-of-interest tree in exploitation (default 15). Lower it to stay shallow; raise it to drill deeper. |
AAMON_SUBPLAN_DEPTH |
Optional. Areas at this depth or shallower begin with their own sub-plan; deeper areas work dynamically (default 7). |
AAMON_CAMPAIGN_CHANNEL_ID / AAMON_CAMPAIGN_THREAD_TS |
Optional. The Slack thread of a running campaign; set both so the heartbeat schedule resumes it if it parks. Unset, the heartbeat does nothing. |
The coverage gate is the depth guardrail: finalize_engagement refuses until the plan is broad enough,
so an autonomous run can't finish after a shallow sweep. It gates on coverage and effort, never on
finding count. Tune the thresholds to the target (a single-page site may need AAMON_MIN_ENDPOINTS=1).
Set variables with vercel env add <NAME> or in the Vercel project settings, then redeploy so the
running deployment picks them up.
The model is a single line in agent/agent.ts and everything else is held constant, which makes it easy
to compare models on the same engagement. The shipped default is deepseek/deepseek-v4-pro at high
reasoning effort. See MODELS.md for the comparison protocol.
eve set model anthropic/claude-opus-5.5 --reasoning highMIT. Use responsibly and only with authorization.