ββββββ ββββββββ βββββββ βββ ββββββββ
ββββββββ ββββββββ ββββββββ βββ ββββββββ
ββββββββ ββββββ βββ ββββ βββ ββββββββ
ββββββββ ββββββ βββ βββ βββ ββββββββ
βββ βββ βββββββββββ ββββββββββββ βββ βββ βββ ββββββββ
βββ βββ βββββββββββ βββ βββββββ βββ βββ βββ ββββββββ
Agentic Execution-Governed Intelligence System
Senior Research Project - Stetson University (2025-2026)
Max Conrad & Dr. Daniel Plante, Faculty Advisor
A.E.G.I.S is an AI-augmented web security assessment framework that combines passive reconnaissance with agent-driven active testing. It differs from conventional scanning tools by grounding every finding in concrete, traceable evidence. No vulnerability is reported without proof from live data sources. The system addresses a core problem in automated security analysis: LLM-generated findings that cannot be verified. The design philosophy is conservative by default: it prefers under-reporting to false positives, enforces human approval at every decision gate, and maintains complete audit trails. This is a research prototype exploring how multi-agent LLM pipelines and human-in-the-loop execution can be combined into a controlled, reproducible security assessment workflow. The architecture is model-agnostic by design: the recon pipeline runs on local models via Ollama, the operator agent uses Claude, and the critical handoff artifact between them, the Target Model, which is entirely deterministic with zero LLM involvement.
- System Architecture
- Passive Reconnaissance
- Operator Mode
- Core System Guarantees
- Execution Postures
- Quick Start
- Documentation
- Repository Layout
- Known Limitations
- Current Focus & Next Steps
- Evidence-only. No finding is trusted without traceable evidence from live data sources. Findings without proof are rejected; contradictions kill claims. CVE IDs are only accepted if returned by VulnResolver. The system prefers under-reporting to false positives.
- Deterministic contracts. The Target Model (recon-to-operator handoff) is built by pure rule-based extraction. Same input, same output. No LLM writes or mutates it.
- Human-in-the-loop. The LLM never executes commands directly. Every proposed action passes through validation, policy enforcement, and explicit operator approval before execution on an isolated VM.
- Token discipline. Raw tool output never enters the prompt. Hard caps on summaries, digests, and total context prevent unbounded token growth.
- Single execution path. The Web UI is a thin adapter over a shared orchestrator. No business logic lives in the interface layer.
Every assessment follows a single governed pipeline. The Web UI and FastAPI backend converge on the same core orchestrator with no divergent execution logic in the interface layer.
flowchart TB
%% ---------- Interfaces ----------
subgraph ENTRY["Interfaces"]
direction LR
GUI["Web UI (React)"]
API["FastAPI Backend"]
GUI <--> API
end
ORCH["Assessment Orchestrator"]
API --> ORCH
%% ---------- Core Workflow ----------
subgraph WF["Assessment Workflow"]
direction LR
%% Recon lane
subgraph RECON["Recon (Passive)"]
direction TB
PW["Playwright Collector"]
RA["Recon Analysis (LLM + CVE)"]
RR["Recon Report"]
TM["Target Model (Deterministic)"]
PW --> RA --> RR
PW --> TM
end
%% Operator lane
subgraph OP["Operator (Human-in-the-loop)"]
direction TB
AG["Claude Agent"]
TG["Target Model Guard"]
PV["Policy Validator"]
HA["Human Approval"]
SE["SSH Execution"]
OR["Operator Report"]
SE --> OR
TM --> AG
AG --> TG --> PV --> HA --> SE
end
end
ORCH -->|"run recon"| RECON
ORCH -->|"optional / after recon (or import session)"| OP
BUNDLE["Unified Run Bundle"]
RR --> BUNDLE
TM --> BUNDLE
OR --> BUNDLE
%% ---------- Kali ----------
subgraph KALI["Kali VM (Execution Only)"]
TOOLS["Allowed Security Tools"]
end
SE -->|SSH| TOOLS
classDef interface fill:#0b1220,stroke:#334155,color:#e5e7eb
classDef orchestrator fill:#111827,stroke:#60a5fa,color:#e5e7eb
classDef recon fill:#0b1f17,stroke:#34d399,color:#e5e7eb
classDef operator fill:#1f1608,stroke:#fbbf24,color:#e5e7eb
classDef output fill:#1b1330,stroke:#a78bfa,color:#e5e7eb
classDef kali fill:#220d0d,stroke:#f87171,color:#e5e7eb
class ENTRY interface
class ORCH orchestrator
class RECON,PW,RA,RR,TM recon
class OP,AG,TG,PV,HA,SE operator
class BUNDLE output
class KALI,TOOLS kali
The recon phase collects live application evidence using a headless browser (Playwright), including DOM structure, network traffic, loaded assets, and security headers. From this evidence, two parallel artifacts are produced:
- Recon Report (LLM-assisted): A four-agent pipeline (via Ollama) interprets collected evidence, cross-references vulnerabilities against OSV/GHSA/NVD/KEV databases, filters false positives through deterministic validation, and generates a human-readable report.
- Target Model (Deterministic): A rule-based builder compiles the observed attack surface into a versioned, schema-validated JSON artifact (
schema_version: "0.1.0"). It encodes routing behavior, API candidates, documentation hints, detected libraries, security posture signals, and pre-populated dead-end routes. It makes zero LLM calls and cannot invent findings. Every field carries anevidence_pointertracing back to the source artifact.
The Target Model is the formal interface contract between recon and operator. For schema invariants and provenance rules, see
docs/target_model_contract.md. For the complete field-level specification, seedocs/artifacts_target_model.md.
flowchart TB
TARGET["Target URL"] --> PW["Playwright Collector"]
PW --> EVID["Collected Evidence<br/>(DOM Β· Network Β· Headers Β· Assets)"]
EVID --> TM["Target Model Builder<br/>(Deterministic)"]
TM --> TM_OUT["target_model.json<br/>target_model.md"]
EVID --> DETECT["Library Detection"]
DETECT --> RESOLVE["Vulnerability Resolution<br/>(OSV/GHSA/NVD/KEV + Cache)"]
subgraph LLMPIPE["Recon Analysis"]
direction LR
A1["Evidence Analysis"] --> A2["Vuln Cross-Ref"]
A2 --> A3["False-Positive Filtering"]
A3 --> A4["Executive Summary"]
end
RESOLVE --> LLMPIPE
A4 --> REPORT["Recon Report<br/>(report.json / report.md)"]
Operator Mode enables controlled active testing. A Claude-powered agent proposes actions grounded in the Target Model, but every step must pass through multiple safeguards before execution. The agent never executes commands directly; all execution occurs on a separate Kali VM behind guardrails and human control.
Each proposed command flows through:
- Target Model Guard: the action must trace to evidence discovered during recon (API candidates, discovered paths, JS bundles), or explicitly justify expanding coverage. Host-scanning tools (nmap, nikto, dirb, ffuf) are unconditionally allowed; static asset curl proposals are hard-blocked.
- Policy Validator: enforces tool allowlists, flag constraints, scope restrictions, and posture-specific rules.
- Human Approval Gate: requires explicit operator consent before execution. Cryptographic approval receipts link each authorization to the specific command hash.
Approved commands execute on the Kali VM via SSH. Raw tool output is stored verbatim on disk; the agent receives only a deterministic structured summary (hard-capped at 2k characters).
Session Vault (sessions/<run_id>/vault/) is the RAG memory layer for each engagement. It maintains a machine-readable command index (command_index.json), a human-readable session log (SESSION_LOG.md), structured evidence digests, a vulnerability ledger (vuln_ledger.json), and a CVE bridge that maps detected technologies to OSV/GHSA/NVD results. Evidence digesters extract technology fingerprints (server versions, framework identities) from HTTP headers, nmap service detection, and nikto banners. The vault powers three layers of duplicate prevention:
- Proposal-time vault guard checks every agent-proposed action against
command_index.jsonbefore it reaches the orchestrator. Signature normalization strips cosmetic flags so adding-vdoes not create a "new" command. For sqlmap specifically,--leveland--riskflags are collapsed so that re-probing the same parameter at a different thoroughness level produces an identical signature. - Orchestrator preflight gate is a second check at execution time.
- Prompt-injected ALREADY EXECUTED list includes all prior commands with an explicit block warning.
SQLi Finding Propagation closes the loop between tool-confirmed findings and the next-action system. When sqlmap confirms an injection point, the digest is promoted directly to a VALIDATED entry in the vulnerability ledger (bypassing the CVE enrichment pipeline). NextActionService reads these validated surfaces and suppresses further probe suggestions for already-confirmed parameters, replacing them with exploitation guidance (--dbs, --tables, --dump).
Session Phase System (vault/phase.py) derives the current assessment methodology phase from vault state and injects a phase directive at the top of every agent prompt:
RECONβ map the surface: nmap, dirb/ffuf, nikto, curl functional endpoints onlyANALYSISβ verify discovered paths, extract login forms, probe SQLi candidates, research CVEsEXPLOITATIONβ execute against confirmed vulnerable targetsPOST_EXPLOITATIONβ enumerate internal resources, document access
Phase transitions are quality-gated, not just tool-presence checks. The RECON β ANALYSIS gate requires:
- Port scan with signal: at least one nmap digest with
port_count >= 1(not just "nmap ran") - Path enumeration with signal: at least one dirb/ffuf/gobuster digest with
total_found >= 1(not just "path enum tool ran") - Tech detection: at least one technology fingerprint extracted from evidence
- Minimum coverage: >= 3 successful recon commands, >= 2 unique endpoints
- Login verification: discovered login paths (via redirect) must be directly curled before advancing
Missing fields on older evidence digests are treated conservatively (not counted toward the threshold).
Prompt Snapshot (Tier 2 Context) (context/prompt_snapshot.py) replaces raw vault data with a bounded, structured snapshot (β€5.6k chars) rebuilt each turn. Sections: phase directive, next actions queue, SQLi candidate surfaces, confirmed paths with intel (forms/redirects/titles), unverified paths (static assets filtered), already executed list, detected technology with CVEs, vulnerability ledger. The session graph (session_graph.py) and planner (planner.py) feed branch-aware strategic context into the snapshot when the agent is in RECON, ANALYSIS, or EXPLOITATION phase.
NextActionService (api/services/next_action_service.py) is the canonical next-action coordinator. It consolidates three parallel generation paths (heuristic ranking, planner branch strategy, deterministic fallback) into a single phase-aware pipeline. RECON prioritizes expansion; ANALYSIS prioritizes validation; EXPLOITATION prioritizes validated leads only. Consumed by prompt snapshot rendering, post-execution guidance, and the UI queue.
B0 Operator Intercept (api/services/session_manager.py) detects tool names in user messages and synthesizes a structured agent response without calling the LLM. Prevents the 3-retry/[NO ACTION] cycle when an operator types "nmap" or "run dirb". The [NO ACTION] recovery chain (retry β nudge β deterministic synthesis β planner fallback) handles cases where the LLM returns commentary without a command.
For event chain invariants and receipt verification, see
docs/execution_governance_contract.md. For token bounds and prompt safety rules, seedocs/context_token_contract.md.
flowchart TB
TM["Target Model Pin<br/>(Immutable Context)"] --> AGENT["Claude Agent"]
SNAP["Prompt Snapshot<br/>(Tier 2 Β· β€5.6k Β· rebuilt each turn)"] --> AGENT
AGENT --> GUARD["Target Model Guard<br/>(+ static asset block)"]
GUARD --> POLICY["Policy Validator"]
POLICY --> APPROVAL{"Human Approval"}
APPROVAL -->|Approved| EXEC["SSH Execution (Kali VM)"]
APPROVAL -->|Denied| AGENT
EXEC --> REDUCER["Tool Output Reducer<br/>(β€2k Summary)"]
REDUCER --> VAULT["Session Vault<br/>(index Β· SESSION_LOG Β· digests Β· vuln_ledger)"]
VAULT --> CVE["CVE Bridge + Vuln Ledger"]
VAULT --> PHASE["Phase Derivation<br/>(quality-gated)"]
VAULT --> NAS["NextActionService<br/>(phase-aware ranking)"]
NAS --> SNAP
PHASE -.->|directive| SNAP
VAULT -.->|preflight| GUARD
CVE -.->|validated surfaces| NAS
One assessment produces one self-contained bundle in reports/aegis-<target>-<timestamp>/:
| File | Purpose |
|---|---|
summary.md |
Short executive summary with cross-references (primary handoff) |
summary.json |
Structured summary: validated findings, operator stats, library digest |
report.md |
Full merged report (recon + operator sections) |
report.json |
Full merged structured data |
recon/target_model.json |
Canonical recon surface model (deterministic, versioned) |
recon/target_model.md |
Human-readable target model |
Summary markdown is rendered via a selectable strategy (SUMMARY_STYLE=deterministic|local-llm|claude). JSON is always deterministic. When an LLM-enhanced style fails, markdown falls back to deterministic with a note in summary.json. Recon findings automatically trigger matching playbooks (operator_mode/playbooks/finding_playbooks.yaml) that define safe follow-up steps, required evidence, and stop conditions.
Phase-separated React + Vite web interface with a FastAPI backend (api/). Recon Tab provides pipeline progress, recon brief, target model display, and skip-preflight button for VPN-only targets. Operator Tab provides real-time approval queue with approve/deny, agent chat, execution timeline over Server-Sent Events, and a recon quality bar showing live gate metrics (nmap dot, path enum dot, cmd count, tech count, endpoints, forms). Session Map tab visualizes the branch-oriented session graph. Run Viewer includes findings browser with severity badges, evidence inspection, and markdown/JSON report rendering.
These are enforced by architecture and tests, not by convention. Each guarantee has a corresponding contract document specifying invariants, implementation links, and the tests that enforce them.
| Guarantee | Summary | Contract |
|---|---|---|
| Target Model Determinism | No LLM writes or mutates the model. Same input β same output. Every field carries evidence_pointer provenance. Routing classification is signal-derived. Schema-validated with schema_version. |
target_model_contract.md |
| Execution Governance | Orchestrator.execute_intent() is the single execution gateway. Every command emits a chained event sequence with cryptographic receipt linkage. No bypass path exists. |
execution_governance_contract.md |
| Token-Bounded Context | Raw stdout β disk only. Tool summaries β€ 2k chars. Session digest β€ 1.8k chars. Prompt budget β€ 120k chars. Pinned context injected once, never repeated. | context_token_contract.md |
| Policy & Posture | YAML policies with posture overlays. VM safety always-on, cannot be bypassed. Aggressive lab mode downgrades destructive blocks to warnings. | policy_system_overview.md |
| Architecture Invariants | run_id β session_id. Recon and operator are separate phases. CLI and GUI are thin adapters. Event log is append-only JSONL. |
ARCHITECTURE_CONTRACT.md |
| Posture | Description |
|---|---|
| STEALTH | Reduced noise, conservative rate limits, passive-only tool subset |
| STANDARD (default) | Balanced intensity, full tool access, moderate timing |
| AGGRESSIVE (lab only) | Maximum intensity, policy violations become warnings, VM destructive commands warn with confirmation instead of hard-block |
| Requirement | Purpose | Required For |
|---|---|---|
| Python3.10+ | Runtime | All features |
| Ollama | Local LLM hosting | Passive recon pipeline |
| Anthropic API Key | Claude API access | Operator Mode |
| Playwright | Browser automation | Evidence collection |
| VM Hypervisor + Kali VM | Security tool execution | Operator Mode |
VM Hypervisor: UTM on macOS Apple Silicon, VirtualBox on Windows/Intel Mac.
Tested on macOS (Apple Silicon / Intel) and Windows 10/11. Linux should work but is untested.
On the Kali VM, install Docker and SSH:
sudo apt update
sudo apt install -y docker.io docker-compose openssh-server rsync jq curl
sudo systemctl enable docker && sudo systemctl start docker
sudo systemctl enable ssh && sudo systemctl start ssh
# Allow Docker without sudo
sudo usermod -aG docker $USER
# Log out and back in after thisVerify everything is working:
docker --version
docker-compose --version
systemctl status docker --no-pager
systemctl status ssh --no-pagerBoth docker compose (v2 plugin) and docker-compose (v1 standalone) are supported and auto-detected. ARM64 (Apple Silicon via UTM/QEMU): lab Docker images must support linux/arm64 or use multi-arch builds. For full details see docs/vm_setup.md.
macOS:
cd offensive-ai-sec-tool
python3 -m venv venv && source venv/bin/activate
pip install -r requirements.txt
playwright install # Required: downloads browser binaries for evidence collectionWindows (PowerShell):
cd offensive-ai-sec-tool
python -m venv venv
.\venv\Scripts\Activate.ps1
pip install -r requirements.txt
playwright install # Required: downloads browser binaries for evidence collectionNote:
playwright installmust be run after every freshvenvcreation. Without it, Step 1 (Evidence Collection) will fail because browser binaries are not bundled with the pip package.
Pull Ollama models (both platforms):
ollama pull qwen2.5:7b-instruct
ollama pull llama3.1:8bCreate a .env file in the project root:
# REQUIRED for Operator Mode
ANTHROPIC_API_KEY=sk-ant-...
# Ollama host (optional, defaults to localhost:11434)
OLLAMA_HOST="http://localhost:11434"
# Optional: Higher rate limits for vulnerability APIs
GITHUB_TOKEN="ghp_your_token_here"
NVD_API_KEY="your_nvd_key_here"
# Operator Mode SSH (override default_policy.yaml per-machine)
OPERATOR_SSH_HOST=<KALI_IP>
OPERATOR_SSH_KEY_PATH=~/.ssh/kali_vm_key
OPERATOR_SSH_HOST_IP=<HOST_IP>The system runs as two processes: a FastAPI backend and a React dev server.
Terminal 1 β Backend:
cd offensive-ai-sec-tool
python -m uvicorn api.main:app --reload --host 0.0.0.0 --port 8000Terminal 2 β Frontend:
cd offensive-ai-sec-tool/gui
npm install # first time only
npm run dev # starts Vite dev server on http://localhost:5173Open http://localhost:5173 in your browser. The frontend communicates with the API at localhost:8000.
Standard targets (directly reachable from host):
- Enter target URL and click Start Assessment
- Preflight Discovery runs automatically (Playwright evidence collection, target model build, CVE enrichment)
- Review recon results in the Recon tab
- Click "Proceed to Operator Mode" β SSH connects to Kali VM, agent starts
- Agent proposes actions, you approve/deny each one in the Approval Queue
- Phase advances automatically as coverage thresholds are met (RECON β ANALYSIS β EXPLOITATION)
HTB / VPN-only targets (not reachable from host):
For targets behind an OpenVPN tunnel (e.g. HackTheBox), the host machine cannot reach the target directly β only the Kali VM can. Preflight Discovery would fail because Playwright runs on the host.
- Enter target URL and click Start Assessment
- In the Recon tab, click Skip Preflight (red button, top-right of the pipeline stepper)
- Confirm the skip β operator mode unlocks immediately, starting in RECON phase
- The agent begins with no preflight context and must discover the surface from scratch via nmap, dirb/ffuf, nikto, and curl
Before starting a session against an HTB or VPN-connected target:
1. Connect to the VPN:
# On the Kali VM
sudo openvpn lab_vpn.ovpn
# Verify the tunnel is up
ip addr show tun0 # Should show a 10.10.x.x address2. Add /etc/hosts entries:
The agent expects vhost-based targets to resolve locally. Add entries on the Kali VM before starting a session:
# On the Kali VM β replace with your target IP and hostname(s)
echo "10.129.20.50 usage.htb admin.usage.htb" | sudo tee -a /etc/hostsThe target IP is shown on the HTB machine page after spawning the instance. Hostnames are discovered during the session (typically via nmap PTR records or HTTP redirects) β add them as you find them.
3. Verify connectivity from Kali:
ping -c 1 10.129.20.50 # Target IP reachable?
curl -s http://usage.htb/ # Hostname resolving? (after /etc/hosts entry)For full Kali VM setup (VirtualBox/UTM), SSH key configuration, and operator mode walkthrough, see docs/CLI_GUIDE.md.
Sample output from a real full-pipeline run (recon + operator mode) is in examples/.
Defined in operator_mode/policies/default_policy.yaml with allowed flags per tool:
- Core (9): nmap, nikto, dirb, ffuf, whatweb, curl, nc, searchsploit, sqlmap
- Extended (12): wfuzz, hydra, wpscan, sslscan, testssl, enum4linux, smbclient, snmpwalk, onesixtyone, dnsrecon, dig
- Disabled by default: gobuster, metasploit, beef, responder (require policy edit). ffuf is preferred over gobuster for content enumeration.
| Document | Purpose |
|---|---|
target_model_contract.md |
Target Model schema invariants, provenance rules, fail-closed semantics |
artifacts_target_model.md |
Complete field-level spec: types, provenance map, versioning strategy |
execution_governance_contract.md |
Single execution gateway, event chain, receipt verification |
context_token_contract.md |
Token bounds, caps, raw-stdout prohibition, pinned context rules |
policy_system_overview.md |
Policy merge order, posture overlays, validation semantics |
ARCHITECTURE_CONTRACT.md |
High-level architectural invariants (identity model, phase separation, logging) |
| Document | Purpose |
|---|---|
CLI_GUIDE.md |
Full CLI usage, operator mode setup, VM configuration |
examples/ |
Sample output from a full pipeline run (report, target model) |
offensive-ai-sec-tool/
βββ aegis.py # CLI entry point (deprecated β see below)
βββ config.py # Shared configuration (env overrides)
β
βββ core/ # Shared orchestration primitives
β βββ assessment_orchestrator.py # Top-level run lifecycle coordinator
β βββ constants.py # Shared constants (run_id gen, posture default)
β βββ posture.py # Posture name β YAML resolution
β βββ run_bundle.py # Run bundle path helpers
β
βββ cli/ # Interactive CLI (deprecated β see below)
β βββ interactive.py # Session handler, menus, operator loop
β βββ display.py # Terminal formatting, operator header
β
βββ api/ # FastAPI backend (primary interface)
β βββ main.py # App factory + CORS + router registration
β βββ routers/ # operator.py, runs.py, health.py
β βββ services/ # session_manager.py, next_action_service.py, phase_gate_service.py, etc.
β
βββ gui/ # React + Vite web dashboard
β βββ src/ # Pages, components, hooks, typed API client
β
βββ recon/ # Passive reconnaissance pipeline
β βββ target_model.py # Target Model builder (deterministic, no LLM)
β βββ agents/ # 4-agent pipeline (evidence β vuln β validate β summary)
β βββ evidence/ # Playwright collector + collected evidence
β βββ services/ # Multi-API vulnerability resolver
β βββ detectors/ # Library/version detection, CVE confirmation
β βββ utils/ # OSV, GHSA, NVD, KEV clients + SQLite cache
β
βββ operator_mode/ # Active testing via Kali VM
β βββ orchestrator/ # Event-sourced execution engine
β β βββ orchestrator.py # Main loop + duplicate guard (the golden path)
β β βββ events.py # Append-only event log (JSONL)
β β βββ safety.py # SafetyController: VM + policy + posture enforcement
β β βββ approval.py # Cryptographic approval receipts
β β βββ evidence.py # Evidence capture + SPA shell detection
β β βββ domain.py # Intent, Plan, domain types
β βββ context/ # Token-efficient context pipeline
β β βββ prompt_assembler.py # Hard-capped prompt builder (120k char budget)
β β βββ prompt_snapshot.py # Tier 2 compact context (β€5.6k, rebuilt each turn)
β β βββ session_digest.py # Session memory facade (snapshot override + vault fallback)
β β βββ tool_reducer.py # Tool output β β€2k structured summary
β βββ recon_context.py # Target model pin builder + suggested action queue
β βββ agent_schema.py # Agent system prompt, decision hierarchy, response schema
β βββ session_graph.py # Derived branch-oriented view of session state from vault
β βββ planner.py # Branch-aware planning aid (strategic fallback advisor)
β βββ vault/ # Per-session RAG memory layer
β β βββ signatures.py # Canonical command signatures (cosmetic-flag normalization)
β β βββ index.py # command_index.json CRUD + preflight duplicate check
β β βββ builder.py # Index + SESSION_LOG.md builder from event stream
β β βββ digest.py # Evidence β structured digest extraction (+ tech/version detection)
β β βββ context.py # Context pack builder (β€5k budget for agent prompts)
β β βββ phase.py # Session phase derivation (RECONβANALYSISβEXPLOITATIONβPOST)
β β βββ cve_bridge.py # Tech β PURL mapping β OSV/GHSA/NVD CVE enrichment
β β βββ vuln_ledger.py # CVE + tool-confirmed finding lifecycle (DETECTEDβENRICHEDβVALIDATEDβEXPLOITABLEβEXPLOITED)
β βββ vault_guard.py # Proposal-time duplicate guard (checks before orchestrator)
β βββ target_model_guard.py # Action-to-evidence trace validator
β βββ validator.py # Command parsing + validation (shlex + tool-aware)
β βββ policy.py # YAML policy loading + validation
β βββ agent_client.py # Claude API client
β βββ executor.py # SSH command execution
β βββ policies/ # default_policy.yaml + posture_*.yaml
β βββ sessions/ # Per-run session data (gitignored)
β
βββ reports/ # Saved assessment bundles (gitignored)
β βββ summary_agent.py # Unified run bundle generator (3-style)
β
βββ tests/ # Test suite (pytest, 528 tests)
β
βββ docs/ # Architecture contracts + reference docs
| Directory | Contents | Generated By |
|---|---|---|
recon/evidence/collected/ |
DOM snapshots, network traffic, evidence metadata | Playwright collector |
operator_mode/sessions/<ID>/ |
Event log (JSONL), state snapshot, session digest, tool artifacts | Orchestrator |
operator_mode/sessions/<ID>/vault/ |
command_index.json, SESSION_LOG.md, evidence digests |
Vault builder |
reports/aegis-<target>-<timestamp>/ |
Run bundle: summary + report + target model | Summary agent |
recon/data/ |
SQLite vulnerability cache, CISA KEV cache | API clients |
python tools/clean.py # Clean all runtime data
python tools/clean.py recon # Recon data only
python tools/clean.py operator # Operator data only- Tool allowlist constrains active coverage. Only tools defined in the policy YAML are available; adding new tools requires a policy update and validator support.
- Vulnerability resolution depends on API availability. SQLite cache mitigates this, but first-run or expired-cache scans require OSV/GHSA/NVD connectivity.
- Results vary across operator sessions. Exploration paths differ based on agent reasoning and operator decisions; the Target Model and playbooks improve consistency but do not eliminate variance.
- Operator mode requires a Kali VM with SSH. No native execution; the VM must be running and reachable before starting a session.
- Long-running tools (nikto, sqlmap) produce no output for extended periods. Live output streaming via
script -qfcwrapper forces line-buffered stdout over SSH; the GUI output panel pins last-seen lines so they don't disappear between progress events. - Late-session duplicate slip-through. Signature normalization catches most duplicates, but edge cases (different flag combinations that produce equivalent scans) can slip through later in long sessions.
- Library detection is URL-based. Only libraries loaded via script tags with version-bearing URLs are detected; bundled/minified assets without version strings are missed.
- Operator exploration is evidence-biased. The Target Model Guard constrains proposed actions to candidates observed in recon; novel paths require explicit "expanding coverage" justification.
The system is functionally complete for end-to-end assessments (recon β operator β report). Live testing is ongoing against HackTheBox targets (VPN-connected labs including usage.htb), OWASP Juice Shop (Node.js/SQLite, deliberately vulnerable), and testfire.net (IBM Altoro Mutual β Apache Tomcat/JSP, real-world banking demo). Current testing validates whether the agent makes intelligent, methodology-driven decisions across a full engagement β not just technically correct ones.
The agent reliably:
- Runs nmap first (enforced by guard bypass for host-scan tools)
- Follows up with nikto and dirb/ffuf for vulnerability scanning and path discovery
- Filters static assets throughout (guard blocks CSS/JS/image curl proposals with hard error)
- Phases to ANALYSIS only after quality-gated coverage thresholds are met (meaningful port scan + path enumeration + tech detection)
- Responds immediately to operator commands via B0 pre-LLM intercept
- Propagates confirmed SQLi findings from sqlmap back into the vulnerability ledger, suppressing redundant re-probing
- Uses principles-based agent prompts (decision hierarchy, not rigid allowlist rules)
Phase 1: Recon β tuned and validated in live sessions.
- Session Phase System (
vault/phase.py):RECON β ANALYSIS β EXPLOITATION β POST_EXPLOITATIONgates derived from vault state with quality-gated thresholds. Phase directive injected at top of every prompt snapshot; GUI header badge shows current phase. - Phase Quality Gates: Port scan requires
port_count >= 1, path enumeration requirestotal_found >= 1in evidence digests. A tool that ran but found nothing does not satisfy the gate. Missing fields on older digests treated conservatively. - Recon Quality Bar (
gui/src/components/operator/OperatorTab.tsx): Live gate/metric indicator β nmap dot, path enum dot, cmd count, tech count, endpoints, forms. SSE state event emitted after every command so the bar updates in real-time. - CVE Enrichment Bridge + Vulnerability Ledger (
vault/cve_bridge.py,vault/vuln_ledger.py): Detected tech β PURL mapping β OSV/GHSA/NVD/KEV lookup β lifecycle ledger (DETECTED β ENRICHED β VALIDATED β EXPLOITABLE β EXPLOITED β CHAINED). Auto-runs after every evidence digest. - SQLi Finding Propagation (
vault/digest.py,api/services/next_action_service.py): Confirmed sqlmap findings are promoted directly toVALIDATEDin the vuln ledger. NextActionService reads validated surfaces and suppresses re-probing, replacing probe suggestions with exploitation guidance. Sqlmap--level/--riskflags are collapsed in signature hashing so different thoroughness levels produce identical signatures. - Target Model Guard β Host Scan Bypass (
target_model_guard.py): nmap, nikto, dirb, ffuf, whatweb, searchsploit, hydra unconditionally allowed (they target hosts, not paths). - Target Model Guard β Static Asset Block (
target_model_guard.py): curl proposals targeting.css/.js/.png/.gif/images/are hard-blocked. Static assets stripped from the guard's discovered-path allowlist at build time. - Static Asset Filtering Throughout: Digester level, unverified paths, branch
notable_discoveries, confirmed paths._WIN_DEVICE_REfilters COM1-9/AUX/NUL device names that Tomcat falsely serves as HTTP 200. - B0 Operator Command Intercept (
api/services/session_manager.py): Tool names in user messages bypass the LLM entirely β agent response synthesized deterministically. - Principles-Based Agent Prompts (
operator_mode/agent_schema.py): Decision hierarchy replaces rigid allowlist guard. Agent writes natural reasoning instead of parroting system prompt language. - HTB VPN Support (
api/routers/operator.py): Skip-preflight endpoint and GUI button for VPN-only targets where the host cannot reach the target directly. - NextActionService (
api/services/next_action_service.py): Canonical next-action coordinator consolidating heuristic ranking, planner branch strategy, and deterministic fallback into a single phase-aware pipeline. - Live Output Sticky Panel (
gui/src/components/operator/ChatPanel.tsx):pinnedLinesstate persists last-seen output lines even if subsequent progress events omit them. - SESSION_LOG HTTP Status Accuracy (
vault/builder.py): Curl entries show actual HTTP status from digest. [NO ACTION]Recovery Chain: 4-level recovery: retry β nudge β deterministic synthesis β planner fallback.- Architectural Refactor (Stages 0-8): SessionManager decomposed into focused services β AgentInteractionService, PhaseGateService, ValidationService, NextActionService. SessionPaths canonical path resolver. Orchestrator-layer defaults unified via
api/config.py.
Phase 2: Analysis β directive and gating issues identified in live testing, partially addressed.
- Rewrite
_PHASE_DIRECTIVES[ANALYSIS]to distinguish "no new broad enumeration" from "verify discovered high-value paths" - Add Analysis action priority ordering to
_populate_next_actions(): unverified high-value paths first, CVE research second - Searchsploit pipeline integration for CVE validation
- Add
get_analysis_criteria()invault/phase.py, wire into phase advance SSE and GUI bar - Fix CVE state machine:
ENRICHEDβVALIDATEDrequires searchsploit confirmation;VALIDATEDβEXPLOITABLErequires PoC - Fix CVE bridge product name mapping:
Apache-CoyoteβApache Tomcatfor searchsploit queries - Add _populate_analyst_notes() to prompt_snapshot.py (bounded Claude call for forward-looking reasoning)
- Reallocate prompt budget: raise snapshot, drop conversation history
Once analysis phase produces reliable, validated findings, exploitation can be driven by them:
- SQLi proof-of-concept: Agent manually probes login/search forms, confirms signal, then escalates to sqlmap on confirmed injectable parameters. Full chain: curl form fields β manual probe β boolean blind β sqlmap with
--dbs. SQLi finding propagation ensures confirmed injections are not re-probed. - Endpoint access: Discovered admin/bank/API endpoints that redirect to login β test for auth bypass, session fixation, or access control gaps.
- CVE-based exploitation: Agent ties validated CVEs to specific versioned assets, optionally validates in Docker sandbox, then applies to target.
- Evidence chain: Every exploit attempt must produce a finding entry in the vault with evidence pointer back to the specific command output.
A proposed extension to validate exploits in isolation before applying them to the target. When the agent discovers a versioned component with known CVEs (e.g., Express 4.17.1 β CVE-2022-24999), it can request an isolated Docker container on the Kali VM matching that version, attempt the known PoC against the sandbox, and, if successful, use the validated payload against the actual target.
Agent finds: Express 4.17.1 on target
β
Vulnerability Ledger: CVE-2022-24999 (qs prototype pollution, exploit available)
β
Exploit Staging Request:
1. SSH β Kali VM: docker run -d --name aegis-sandbox-001 -p 9001:3000 node:16-slim
2. Deploy minimal test harness (pre-built Express 4.17.1 template)
3. Agent tests known PoC payload against localhost:9001
4. Result: CONFIRMED EXPLOITABLE β ledger entry promoted to VALIDATED
β
Agent applies validated technique to real target with proven payload
Key design points: reuses existing SSH executor (Docker on Kali, no new VM), pre-built harness templates per ecosystem, hard timeout per sandbox (60s), new IntentSource.SANDBOX type. Draws from PTES Phase 5 methodology, MITRE CALDERA, and Vulhub CVE-indexed environments. Novel contribution: LLM-agent-driven sandbox orchestration for exploit validation.
Related academic work:
- "POMDPs Make Better Hackers: Accounting for Uncertainty in Penetration Testing" (Sarraute, Buffet, Hoffmann, AAAI 2012) -- models pentesting as a POMDP with AI planning for exploit selection
- "MulVAL: A Logic-based Network Security Analyzer" (Xinming Ou, Govindavajhala, Appel, USENIX Security 2005) -- Datalog-based attack graph generation
- "PentestGPT: Evaluating and Harnessing Large Language Models for Automated Penetration Testing" (Deng et al., USENIX Security 2024) -- LLM agents solving CTF challenges and guiding pentesting decisions
Testing has revealed a fundamental design tension: the agent loop is purely LLM-driven with reactive guard rails. The planner, session graph, and phase system provide rich strategic data, but they only advise. The LLM still decides what to do each turn, and it frequently makes low-value choices (returning no-action commentary, ignoring phase directives).
The correct architecture inverts this: planner decides strategy, agent fills in details.
Current: LLM decides β guards catch mistakes β fallbacks recover
Better: Planner picks branch + action type β LLM fills specifics β guards validate
This means the planner would select "branch: injection_testing, action: sqlmap on /api/Products?search=" and the agent would determine the specific flags and payloads. This is tractable now that Stages 0-8 have decomposed session_manager.py into focused services with clear ownership boundaries.
- Observed request modeling: HTTP method/path/query keys from network log mapped as typed API candidates in the Target Model
- Confirm vs Expand budgets: per-session caps distinguishing confirmation-mode from exploration-mode
- SARIF export: standard static analysis results format
- Session replay + diff: compare two operator sessions against the same target
- Auto-approve rate cap: max N consecutive auto-approvals before requiring manual continue
- Expand test target coverage (DVWA, additional HackTheBox machines, internal lab targets)
The CLI entry point (aegis.py β cli/interactive.py) still exists on disk but is no longer maintained. All current development and testing uses the Web GUI. The CLI and GUI share the same core orchestrator, so functionality is equivalent, but the GUI provides the approval queue, phase suggestion cards, recon quality bar, session map, and live output panel that the CLI lacks.
Legacy CLI invocation (for reference only):
# Interactive mode
python aegis.py
# With target pre-set
python aegis.py --target http://localhost:3000
# Batch mode (non-interactive)
python aegis.py --target http://localhost:3000 --batch --mode fullThe CLI produces the same run bundle and session artifacts. If you need headless operation, the FastAPI backend endpoints can be driven directly without the React frontend.
This project is intended for educational and research use only.
- Only run against systems you own or have explicit written permission to test.
- Unauthorized security testing is illegal and unethical.
- The authors are not responsible for misuse.
License: MIT
Research Support:
- Stetson University Department of Computer Science
- Dr. Daniel Plante, Faculty Advisor
Security Data Sources:
- OWASP Top 10 (2021), NVD/CVE, OSV.dev, GHSA, CISA KEV
Technology Stack:
- Ollama (local LLM hosting), Playwright (browser automation), Anthropic Claude API, Qwen 2.5 / Llama 3.1