AEGIS — Adaptive Engagement & Generic Inspection Scanner
Project description
aegis · v0.10.0
Adaptive Engagement & Generic Inspection Scanner
An autonomous, AI-orchestrated web penetration testing agent. Aegis handles reconnaissance, fingerprinting, vulnerability discovery, verification, and reporting so the human pentester focuses on what actually requires human judgment.
What it is
Aegis runs structured, methodology-driven engagements against web targets. It profiles the host environment, fingerprints the target stack, selects relevant tools and tests from the PTES + OWASP WSTG v4.2 playbook, executes them concurrently, and produces a verified findings report with remediation guidance.
It is not a Burp Suite replacement. It is the autonomous recon and vuln-discovery layer that feeds the human pentester, eliminating roughly 70% of routine busywork.
Hard constraints built into the runtime:
- Every engagement requires a signed
scope.yamlbefore any network egress. - Every outbound request is matched against in-scope and out-of-scope rules before the socket opens.
- Scope violations abort the current task and are written to the audit log.
- Destructive tools (
sqlmap,wpscan,commix,kerbrute,crackmapexec, …) refuse to run without operator approval unlessscope.yamlexplicitly enables them. - There is no
--forceflag that bypasses scope.
Installation
Option A — Docker (recommended, all tools pre-installed)
# Pull pre-built image (~4 GB) or build locally (~15-30 min)
aegis docker pull # from GitHub Container Registry
# OR
aegis docker build # build locally from Dockerfile
# Run an engagement
export ANTHROPIC_API_KEY=sk-ant-...
aegis docker run engagements/2026-acme
# Interactive shell with every tool on PATH
aegis docker shell
# Check image status and tool inventory
aegis docker status
The Docker image is based on Kali rolling and includes every tool in the catalog.
Option B — PyPI
pip install aegis-pentest
# or
pipx install aegis-pentest
Option C — Arch (AUR)
yay -S aegis-pentest
# or
paru -S aegis-pentest
Optdepends cover the full tool surface; install only what you need.
Option D — Native install script (one-liner)
# Auto-detects Arch, Kali, Ubuntu/Debian, Fedora, macOS
curl -fsSL https://raw.githubusercontent.com/glorybnat/aegis-pentest/main/scripts/install.sh | bash
# Or from the repo
bash scripts/install.sh
# Build Docker image instead
bash scripts/install.sh --docker
Option E — From source
git clone https://github.com/glorybnat/aegis-pentest.git
cd aegis-pentest
pip install -e .
cd tui && npm install && npm run build
After installing AEGIS, detect what's already on the host and fill in the rest:
aegis init # detect what's installed
aegis env tools --missing # show what's missing + install commands
aegis env install --missing # install everything (no-sudo tools)
aegis env install --missing --dry-run # preview first
Requirements:
- Python 3.12+
ANTHROPIC_API_KEYin environment- Docker (Option A) or pentest toolchain (Option B–E)
Quickstart
# Docker quickstart (zero host setup)
export ANTHROPIC_API_KEY=sk-ant-...
aegis docker build # or: aegis docker pull
aegis docker run engagements/2026-acme
# Native quickstart
# First run: profiles host, lists missing tools
aegis init
# Sync the knowledge base (NVD, GHSA, nuclei-templates, CISA KEV, FIRST EPSS)
aegis kb sync
# Create a new engagement
aegis engagement new --client "Acme Corp" --domain "acme.com"
# Fill in the authorization details
vim engagements/2026-05-acme/scope.yaml
# Optional: seed endpoints from an existing API spec or proxy trace
aegis ingest openapi engagements/2026-05-acme/spec.yaml --engagement engagements/2026-05-acme
aegis ingest postman engagements/2026-05-acme/collection.json --engagement engagements/2026-05-acme
aegis ingest har engagements/2026-05-acme/burp.har --engagement engagements/2026-05-acme
# Run
aegis run engagements/2026-05-acme
# Resume from the last completed phase after a crash or Ctrl+C
aegis run engagements/2026-05-acme # picks up state.json automatically
# Generate report — md/html/json/sarif/h1/bugcrowd, or "all"
aegis report engagements/2026-05-acme --format html
aegis report engagements/2026-05-acme --format sarif # GitHub/GitLab code scanning
aegis report engagements/2026-05-acme --format h1 # HackerOne JSON, one per finding
aegis report engagements/2026-05-acme --format bugcrowd # Bugcrowd VRT bundle
scope.yaml
Aegis refuses to run without this file. No exceptions.
engagement_id: "BL-2026-007"
client: "Acme Corp"
operator: "Majd Bnat <hey@majdb.com>"
authorization:
document_ref: "SOW-2026-007.pdf"
signed_date: "2026-05-12"
expiry: "2026-06-12"
in_scope:
domains:
- "*.acme.com"
- "api-staging.acme.io"
ips:
- "203.0.113.0/24"
out_of_scope:
- "admin.acme.com"
- "*.internal.acme.com"
rules_of_engagement:
rate_limit_rps: 10
business_hours_only: false
destructive_tests: false
no_credential_stuffing: true
no_dos_tests: true
confirm_before: # per-engagement gate for destructive tools
- sqlmap
- hydra
- commix
Architecture
aegis CLI
|
Engagement Manager
(scope validation, lifecycle, audit log)
|
+-----------------+-----------------+
| | |
Environment Target Methodology
Profiler Profiler Engine
(host info) (fingerprint) (PTES phases)
| | |
+--------+--------+--------+--------+
|
LLM Orchestrator
(Haiku / Sonnet / Opus)
|
+----------+---------+----------+----------+
| | | | |
Tool Knowledge Findings PTT PoC
Registry Base DB Graph Generator
(162 tools) (NVD/GHSA (SQLite) (aiosqlite) (14 types)
+KEV/EPSS)
| |
Tool Executor Hallucination Guard
(async, sandboxed, (output verification)
destructive-gated)
|
Reporter
(md/html/json/sarif/h1/bugcrowd)
The orchestrator runs a bounded loop per phase:
plan(phase_context) -> execute(action) -> observe(result) -> update(state)
^ |
+---------------------------------------------------------------+
until phase complete OR budget exceeded
Three independent budgets bound each phase: token budget, wall-clock time, and action count. Whichever trips first ends the phase and triggers finalize mode.
State is persisted to <engagement_dir>/state.json after every phase advance via atomic tmp + os.replace. Re-running aegis run against the same directory resumes at the last saved phase.
Attack chain detection
Findings carry structured tags. The chain detector matches on tag sets, not title substrings. 22 chains ship out of the box — 7 legacy web chains, 10 modern web/API chains, and 5 Active Directory chains:
| Chain | Severity | Predicate (tag groups) |
|---|---|---|
| Account takeover via CORS + JWT | critical | cors_wildcard + jwt-family |
| Stored XSS + CSRF = session hijack | critical | xss_stored + csrf |
| SQL injection + weak crypto | critical | sqli + weak_crypto |
| SSRF + internal service exposure | high | ssrf + cloud/internal |
| SSRF + cloud metadata v1 | critical | ssrf + cloud_metadata_v1 |
| Mass assignment + admin endpoint | critical | mass_assignment + admin_endpoint |
| Open bucket + reachable Lambda | high | bucket_open + lambda_invoke |
| Request smuggling → auth header bypass | critical | request_smuggling + auth_header |
| Cache poisoning → auth bypass | critical | cache_poisoning + auth_cookie |
| Prototype pollution → RCE sink | critical | prototype_pollution + dangerous_sink |
| JWT alg-confusion → privilege escalation | critical | jwt_alg_confusion + privileged_endpoint |
Exposed .git → source code disclosure |
high | git_exposure |
| Open registration + IDOR | high | open_registration + idor |
| Race condition → auth bypass | high | race_condition + auth |
| Kerberoasting → service account compromise | high | ad_kerberoast + ad_spn + weak/service |
| AS-REP roasting | high | ad_no_preauth + weak/user |
| DCSync → full domain compromise | critical | ad_dcsync + any AD creds |
| AdminSDHolder ACL backdoor | critical | ad_adminsdholder + any AD creds |
| Unconstrained delegation → ticket forge | critical | ad_unconstrained + any AD creds |
For engagements predating the tag rollout, a substring fallback still fires the legacy 7 rules against finding titles.
Token model
Aegis is designed to complete a full medium-scope engagement for under $2 in LLM tokens. This is achieved through several layered tactics:
| Tactic | Impact |
|---|---|
| Tiered model routing (Haiku handles ~70% of calls) | -60% cost |
| Prompt caching on system prompt + engagement context | -40% on input tokens |
| Parsed tool output, never raw stdout to the LLM | -80% on tool-heavy phases |
| Structured tool-use schema, no prose planning | -30% output tokens |
| Methodology-driven action space pruning | -50% wasted calls |
| SQLite-cached recon reused across phases | variable |
| Finding deduplication before LLM sees results | -10-30% |
Model tiers:
| Tier | Model | Used for |
|---|---|---|
| NANO | claude-haiku-4-5 | Parsing, classification, summarization |
| MAIN | claude-sonnet-4-6 | Planning, hypothesis generation, verification probes |
| DEEP | claude-opus-4-7 | Attack chain analysis, hard reasoning |
| LOCAL | ollama (optional) | Offline pre-classification |
The live cost meter runs in the terminal throughout each phase:
Phase: VULN_ANALYSIS [>>>>>>>>--] 80%
Budget: $0.74 / $5.00 Tokens: 41.2k / 200k Time: 12m / 60m
Tier breakdown: NANO 24% . MAIN 71% . DEEP 5% Cache hit: 82%
Tool catalog
Aegis exposes 162 MCP tools wrapping 102 external binaries plus orchestration primitives. Raw output is never passed to the LLM — each tool has a typed parser that produces structured Finding or Observation models. A nmap scan returning 47 open ports becomes 47 OpenPort observations of ~80 bytes each, not 200 KB of XML.
All tools degrade gracefully: if a binary is not installed, the tool returns a structured error with the exact install command.
| Category | Tools |
|---|---|
| API ingest | aegis ingest openapi, aegis ingest postman, aegis ingest har (writes Endpoint observations + paths.txt/params.txt wordlists) |
| Subdomain enumeration | subfinder, amass, assetfinder, findomain, dnsx, alterx, massdns, shuffledns, puredns, dnstwist, subdomain_brute_massive |
| DNS recon | dnsrecon, dnsx, massdns, fierce, crt.sh (cert transparency) |
| OSINT / passive | uncover (Shodan/Fofa/Censys/ZoomEye), shodan CLI, censys CLI, asnmap, passive_intel, github_discover, pwndb_search, theharvester, spiderfoot, recon_ng, google_dorks |
| Live host detection | httpx, httpx_batch, httprobe, naabu |
| Port scanning | nmap, naabu, masscan, rustscan |
| Web crawling | katana, gospider, hakrawler, getjs |
| URL / archive recon | gau, waybackurls, wayback_recon, meg, unfurl, qsreplace |
| Content discovery | ffuf, feroxbuster, gobuster, dirsearch, wfuzz, content_discovery, kiterunner |
| Vhost fuzzing | ffuf_vhost |
| Tech fingerprinting | whatweb, httpx -tech-detect, cdncheck, tlsx |
| WAF detection | wafw00f, whatwaf |
| TLS auditing | sslscan, sslyze, tlsx |
| Parameter discovery | arjun, paramspider, gf (pattern filtering) |
| XSS | dalfox, kxss, crlfuzz, xsstrike, nuclei, aegis_verify (xss probe) |
| SQLi | sqlmap*, nosqlmap*, nuclei, aegis_verify (sqli / timing_sqli probes) |
| SSTI | sstimap*, aegis_verify (ssti probe) |
| Command injection | commix*, aegis_verify (cmdi_oob probe) |
| HTTP smuggling | smuggler* (CL/TE, TE/CL), h2csmuggler (HTTP/2 cleartext) |
| CORS | corsy |
| SSRF / OOB | oob_init + oob_poll (interactsh), aegis_verify (ssrf_oob / xxe probes) |
| Race conditions | race_condition_scan, aegis_verify (race probe) |
| OAuth | oauth_audit (open redirect, state bypass, PKCE) |
| JWT attacks | jwt_audit (alg:none, RS256→HS256, weak secret) |
| GraphQL | graphql_audit (schema walk, batch DoS, deep nesting, per-query auth probe, rate-limit burst), graphql_cop |
| WebSocket | websocket_test (injection, origin validation, auth) |
| API discovery | api_discover, kiterunner, openapi_audit |
| IDOR | idor_check (cross-user object access) |
| JS analysis | js_recon, linkfinder, secretfinder |
| Header injection | header_injection_scan (Host header, cache poisoning) |
| 403 bypass | bypass_403 (path tricks + header overrides) |
| Prototype pollution | aegis_verify (prototype_pollution probe) |
| Secrets / SAST | trufflehog, semgrep, bandit, safety, npm_audit, retire_js, secret_scan |
| Vulnerability scanning | nuclei, nuclei_fuzz, nuclei_ai_generate, wapiti, nikto |
| CMS scanning | wpscan*, cmseek, joomscan, droopescan |
| Network / SMB | enum4linux, smbmap, snmpcheck |
| Active Directory | impacket (GetUserSPNs.py, GetNPUsers.py, secretsdump.py), kerbrute*, bloodhound-python, ldapdomaindump, crackmapexec*, certipy |
| Cloud config audit | scoutsuite (AWS/Azure/GCP/Aliyun/OCI), cloudsplaining, pmapper, iamspy, azurehound, roadtools, gcp-iam-collector, gcp-scanner |
| Cloud storage | cloud_enum, s3scanner, bucket_finder, gitdumper, cloudfox |
| Kubernetes | kube_bench, kube_hunter, kdigger, kubectl-who-can |
| Container / SBOM | trivy, grype, syft |
| Auth / brute force | hydra* |
| Subdomain takeover | subjack, subzy, subdomain_takeover_scan |
| Recon orchestration | bbot (multi-module OSINT), interlace (parallel execution) |
| Reporting | aegis_report (md / html / json / sarif / h1 / bugcrowd) |
| Methodology | wstg_check (OWASP WSTG v4.2, 80+ checks) |
| Attack graph (PTT) | ptt_add_node, ptt_update_node, ptt_get_graph, ptt_next_targets, ptt_spawn_tasks, ptt_summary |
| Orchestration | aegis_hotlist (asset risk scoring), aegis_compress_context (context compression), aegis_engagement_status |
| PoC generation | generate_poc (14 vuln classes: XSS, SQLi, SSRF, LFI, RCE, IDOR, open redirect, JWT, CORS, CSRF, HTTP smuggling, SSTI, XXE, prototype pollution) |
| Output verification | verify_tool_output (hallucination guard — validates tool output before Claude acts on it) |
* marks tools that require operator approval before each run (destructive-gated).
Verification probes
43 in-process probes (aegis.verify.probes) confirm findings without re-invoking external binaries. Each probe targets a specific class and emits a structured ProbeResult. Probes are HTTP-only by default and rate-limited per scope.
blind_cmdi, blind_cmdi_oob, blind_sqli, cache, cache_poisoning,
cmdi_oob, cors, cors_misconfig, csrf, csrf_missing, exposure,
file_exposure, headers, http_smuggling, jwt, jwt_alg_confusion,
lfi, misconfig, oauth, oauth_redirect, open_redirect, pp,
prototype_pollution, race, race_condition, redirect,
request_smuggling, smuggling, sqli, sqli_error, ssrf, ssrf_oob,
ssti, subdomain_takeover, takeover, template_injection,
timing_cmdi, timing_sqli, toctou, xml_injection, xss,
xss_reflected, xxe
Reports and webhooks
Six output formats, all driven from the same Reporter context:
| Format | Use |
|---|---|
md / html |
human consumption |
json |
machine consumption with stable schema |
sarif |
GitHub Code Scanning, GitLab Security, Azure DevOps |
h1 |
HackerOne submission — one JSON per finding under reports/h1/ |
bugcrowd |
Bugcrowd VRT-mapped JSON bundle |
PII redaction is opt-in via [reporting] redact_pii = true. Sweeps emails, JWTs, AWS keys, GitHub PATs, Slack tokens, US SSNs, credit-card-shaped numbers, and phone numbers. IP redaction is a separate switch. Audit log records counts only — never content. Scope metadata (engagement_id, client) is intentionally preserved.
Live findings webhook via aegis watch:
aegis watch engagements/2026-acme \
--webhook https://hooks.slack.com/services/... \
--webhook-format slack \
--webhook-min-severity high
Supported platforms: slack (Block Kit), discord (severity-coloured embeds), linear (issue title/description/priority), json (stable schema for n8n / Zapier).
Environment profiling
On first run, aegis init profiles the host and derives auto-tuned concurrency settings:
Host: arch-workstation
OS Arch Linux (rolling, kernel 6.9.3-arch1-1)
CPU AMD Ryzen 7 5800X . 8 cores / 16 threads . 4.7 GHz
Memory 32 GB total . 24 GB available
Repos core, extra, multilib, blackarch
Pentest toolchain: 28/35 detected
nmap 7.95 nuclei 3.2.9 httpx 1.6.6
ffuf 2.1.0 subfinder 2.6.6 katana 1.1.0
sqlmap 1.8.5 wpscan 3.8.27 nikto 2.5.0
gobuster 3.6.0 amass 4.2.0 gowitness 3.0.3
Missing: testssl.sh feroxbuster dnsrecon arjun paramspider trufflehog
-> Run: aegis env install --missing
Auto-tuned concurrency:
nmap_parallelism=16 nuclei_concurrency=32 ffuf_threads=64
httpx_concurrency=80 max_parallel_tools=4
CLI reference
aegis init First-run setup and env profile
aegis env show Display host profile
aegis env tools Tool inventory
aegis env install --missing Generate install commands for missing tools
aegis env refresh Re-detect host profile
aegis kb sync [--source nvd|ghsa|nuclei|kev|epss] Sync knowledge base
aegis kb stats Knowledge base summary
aegis kb query --product nginx --min-cvss 7 Query CVEs
aegis engagement new --client X --domain Y Scaffold engagement dir and scope.yaml
aegis engagement list List engagements
aegis ingest openapi <spec> --engagement <dir> Seed endpoints from OpenAPI / Swagger
aegis ingest postman <coll> --engagement <dir> Seed endpoints from Postman v2.x
aegis ingest har <trace> --engagement <dir> Seed endpoints from a browser HAR
aegis run <dir> [--phase PHASE] Run engagement (resumes from state.json)
aegis run <dir> --dry-run Preview planned actions
aegis run <dir> --budget-usd 2.00 Cap spend
aegis watch <dir> --webhook <url> Live findings webhook
--webhook-format slack|discord|linear|json
--webhook-min-severity critical|high|medium|low|info
aegis report <dir> [--format md|html|json|sarif|h1|bugcrowd|all] Generate report
aegis findings list <dir> [--severity high] List findings
aegis findings suppress <finding-id> --reason "..."
aegis cost <dir> Detailed cost breakdown
aegis audit <dir> Full audit log
aegis stats [<root>] [--json] Cross-engagement metrics
aegis shells Tool execution history (last scan)
aegis shells --all [--tool X] [--engagement Y] Cross-engagement shell history (SQLite)
aegis docker build|run|shell|pull|status Docker sub-app
All commands support --json for scripting, -v/-vv/-vvv for verbosity, --quiet for CI.
Configuration
Global config lives at ~/.config/aegis/config.toml. Any key can be overridden per engagement in engagement_dir/config.toml.
[api]
anthropic_api_key_env = "ANTHROPIC_API_KEY"
[models]
nano = "claude-haiku-4-5-20251001"
main = "claude-sonnet-4-6"
deep = "claude-opus-4-7"
[models.local]
enabled = false
endpoint = "http://localhost:11434"
model = "qwen2.5:7b"
[budgets]
tokens_per_phase = 30000
tokens_per_engagement = 200000
usd_per_engagement = 5.00
wall_time_per_phase_sec = 1800
[caching]
prompt_cache = true
kb_cache_dir = "~/.cache/aegis/kb"
fingerprint_cache_ttl_hours = 168
[tooling]
docker_isolate = false
default_rate_limit_rps = 10
respect_robots_txt = false
[reporting]
default_format = "html"
include_audit_log = true
redact_pii = false
redact_ips = false
Tech stack
| Layer | Choice |
|---|---|
| Language | Python 3.12+ |
| CLI | Typer + Rich |
| TUI | React + Ink (TypeScript) |
| Async | asyncio + anyio |
| HTTP | httpx (async, HTTP/2) |
| Models | Pydantic v2 |
| Storage | SQLite + SQLModel + Alembic |
| MCP | FastMCP |
| LLM | Anthropic SDK (Claude) |
| Templating | Jinja2 |
| Logging | structlog + rich |
| Packaging | uv (dev), hatch (build) |
| Testing | pytest + pytest-asyncio + respx (281 tests) |
License
MIT. Use responsibly and only against systems you are authorized to test.
Built by Majd Bnat
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file aegis_pentest-0.11.0.tar.gz.
File metadata
- Download URL: aegis_pentest-0.11.0.tar.gz
- Upload date:
- Size: 411.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5b85b39ac85d446996af88d4fa6c2e5720c96d7a739438369e06167da4a84e61
|
|
| MD5 |
f95956c297c673eddc54a179334d963d
|
|
| BLAKE2b-256 |
a6b933ad48a52a8654c15217862202b921eb194256b16130e49eac4e6bed63f1
|
File details
Details for the file aegis_pentest-0.11.0-py3-none-any.whl.
File metadata
- Download URL: aegis_pentest-0.11.0-py3-none-any.whl
- Upload date:
- Size: 414.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e52f25cd7e20d888fdf2c55a56fe0714442f427356697d600dc621b40f04e649
|
|
| MD5 |
1c013486c0853c1d617ebe5e93bb2fb2
|
|
| BLAKE2b-256 |
1e4da03baf115e863ede00be26ea3bea33eefb9c59a6a93d07d021bd4d2c2c51
|