Skip to content

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

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.

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 run

Ingest is content-addressed, so the same push repeated is a no-op:

sent 5
appended 0
duplicates 5 already on the server

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

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.

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.