ravage

How To Use

This guide covers the source-checkout workflow for running Ravage against controlled, authorized targets.

Ravage is not a public-internet scanner. Use it only against systems you own or are explicitly authorized to test. The active CLI is localhost-first: expose the authorized app on 127.0.0.1 or localhost, then put that URL in the brief.

What Ravage Does

Ravage takes an engagement brief, checks scope, runs tools, records evidence, and writes a report. You choose one of two normal workflows:

Both workflows write the same kind of run directory, so you can inspect, compare, and resume them the same way.

Configure A Brief

The brief is the user-facing configuration file. It should say what target is authorized, what behavior is allowed, and whether this is a broad assessment or a targeted retest.

For a normal web pentest, use a broad objective:

engagement_id: "99999999-9999-4999-8999-999999999999"
scope:
  in_scope:
    - "https://staging.example.test"
  out_of_scope: []
roe:
  max_rps: 5
  no_destructive_actions: true
  data_handling: "placeholders_only"
objectives:
  - "web_application_assessment"
budget:
  max_cost_usd: 5.0
  max_runtime_min: 20

Use api_security_assessment when the target is primarily an API. Use specific classes like xss, jwt, or sql_injection only for targeted retests or lab runs. Clean XBEN runs should not include vulnerability-class hints; let the agent derive hypotheses from the challenge description and live target evidence.

Ten-Minute Quickstart

This quickstart runs the local Acme lab and a deterministic scan. It does not call a model.

  1. Install the checkout:
git clone https://github.com/duriantaco/ravage.git
cd ravage
scripts/bootstrap.sh
source .venv/bin/activate
ravage --version
  1. Start the lab:
ravage lab up ravage-acme-box --labs-dir examples/labs
  1. In another terminal, run a scan:
ravage scan examples/labs/ravage-acme-box/brief.yaml \
  --run-dir runs/quickstart-acme-scan \
  --probe surface_map \
  --report
  1. Inspect the result:
python -m json.tool runs/quickstart-acme-scan/report.json | head -80
ravage audit verify runs/quickstart-acme-scan
ravage lab down ravage-acme-box --labs-dir examples/labs

Expected result: the run directory exists, report.json is present, and audit verification prints audit verify OK.

Use the agent only after the scan workflow is working:

ravage attack examples/labs/ravage-acme-box/brief.yaml \
  --model-profile local-ollama \
  --model-tier mid \
  --tool-runtime auto \
  --memory off \
  --max-turns 18

Install From Source

Use Python 3.12 and install the checkout:

cd ravage
scripts/bootstrap.sh
source .venv/bin/activate

Verify the CLI:

ravage --version
ravage init --target-url http://127.0.0.1:8080
ravage setup check --brief brief.yaml

If an old virtualenv entry point still imports orchestrator, rerun bootstrap. It repairs stale .venv activation paths and reinstalls the editable checkout:

scripts/bootstrap.sh

For development runs before reinstalling, call the module directly:

PYTHONPATH=packages/ravage/src:packages/schemas/src \
  .venv/bin/python -m ravage --help

Manual install equivalent, when you are not using bootstrap:

python3.12 -m venv .venv
source .venv/bin/activate
python -m pip install "setuptools>=68" wheel
python -m pip install --no-build-isolation -e .
ravage --version

Check Tool Runtime

Ravage can run with host tools, Docker-backed tools, or auto mode. Auto mode uses host tools when available and falls back to the configured Docker image.

List supported tool binaries:

.venv/bin/ravage tools list

Check local and Docker availability:

.venv/bin/ravage tools check

Install or build supported external tools from the source checkout:

scripts/install_tools.sh --method docker --execute
.venv/bin/ravage tools check

Start A Local Lab

Local labs are deliberately vulnerable. Keep them on localhost or an isolated private lab network.

docker compose -f examples/labs/ravage-acme-box/docker-compose.yml up --build

In another terminal, confirm the target is reachable:

curl -sS http://127.0.0.1:8080/

Run Deterministic DAST

Use ravage scan when you want a reproducible run without model calls:

