The CLI, the server and CI
Bravos is one product delivered in three pieces. Only the first is free, and the line between them is worth being exact about, because a team that assumes CI is free until a pipeline tries it is worse off than one that was told.
| Where it runs | Cost | |
|---|---|---|
| The CLI | a developer’s machine | free |
| The server | your infrastructure | licensed |
| CI/CD execution | your pipeline | licensed |
The CLI
Section titled “The CLI”The bravos CLI is the only thing that runs a scan. It needs no server, no
account, and no network beyond whatever the target itself requires. A run reads
your repository, stands up a target, fires probes, and writes a ledger under
$BRAVOS_HOME/runs/<run-id>/. Nothing leaves the machine.
That includes the build gate. bravos ci reads a ledger and a policy file from
your repository and exits with a code, and it
contacts no server at all. A pipeline
can fail a build on a confirmed finding without anyone having bought anything.
| Capability | Needs a licence |
|---|---|
bravos auto, run, round, replay: the whole loop |
no |
| The ledger, verdicts, advisories and reports | no |
bravos ci, the build gate |
no |
bravos dashboard, the local read-only page |
no |
bravos mcp, the agent surface |
no |
bravos push, filing a run centrally |
needs a server, which is licensed |
| Running the loop inside the prebuilt CI image | yes |
Where the CLI stops
Section titled “Where the CLI stops”Its state is one directory on one machine. That is the limit, and it is a real one:
- A run is visible to whoever ran it. A colleague cannot read your ledger, and a security team cannot see what any developer proved.
- History is per machine. There is no view of what a repository looked like three runs ago unless those runs happened here.
- Nothing accumulates across repositories. Each checkout knows only its own runs.
The server exists to fix those three things and nothing else.
The server
Section titled “The server”bugb-server stores, serves, and governs findings that the CLI pushes to it. It
is a FastAPI process over Postgres, with bearer-token auth, hard tenant
isolation, and a read-only dashboard at /app.
One bravos push files several things, each an artifact the run had already
written to disk:
pushed 20260910-004305-demo → github.com/acme/demo-shop http://127.0.0.1:8123/v1/events sent 5 appended 5 duplicates 0 summary yes master dashboard no no threat-dashboard.html in the codebase advisories no no confirmed findings in this run templates no no confirmed findings in this runIngest is content-addressed, so the same push repeated is a no-op:
sent 5 appended 0 duplicates 5 already on the serverThat is the designed answer to a retry, not an error.
It is a licensed product, and the licence is what makes it work. A published
bugb-server image verifies a signed licence against a key stamped into the image
at build time. Without one it starts, says why in its log, and answers 402 to
every request until it holds one. The image itself is published to a private
registry, so pulling it needs a credential that comes with the licence. Seats
are enforced by the licence, at the moment a credential is minted. See
How licensing works.
CI/CD execution
Section titled “CI/CD execution”The third piece is running the loop inside a pipeline rather than on a laptop. Two things about a pipeline make that different from a local run:
- A job that installs cxg, guardlink, Playwright and a headless Chromium pays several minutes for every build.
- A gate whose own toolchain floats is not a gate. If the scanner changes version between two builds, the two verdicts are not comparable.
Both are answered by one artifact: a prebuilt runner image,
ghcr.io/bugb-technologies/bugb-ci, with every component pinned.
| Component | Pinned to |
|---|---|
| base | ubuntu:24.04, by manifest digest |
cxg |
v1.3.0, the public release binary, SHA256-verified against the release’s own SHA256SUMS |
| the cxg pentest pipeline | materialised at build time by cxg pentest install, from the binary’s embedded copy |
playwright and Chromium |
the version that materialised pipeline’s own requirements.txt names |
guardlink |
2.0.0, from public npm |
bravos |
a pinned commit, installed from source into the image |
The image is published to the same private registry as the server, and pulling it needs the same kind of credential. That is the gate: the CLI is free on a developer’s machine, and running it as a pipeline’s own toolchain is not.
Which pieces you need
Section titled “Which pieces you need”Run the CLI alone when one person is scanning one repository and the ledger on their machine is the audience. That is a complete product and it costs nothing.
Add the server when more than one person needs to read the same finding, or when a security team needs the history rather than the latest run.
Add CI/CD execution when the loop should run on every pull request rather than when somebody remembers.
Licences and deployment keys are issued at account.bugb.io.
Related
Section titled “Related”- How licensing works: the term, the daily refresh, and why verification never leaves your network.
- Run Bravos in CI/CD: what a pipeline can do today.
- Deploy the server with Docker Compose: standing one up.
- Connect the CLI to a server: what changes on a developer’s machine once there is one.

