Install Bravos
At the end of this page bravos setup --check reports READY, and the
machine can run the model tier at minimum. That is the state every other page
here assumes.
Bravos needs a different set of tools depending on how far you intend to go. The model tier needs two. The verify tier needs three more, and one of them is a coding agent that will edit your repository unattended.
Before you start
Section titled “Before you start”- Python 3.11 or newer. Bravos is a Python package, and 3.10 is refused at install time.
git. Bravos reads the repository’s branch, commit and files through it.
Ask the machine what it is missing
Section titled “Ask the machine what it is missing”bravos setup is the one command to run first. --check detects and prints,
and never installs or prompts:
bravos setup --check BRAVOS SETUP what this machine can run, and what would change that
MODEL TIER available annotate, threat model, report and dashboard — no traffic found bravos engine 0.1.0 found git 2.53.0 found guardlink 2.0.0
VERIFY TIER available live probes that prove exploitability — real traffic, gated by consent found cert-x-gen cxg 1.3.0 found coding agent 2.1.266 (Claude Code) found Docker Docker version 29.4.0, build 9d7ad9f Docker (optional): here, so Bravos can stand disposable test targets up from your repo — author a lab, run verify against it, tear it down, all hands-off.
SAST CHANNEL unavailable deterministic code analysis with codegraph reachability — separate from a run, never in the ledger absent bravos not on PATH — it is what runs the deterministic code analysisTruncated after the SAST channel’s first row. The full output explains both optional analyzer components, lists anything that has to be installed, and ends with a verdict line.
On a machine that has everything, that verdict is:
nothing to install — everything Bravos manages is already here
READY — model and verify tiers are availableThree things about this command are worth knowing before you rely on it.
- It exits
3when something is missing and0when the tiers it reports are available, so a provisioning script can branch on it. --jsoncarries the same facts, and more of them: per tool, what it is, what it unlocks, the exact install command, its source, and any caveat.- It will not install a toolchain for you. Node, Rust and your operating
system’s package manager are named, never run.
bravos setup -yinstalls the tools Bravos itself manages, once those toolchains are in place.
What each tier needs
Section titled “What each tier needs”| Tool | Model tier | Verify tier | What it is for |
|---|---|---|---|
bravos |
required | required | the loop itself |
| Python 3.11+ | required | required | Bravos is a Python package |
git |
required | required | reads the repository’s branch, commit and files |
guardlink |
required | required | parses the annotations, produces the SARIF export |
cxg |
required | executes the probes against the target | |
| Docker | required for a lab | stands the disposable target environment up | |
| a coding-agent CLI | required | the judgment points: annotation, recipe authoring, goal enrichment, write-back |
The agent CLI is one of claude, codex, or gemini. The
VS Code extension can supply the
editor’s own model instead, through Bravos’s bridge provider.
Prove you have them
Section titled “Prove you have them”bravos setup --check answers all of this in one go. These are the individual
checks, for when one of its rows disagrees with what you expected.
-
Bravos and Python.
Terminal window bravos --versionpython3 -Vbravos 0.1.0Python 3.12.13To a terminal,
--versionprints a block-letter BRAVOS mark above that line. To a pipe, a capture or a CI log it prints the version line alone, so$(bravos --version)is stillbravos 0.1.0. -
git.
Terminal window git --versiongit version 2.53.0It comes from your operating system, not from Bravos:
apt install git,brew install git, or the installer at git-scm.com. -
guardlink, the model tier’s other dependency.
Terminal window guardlink --version2.0.0If this fails:
npm install -g guardlink. See Install GuardLink.At this point the model tier works. Everything below is for the verify tier.
-
cxg, the engine that runs the probes.
Terminal window cxg --versioncxg 1.3.0See Install Cert-X-Gen. The pentest pipeline inside it is materialised separately, by
cxg pentest install. See Run a pentest. -
Docker, only if Bravos is to stand a lab up for you. A run against a target you started yourself does not need it.
Terminal window docker --versionDocker version 29.4.0, build 9d7ad9f -
A coding-agent CLI.
Terminal window claude --version2.1.266 (Claude Code)codexandgeminiare the alternatives. Which one a run uses is the--agentflag, or thedefault_agentkey in$BRAVOS_HOME/config.toml.
What a missing tool looks like
Section titled “What a missing tool looks like”Every refusal names the tool, says what it is, what it unlocks, and how to get it, rather than ending on a bare “not found”:
bravos: guardlink: not found on PATH, and `bravos inspect` cannot run without it what reads the threat-model annotations in your code and exports them as SARIF — it is where every exposure bravos reasons about comes from unlocks bravos inspect, bravos model, bravos annotate, bravos plan, bravos round, bravos run, bravos auto install npm install -g guardlink needs npm — install it from https://nodejs.org source https://github.com/Bugb-Technologies/guardlink next bravos setup --check what this machine has and is missing bravos setup --json the same answer, machine-readableThe what and unlocks lines wrap to your terminal’s width; they are one line
each.
That refusal exits 3, the code that means “this machine is missing something
Bravos needs”. It is deliberately not 1, which is reserved for a policy breach
so that a pipeline branching on 1 is never branching on a missing dependency.
| Exit | Means |
|---|---|
0 |
ok |
1 |
the answer is no: a policy breach or a failed gate |
2 |
the request could not be carried out as asked (usage, path, missing run) |
3 |
this machine is missing something Bravos needs. Run bravos setup |
130 |
interrupted |
Where Bravos keeps its state
Section titled “Where Bravos keeps its state”None of it is in your repository.
| Path | Holds |
|---|---|
$BRAVOS_HOME (default ~/.bravos) |
everything below |
$BRAVOS_HOME/runs/<run-id>/ |
one directory per run: manifest, journal, events, ledger, per-round goals, probe templates, cxg logs, reports |
$BRAVOS_HOME/envs/<slug>/ |
the environment recipe for one target, replayed on later runs |
$BRAVOS_HOME/plans/<plan-id>.json |
a derived scan plan, written 0600 |
$BRAVOS_HOME/config.toml |
optional. Every field has a working default |
Your repository receives exactly two things, and only on the verify tier: a
bravos/run-<id> branch, and annotation comments committed to it.
--no-checkpoint turns even that off. The reasoning is in
Authorization and blast radius.
Override the location with --home, or by exporting BRAVOS_HOME.
bravos config prints every setting and where it came from:
bravos config --show config file /Users/you/.bravos/config.toml not created yet — every value below is a default
[agents.claude] bin claude args -p, --dangerously-skip-permissions, --output-format, json, --strict-mcp-config, --setting-sources, user timeout_s 900.0Truncated after the first agent. The full output runs through every agent, the
provider, guardlink, cxg and the analyzer. bravos config --init writes the
file with every setting commented out.
Upgrading from bugb
Section titled “Upgrading from bugb”The CLI was called bugb up to and including 0.1.0, and the published package
installs one command, which is bravos. Everything the old name wrote is still
read, so an in-place upgrade needs no migration step.
| What you have | What happens |
|---|---|
the bugb command in scripts and CI |
replace it with bravos. The package installs one command, and bugb is not it |
~/.bugb full of runs |
used as the state root while ~/.bravos holds no runs of its own |
.bugb/ committed in a repository (policy.toml, sessions/, verifications.json) |
read as it stands, so a CI gate keeps the threshold you committed |
$BUGB_TOKEN, $BUGB_SERVER_URL, $BUGB_HOME in a pipeline |
still read |
git config bugb.server.url / bugb.projectId |
still read |
bugb/run-* branches, bugb/baseline/* and bugb/annotated/* tags |
still recognised |
Each of those says so once, on stderr, so bravos ci --format json stays a
document a pipeline can parse:
note: $BUGB_TOKEN is the old name for $BRAVOS_TOKEN and was used. Set $BRAVOS_TOKEN instead; $BUGB_TOKEN stops being read in a future release.note: reading state from ~/.bugb — the CLI was renamed from bugb to bravos and ~/.bravos holds no runs yet. Move it when convenient: mv ~/.bugb ~/.bravosnote: reading .bugb/ in /Users/you/demo — the CLI was renamed from bugb to bravos and this repository has no .bravos/ yet. Rename it when convenient: git mv .bugb .bravosNew state is always written under the new name, so migrate whenever suits you:
mv ~/.bugb ~/.bravosgit mv .bugb .bravosgit config bravos.server.url "$(git config bugb.server.url)"The old names are read, not supported forever. They stop being read in a future release.
- Build your first threat model: the model tier, end to end, in one command.

