Docs / Agent & automation / CLI & CI
The CLI & CI pipeline
The short version. Crusader is the same engine on the desktop and on the command line. Every verb prints JSON to stdout; errors go to stderr as error: <msg> with exit code 1. That makes every command pipe-safe — you can jq the output, gate a build on it, or hand it to an agent. Basic verbs (send, history, import, read-only sql) are Free; the full automation surface — active scanner, hunt, identity writes, mcp write tools — is Hunter Pro (FullCli). This page is the command catalog, four worked examples, and a scriptable scan-over-imported-traffic pipeline you can drop into CI.
01How the CLI behaves
There is one binary. A packaged install exposes it as crusader <verb>; from a source checkout the same thing is dotnet run --project .\CrusaderAvalonia.csproj -- <verb>. Start with the built-in catalog:
# list every verb and its subcommands
crusader cli help
# or, from a source checkout
dotnet run --project .\CrusaderAvalonia.csproj -- cli help
Three contracts hold for every command, which is what makes the CLI scriptable:
- Output is JSON on stdout. One result object (or array) per invocation. Nothing decorative is written to stdout, so you can pipe straight into
jqor a file. - Errors are on stderr, exit code 1. Failures print
error: <msg>to stderr and return a non-zero status — soset -e,&&chains, and CI step-failure all work the way you expect. - It shares the desktop workspace. The CLI reads and writes the same
~/.crusaderworkspace as the GUI (relocate it withCRUSADER_HOME). A capture fromcrusader sendlands in the same History the app shows; animportfrom the CLI opens in the app.
Because stdout is pure JSON, a clean run is silent except for the result object. If a command prints nothing and exits non-zero, check stderr — that's where the error: line is.
02The command catalog
The verbs group by what they touch. The tables below cover the surface; crusader cli help (or crusader <verb> --help) is always the authoritative, version-matched reference. Tier notes call out where a verb's write/active path needs Hunter Pro.
Project & import
| Verb | What it does |
|---|---|
project | List, create, and switch the active project (each project is its own history DB). |
import | Load traffic from another tool — burp, har, saz, fiddler, caido, or scope (Burp Target Scope JSON). Free; never modifies the source file. |
settings | Read and set workspace settings. |
scope | View and edit the engagement's in/out-of-scope rules. |
license | status / features / accounts / switch / activate <key> / trial / free. |
update | Check for and apply Crusader updates. |
Capture & replay
| Verb | What it does |
|---|---|
proxy | serve the intercepting proxy (emits JSONL), plus status / install-ca / cert-path. |
send | Fire a one-off HTTP request and capture the exchange. The CLI's curl. |
repeater | send <history-id> — re-issue a captured request. |
intruder | detect / run — payload-driven fuzzing (Sniper Free; other modes Pro). |
intercept | Drive interception (Off / Watch / Hold) from the shell. |
ws | Inspect captured WebSocket traffic. |
pass-through | Single probe, e.g. --url <url> --mode probe-url. |
transport | JA3 / curl-impersonate sidecar: install / status / start / stop / test (Pro). |
Search & navigate
| Verb | What it does |
|---|---|
history | list / search captured exchanges, with --sort and a direction flag. |
sitemap | The endpoint tree; filters like --auth-gated / --idor / --mutating / --untested / --ghosts (smart flags Pro). |
sql | Read-only SQLite over the project history DB — tables / schema / query. |
compare | compare <id-a> <id-b> [--unified|--side-by-side]. |
dashboard | Project overview / activity rollup. |
Find & prove (Pro)
| Verb | What it does |
|---|---|
scanner | run over captured History, findings to filter results, test <traffic.jsonl>. Passive is Free; active proof replay is Pro and needs a target scope. |
findings | list / get / add / read — the unified findings store (export is Pro). |
hunt | run — replays captured History with saved identities for IDOR / access-control. Needs traffic + an identity. Not a URL probe. |
idor | candidates / scan / explain — IDOR-specific helpers. |
beacon | Out-of-band callbacks: payload --kind http|dns|smtp [--purpose ...] and callback review (BYO Free; hosted Pro). |
mtls | mTLS client-cert extraction workflow (Pro). |
mobile | Mobile / Frida instrumentation workflow (Pro). |
Identity, agent & extend
| Verb | What it does |
|---|---|
identity | list / get / rename / use / active / create / delete / refresh / export-pfx / import-pfx (writes Pro). |
agent | guide / status / next / memory / plan / mcp-config / tools — the planner loop for coding agents. |
mcp | serve the MCP server (stdio JSON-RPC), tools to print the catalog (write tools Pro). |
plugin / ext | preview / install JavaScript plugins (community plugins Free; advanced APIs Pro). |
llm | prompt <history-id> — BYO-AI analysis of an exchange (Pro). |
Decode & transform
| Verb | What it does |
|---|---|
decoder | Encode/decode: Auto, URL, HTML, Base64, Hex, JSON, Protobuf. |
match-replace / mr | Request/response rewrite rules (Free capped at 10 active regex rules; unlimited Pro). |
body | decode / encode / history — request/response body helpers. |
protobuf | decode / encode protobuf payloads. |
graphql | GraphQL request helpers. |
headers | Header inspection / manipulation helpers. |
03Worked examples
Each of these is copy-pasteable. They all write a JSON result to stdout, so the pattern is always the same: run it, pipe it, gate on it.
Send a request
send is the CLI's curl: it issues the request through the same stack the proxy uses and returns the full exchange as JSON. Use --no-history to keep one-off probes out of your capture log:
# authenticated GET; don't record it in History
crusader send GET https://target.example/api/me \
-H 'Authorization: Bearer x' --no-history
Query History, sorted
history list and history search both take --sort = number|id|time|date|timestamp and a direction (--asc / --desc, or --direction asc|desc); the default is Number / Desc. Pipe the JSON into jq to reshape it:
# 20 most recent exchanges, newest first
crusader history list --sort number --desc --limit 20
# search a path, sort by capture time, pull a flat table with jq
crusader history search "/api/users" --sort date --desc --limit 20 \
| jq -r '.[] | [.id, .method, .status, .url] | @tsv'
Run the scanner, get findings JSON
The scanner runs over already-captured History — it is not a crawler. Passive analysis is Free; active proof replay (Hunter Pro) needs a target scope set, or the run hard-fails. --json emits the findings as one object you can redirect:
# active scan over captured traffic for one host → findings.json
crusader scanner run --host target.com --json > findings.json
# passive-only run (Free) — no active proofs
crusader scanner run --host target.com --passive --json > findings.json
Run active scans and hunts only against systems you're authorized to test. The active scanner refuses out-of-scope hosts and private / loopback / link-local / cloud-metadata IPs at connect time — but scope authority is yours to set.
Replay traffic for IDOR with hunt
hunt run is access-control testing, not a URL probe: it replays the requests already in your History using your saved identities and compares what each actor can reach. It needs captured traffic plus at least one identity:
# list identities first — hunt needs at least one
crusader identity list
# replay History across identities for IDOR / access-control drift
crusader hunt run
04A CI scan pipeline
Because the CLI is headless and JSON-first, you can run a scan in CI over traffic you captured earlier. The shape that works well: capture once, export the traffic, then in CI import it into a fresh project, set scope, scan, and gate the build on the findings JSON. The scanner reads History, so the job's input is a traffic file, not a live crawl.
Step 1 — capture and export the traffic (once)
During an engagement, browse the target through Crusader's proxy so the requests land in History. Then export that History to a portable JSONL file — this is the artifact CI consumes. The scanner's test verb accepts a .jsonl / .jsonl.gz traffic file directly, so commit a sanitized capture (or publish it as a build artifact) for the pipeline to pick up.
Step 2 — the pipeline script
This script is the body of a CI job. It imports the captured traffic into a clean project, sets a target scope (required for the active scan), runs the scan to findings.json, and fails the build if any High/Critical finding is present. Every step is gated with && so a non-zero exit stops the job:
#!/usr/bin/env bash
set -euo pipefail
# 1. fresh project from the captured traffic artifact
crusader import har ./artifacts/target-traffic.har --name "ci-$(date +%F)"
# 2. scope is REQUIRED — an active scan hard-fails without it
crusader scope add "*.target.com"
# 3. scan over the imported History; JSON to a file
crusader scanner run --host target.com --json > findings.json
# 4. gate the build: fail if any HIGH or CRITICAL finding exists
crusader scanner findings --severity HIGH --json \
| jq -e 'length == 0' > /dev/null \
|| { echo "High-severity findings — failing build" >&2; exit 1; }
Swap import har for import burp / saz / fiddler / caido depending on where your traffic came from. The scanner test ./artifacts/target-traffic.jsonl.gz verb is an alternative when you want to scan a traffic file without first importing it into a named project.
Active proof replay is Hunter Pro (FullCli + ActiveScanner); the CI runner needs an activated license (crusader license status tells you the tier in JSON). For a Free pipeline, add --passive to scanner run — passive analysis still produces findings JSON, just without active proofs, and doesn't require scope.
Step 3 — collect the results
The job leaves a machine-readable findings.json you can publish as an artifact, post to a tracker, or diff against the previous run. Findings carry severity, status, module, endpoint and (for confirmed active findings) a ProofPack reproduction. Note that report export — Markdown, SARIF, JSON, CSV, HackerOne / Jira — is Hunter Pro (Reporting); local findings stay available either way, but generating an exported report file is gated.
05Tiers & gotchas
The CLI never crashes on a gated call: invoking a Pro verb on Free returns a normal JSON result with "code": "requires_upgrade" (carrying the feature, required_tier, and a hint to run crusader license status) — not an exception. Design scripts to read that field rather than relying on a thrown error.
- Free CLI:
send,history,import, read-onlysql,decoder/body/protobuf/graphql,compare,sitemap(no smart flags), passivescanner run --passive, BYObeacon, Sniperintruder, read-onlymcp. - Hunter Pro CLI (
FullCli): activescannerproof replay,hunt run,identitywrites,mcp servewrite tools,mtls,mobile, JA3transport, report export, fullintrudermodes, unlimited match-and-replace. - Active scan needs scope.
scanner run(active) hard-fails without a target scope. Set it withcrusader scope add <pattern>first. hunt runreplays History, it does not probe a URL. No captured traffic or no saved identity means nothing to replay.- It's the same workspace. CLI and GUI share
~/.crusader(override withCRUSADER_HOME), so a CI runner and a desktop pointed at the same home see the same projects.
The 14-day Hunter Pro trial needs just an email (no card), and an active lease keeps an offline grace of 21 days — handy when the CLI runs on a headless CI box or VPS. crusader license status reports the current state as JSON.
Want a guide that isn't here yet? Email hello@crusaderproxy.com.