Run the loop unattended
The verify tier is one command once it has a plan. This page covers the three steps that get you there, describe the scan, approve the plan, run it, and how to resume when it stops.
Before you start
Section titled “Before you start”- The verify tier’s dependencies:
cxg, Docker, and a coding-agent CLI. See Install Bravos. - A target you are authorised to attack, and written authorisation you are willing to record. Read Authorization and blast radius first.
The path through
Section titled “The path through”-
Describe the scan.
bravos intaketakes a brief in your own words: the repository, the target URL, the identities, how deep to go. It turns that into a plan.Terminal window bravos intake "Thorough pentest of my app at /path/to/repo. It runs onhttp://127.0.0.1:9054, logins admin@example.com/Admin123! anduser@example.com/User123!. Go deep and find chained exploits."The plan it prints carries a plan id, and it is the thing to argue with: the target it resolved, the login shape it read out of the repository, the lens rotation, the round budget, and an explicit list of what it could not determine.
-
Approve it. Approving is the consent step; nothing before it sends traffic.
Terminal window bravos intake --listbravos intake --show <PLAN_ID>bravos intake --approve <PLAN_ID>With no plans yet,
--listsays so:no plans yet — try `bravos intake "<what you want>"`--forceapproves a plan that still has unresolved items. The run then pauses when it reaches one. -
Run it.
Terminal window bravos auto --plan <PLAN_ID>The plan supplies the target, the identities, and the attestation, so this is the whole loop: annotate, export, synthesise goals, probe, write back, report, rotate the lens, and repeat until it converges or halts.
Skipping intake
Section titled “Skipping intake”If you already have a target running and identities captured, drive it directly:
bravos auto /path/to/repo --target http://127.0.0.1:9054 \ --attestation "Authorized self-test, Jane Doe, 2026-08-18"--attestation is required for any run that sends traffic or edits code unless
the run came from an approved plan. It is recorded in cxg’s audit log as your
assertion that the target is yours to test.
Identities come from --cred, repeatable, or --creds-file:
bravos auto /path/to/repo --target http://127.0.0.1:9054 \ --cred alice:alice@example.com:Alice123!:admin \ --cred bob:bob@example.com:Bob123! \ --attestation "Authorized self-test, Jane Doe, 2026-08-18"The role defaults to user; mark the privileged identity admin. Bravos reads
the login shape off the target, logs each identity in, and saves a recipe so
sessions re-authenticate mid-run and later runs reuse them.
The alternative is to capture sessions first with bravos env login and pass
profile names with --auth. See
Manage a test environment.
The flags that change what a run costs
Section titled “The flags that change what a run costs”| Flag | Effect |
|---|---|
--rounds N |
maximum rounds this invocation |
--max-goals N |
cap goals per round |
--concurrency N |
simultaneous goals (default 3) |
--fast |
1 template per goal and 1 mutation retry, instead of the default 2 and 2 |
--trust-annotations |
treat an existing @confirmed as settled instead of re-verifying it |
--retest <THREAT_ID|KEY> |
forget a prior verification so the threat is tested again |
--no-checkpoint |
no branch, no per-phase commits |
--no-capture |
do not drive interactive logins inline; pause and print the cxg pentest auth commands instead |
--chain-declared-flows |
test a declared cross-service @flows edge as one chained attack. Roughly 120s and one AI generation call per extra template, on partnered goals only |
--fast favours speed over per-goal coverage, and its help text is explicit
about when that is the wrong trade: the thorough default is for discovery, fast
mode is for repeat and regression runs. A one-template goal has no partner to
pair with, so --fast and --chain-declared-flows together chain only on the
goals that have a declared partner to widen for.
Resume
Section titled “Resume”A run that is interrupted keeps its place. Journalling is per phase, so a completed step does not re-execute.
bravos resume 20260818-120316-nodegoat r2 resumable 20260817-221148-nodegoat r0 interrupted — resumable 20260814-114720-bravos_observability r1 registry 20260810-214147-portainer-2.39.2 r1 modelTruncated: this machine lists 25 runs. The right-hand column is what the run can
still do: resumable, interrupted — resumable, or the tier it stopped in.
bravos resume 20260818-120316-nodegoatA resume keeps the --ai-provider the run started with, so the provider that
generated a run’s probes does not change halfway through its ledger. Overriding
it re-stamps the run’s config, and a config that has drifted since the run began
is refused unless you pass --force-config-drift, because a ledger assembled under two
different settings is not auditable.
bravos resume --abandon <RUN_ID> stops tracking a run and keeps its artifacts.
Related
Section titled “Related”- The verification loop: what a round does, and how a run decides to stop.
- Read a run: the ledger, the reports, and the advisories a run leaves behind.
- Manage a test environment: the lab and the identities a run needs.

