breachlens CLI is a thin client: it scans nothing locally. It drives your
self-hosted BreachLens API — trigger a scan, wait for it, download the SARIF, and
turn the result into an exit code. That exit code is the whole point: 0 passes,
1 fails the build.
The CLI carries no scanners (~200 KB, Node ≥ 20). Your code is cloned and analysed
server-side on your BreachLens deployment — so the same binary drops into a
laptop pre-push hook, a GitHub Action, or a GitLab job with nothing but a different
--severity-gate.Install
Quickstart
Point it at your deployment, pass a token, name a target, and set a gate:How it works
1
Trigger
POST to the API. --repo owner/name hits /api/scans/from-github, which
auto-onboards the repo on first run; explicit IDs hit
/api/{repos,containers,domains}/:id/scan.2
Poll
Scans are async, so the CLI polls
/api/scans/:id every --poll-interval seconds
until COMPLETED (or FAILED), with a hard --timeout.3
Fetch SARIF
Downloads
/api/scans/:id/export.sarif to a file — the standard format your
pipeline can upload to its security tab.4
Gate
Counts findings by severity and compares to
--severity-gate. Any finding at or
above the threshold exits 1; none reports without ever failing.Authentication
Mint a scoped token in Settings → API Tokens with thescans:trigger and
scans:read scopes. Pass it as --token (or BREACHLENS_API_TOKEN); it authenticates
as Authorization: Bearer blt_…, scoped to your org. See the API reference for
token details.
Cloudflare Access
If your deployment sits behind a Cloudflare Access perimeter (a hosted / edge-fronted instance), a bare token gets bounced to the SSO login page. Supply a service token so the CLI’s requests clear the edge:Targets
Pass exactly one:--repo owner/name
Auto-onboards + scans a GitHub repo (needs the BreachLens GitHub App installed on that account).
--repo-id <id>
An existing BreachLens Repository — from its detail-page URL.
--container-id <id>
An existing Container image.
--domain-id <id>
An existing Domain (DAST / pentest target).
Options
Exit codes
The exit code is the CI signal — the same severity buckets the GitHub Action and GitLab template use, so verdicts always agree.In CI
Because only the exit code matters, the same command works two ways — a bypassable pre-push hook (advisory) and a required CI check (enforcing):Applying a license and the full runtime-enforcement behavior live on the
Self-hosting & air-gap page — the scan CLI itself
needs no license to run.