Skip to content

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.

  • 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.

bravos setup is the one command to run first. --check detects and prints, and never installs or prompts:

Terminal window
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 analysis

Truncated 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 available

Three things about this command are worth knowing before you rely on it.

  • It exits 3 when something is missing and 0 when the tiers it reports are available, so a provisioning script can branch on it.
  • --json carries 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 -y installs the tools Bravos itself manages, once those toolchains are in place.
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.

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.

  1. Bravos and Python.

    Terminal window
    bravos --version
    python3 -V
    bravos 0.1.0
    Python 3.12.13

    To a terminal, --version prints 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 still bravos 0.1.0.

  2. git.

    Terminal window
    git --version
    git version 2.53.0

    It comes from your operating system, not from Bravos: apt install git, brew install git, or the installer at git-scm.com.

  3. guardlink, the model tier’s other dependency.

    Terminal window
    guardlink --version
    2.0.0

    If this fails: npm install -g guardlink. See Install GuardLink.

    At this point the model tier works. Everything below is for the verify tier.

  4. cxg, the engine that runs the probes.

    Terminal window
    cxg --version
    cxg 1.3.0

    See Install Cert-X-Gen. The pentest pipeline inside it is materialised separately, by cxg pentest install. See Run a pentest.

  5. 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 --version
    Docker version 29.4.0, build 9d7ad9f
  6. A coding-agent CLI.

    Terminal window
    claude --version
    2.1.266 (Claude Code)

    codex and gemini are the alternatives. Which one a run uses is the --agent flag, or the default_agent key in $BRAVOS_HOME/config.toml.

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-readable

The 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

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:

Terminal window
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.0

Truncated 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.

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 ~/.bravos
note: 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 .bravos

New state is always written under the new name, so migrate whenever suits you:

Terminal window
mv ~/.bugb ~/.bravos
git mv .bugb .bravos
git 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.