.venv/bin/ravage scan examples/labs/ravage-acme-box/brief.yaml \
  --run-dir runs/acme-scan \
  --tool-runtime auto

Useful options:

Run The Agent

Use ravage attack for the model-driven ai-web loop:

.venv/bin/ravage attack examples/labs/ravage-acme-box/brief.yaml \
  --model-profile local-ollama \
  --model-tier mid \
  --tool-runtime auto \
  --memory off \
  --max-turns 18

For hosted routes, set the provider key and opt into paid model use:

OPENAI_API_KEY=... \
.venv/bin/ravage attack examples/labs/ravage-acme-box/brief.yaml \
  --model-profile hosted-openai \
  --model-tier low \
  --tool-runtime auto \
  --memory off \
  --allow-paid-models

Attack run directories are stateful. Leave --run-dir unset for normal new runs so Ravage creates a timestamped directory. If you set --run-dir yourself, use a new path for each fresh attack. Reusing an old attack workspace is blocked unless you pass --resume.

Important options:

Resume And Observe

Resume an attack by pointing at the same run directory and passing --resume:

.venv/bin/ravage attack examples/labs/ravage-acme-box/brief.yaml \
  --run-dir runs/acme-attack \
  --resume \
  --memory off

Open the observer for an existing run:

.venv/bin/ravage observe runs/acme-attack

The observer follows an existing run directory. Start it in a separate terminal after the run directory exists.

Outputs

Attack and scan runs write a consistent run shape:

Verify the audit hash chain:

.venv/bin/ravage audit verify runs/acme-attack

What Success Looks Like

A successful run is not just “the process exited.” Check these artifacts:

runs/acme-attack/
  audit.db
  agent.stdout
  report.json
  report.html
  workspace/
    events.jsonl
    transcript.jsonl
    artifacts/

For ravage scan, stdout is scan.stdout instead of agent.stdout.

Use this quick checklist:

How To Read report.json

Start with these fields:

For a finding, check:

If a report has no findings, inspect agent.stdout or scan.stdout, then workspace/events.jsonl, to see whether the run failed early, lacked tools, ran out of turns, or simply found no evidence.

Memory

Memory is design-stage in the current public CLI. ravage attack accepts --memory off for reproducibility parity, but active memory retrieval, writes, review, and promotion are not wired into the current entry point.

.venv/bin/ravage attack examples/labs/ravage-acme-box/brief.yaml \
  --model-profile local-ollama \
  --model-tier mid \
  --memory off

Use live tool evidence for findings and flags. Treat Memory Design as architecture context until ravage --help shows active memory commands.

For public benchmark runs, state that memory was off.

XBEN

Set the benchmark root to a clean checkout, then run no-spend selection or preflight first:

export XBEN_ROOT=/path/to/validation-benchmarks/benchmarks
PYTHONPATH=packages/ravage/src:packages/schemas/src \
  .venv/bin/python -m ravage xben \
  --benchmarks-root "$XBEN_ROOT" \
  --output-dir runs/xben/preflight \
  --ids XBEN-001-24 XBEN-002-24 \
  --mode black-box \
  --agent ai-web \
  --model-profile hosted-openai \
  --model-tier low \
  --tool-runtime host \
  --max-turns 8 \
  --max-model-requests-per-case 8 \
  --preflight

Run selected cases after checking preflight:

PYTHONPATH=packages/ravage/src:packages/schemas/src \
  .venv/bin/python -m ravage xben \
  --benchmarks-root "$XBEN_ROOT" \
  --output-dir runs/xben/selected \
  --ids XBEN-001-24 XBEN-002-24 \
  --mode black-box \
  --agent ai-web \
  --agent-mode ctf-free-roam \
  --model-profile hosted-openai \
  --model-tier low \
  --tool-runtime host \
  --max-turns 8 \
  --max-model-requests-per-case 8 \
  --allow-paid-models

Use --resume or --retry-failed for follow-up runs. When rerunning a failed benchmark investigation, select only the failed IDs so results stay readable.

Troubleshooting

Short Glossary