Skip to content

Scan Workflows

Use this guide for the operator workflow. Commands is the exhaustive flag reference; Configuration explains runtime and configuration resolution.

TaskCommandBoundary
Web application0sec scan --target https://staging.example.com --scope ./scope.jsonActive network assessment
MCP endpoint0sec scan --target mcp://server.example.com --scope ./scope.jsonActive MCP assessment
Local source or Git repository0sec review ./my-appSource review; preparation and tools can access the network
npm package0sec audit expressPackage acquisition and analysis
Whole-repository file coverage0sec file-review ./my-appFile-level review with its own checkpoints
Seedless specialized review0sec deep-review ./my-appMulti-lens discovery; survivors remain leads

Explicit commands avoid ambiguity in bare-target routing. scan --mode selects probe, deep, mcp, web, or worker-driven http_audit. A review target profile is different: review --target c-library ./libfoo selects the C-library review path, not a URL.

For variant hunting, specification checks, fuzzing, binaries, and kernel workflows, see Research Workflows.

scan requires an engagement scope for HTTP, HTTPS, and MCP targets, including localhost. Worker-driven http_audit instead builds its policy from operator-provided configuration. Neither --require-scope nor its absence is a way to bypass the live-target requirement.

Start with the schema and matching rules in Scope & Authorization. Authorize only the hosts, paths, and activities covered by your engagement.

Terminal window
0sec scan --target https://staging.example.com --scope ./scope.json

Scope is an application-level policy, not an OS sandbox. Source review and package audit do not require a live-target scope file, but can acquire dependencies, clone repositories, or execute tooling. Run untrusted inputs on a disposable worker without unrelated credentials.

Terminal window
0sec scan --target https://staging.example.com --scope ./scope.json \
--attribution-header "X-Customer=acme-corp" \
--attribution-ua "pentest-engagement" \
--engagement-profile conservative

The conservative posture changes request behavior, rate defaults, and WAF-evasion behavior. --no-waf-evasion explicitly disables the adaptive evasion path. These settings do not grant authorization. See Authorized Engagements for precedence and limits, rather than assuming every setting follows one global merge rule.

Provider credentials pay for model calls. Target credentials authenticate to the assessed application. Cloud login is a third, separate credential flow.

Terminal window
0sec scan --target https://staging.example.com --scope ./scope.json \
--auth ./auth.json --api-spec ./openapi.yaml --depth deep

--auth accepts a JSON object or a file containing one. Supported forms include:

{"type":"bearer","token":"your-target-token"}
{"type":"cookie","value":"session=your-session-cookie"}
{"type":"basic","username":"test-user","password":"your-test-password"}
{"type":"header","name":"X-API-Key","value":"your-target-api-key"}

Keep credential files out of version control and prefer a file over secrets in shell history. API Keys covers provider authentication; White-Box Mode covers adding --repo source context to a live assessment.

--depth quick, default, and deep select different investigation budgets. They are not guaranteed wall-clock deadlines, and a clean result does not prove the absence of vulnerabilities.

Terminal window
0sec scan --target https://staging.example.com --scope ./scope.json \
--depth quick --cost-ceiling 5 --rate-limit 2

--cost-ceiling bounds tracked model spend. --timeout is not a universal command deadline. Rate limits, provider/runtime billing, and partial-run behavior have separate contracts; see Budget Management.

scan --features enables supported feature tokens. fp-moat is a preset, not a claim that every layer ran or that all remaining findings are reproduced.

Terminal window
0sec scan --target https://staging.example.com --scope ./scope.json \
--features fp-moat

Inspect per-finding triage provenance. A skipped layer and an unrecorded layer are different. Features lists current toggles; Finding Triage explains the evidence gates.

The default output is terminal. json, md, and sarif support machine-readable or text exports:

Terminal window
0sec scan --target https://staging.example.com --scope ./scope.json \
--format json > scan.json
0sec review ./my-app --format sarif > results.sarif

HTML and PDF output write a timestamped report under the system temporary directory and print its path. Redirecting stdout does not relocate the generated report. scan does not register --report-path; copy the emitted file to durable storage. See Integrations.

Current scan storage is run-local: by default ~/.0sec/runs/<scan-id>/state.db, subject to the configured state root. --db-path selects an explicit database. Do not assume every command uses a single ~/.0sec/0sec.db.

Terminal window
0sec scan --target https://staging.example.com --scope ./scope.json \
--db-path ./engagement.db
0sec history --db-path ./engagement.db
0sec findings --db-path ./engagement.db

Keep the database and associated run artifacts when handing off or resuming work. Cloud engagement IDs, console sessions, and scan IDs are not interchangeable.

Use the same database that holds the scan:

Terminal window
0sec findings --db-path ./engagement.db
0sec findings show FINDING_ID --db-path ./engagement.db
0sec findings accept FINDING_ID --db-path ./engagement.db
0sec findings suppress FINDING_ID --db-path ./engagement.db
0sec findings reopen FINDING_ID --db-path ./engagement.db

Replace FINDING_ID with the recorded ID or supported unique prefix. Accepting or suppressing a finding records a human decision; it does not execute a verifier.

For false-positive feedback and durable memories:

Terminal window
0sec triage mark-fp FINDING_ID --reason "Known test-only behavior" --db-path ./engagement.db
0sec triage memory add --finding FINDING_ID --reason "Known test-only behavior" --db-path ./engagement.db
0sec triage memory list --db-path ./engagement.db
0sec triage memory remove MEMORY_ID --db-path ./engagement.db

Review request/response evidence, source locations, lifecycle state, verifier outcomes, and triage provenance together. Persisted rows and discovery leads are not automatically confirmed findings.

Terminal window
0sec resume SCAN_ID --db-path ./engagement.db
0sec resume SCAN_ID --db-path ./engagement.db --format json
0sec resume SCAN_ID --db-path ./engagement.db --branch-from 12

Resume requires compatible persisted scan state. Journal-based branching also requires the relevant journal entries. Keep the run’s artifacts; a JSON report alone is not a resumable checkpoint. The standalone resume command supports specific persisted target routes, not every research or console workflow.

For a live scan that needs its explicit scope supplied again, use the scan entry point:

Terminal window
0sec scan --target https://staging.example.com --scope ./scope.json \
--db-path ./engagement.db --resume SCAN_ID

Do not assume standalone resume restores target credentials or authorization that are absent from its options. Console continuation has a separate contract in Console.

Terminal window
0sec replay
0sec replay --scan SCAN_ID
0sec scan --replay

Replay renders saved findings; it does not launch a fresh assessment or independently reproduce the vulnerability. verify is a different operation.

Blind Verification explains independent agent verification. Deterministic replay instead executes a particular finding, fixture, or reproduction bundle and records concrete assertions. Verification availability and outcomes depend on the selected path; do not assume every stored finding passed the same pipeline.

Terminal window
# Execute a finding with the selected runner.
0sec verify finding.json --runner docker
# Replay vulnerable and patched snapshots from a reproduction bundle.
0sec verify --bundle ./bundle-dir --runner docker
# Use the separate kernel-finding verification path.
0sec verify --kernel-finding finding.json --kernel-tree ./linux

A scan report containing many findings is not itself a single finding.json. Preserve the selected finding’s executable verification data and target context. The Docker runner requires its runtime prerequisites; local execution runs on the host. Kernel execution requires its own setup in Kernel VM Verification.

The fixture path is documented with a complete invocation in Verification Results. Reproduction bundles, runner-based replay, legacy PoC-step execution, and kernel verification have different result contracts. Inspect the emitted JSON and the mode’s exit semantics rather than interpreting every exit 2 as the same condition.

A negative replay result can mean the tested environment differs from the original finding. An inconclusive or failed setup is not evidence that a vulnerability is fixed.

fix takes a clean local Git worktree, not a finding file as its positional argument. Select one reproduced source finding, provide its verification contract, and supply an explicit regression command.

Terminal window
0sec fix ./my-app --finding ./finding.json \
--test-command "npm test" --output ./validated.apply-patch

The external finding must carry verificationSpec. If it does not already carry the required verification result, pass --verification-result ./verification-result.json. Alternatively select a persisted finding with --finding-id and --db-path.

The workflow generates and checks a candidate in an isolated worktree. --output writes validated apply_patch DSL, not a standard unified diff. By default it does not apply the candidate to the original worktree.

Terminal window
0sec fix ./my-app --finding ./finding.json \
--test-command "npm test" --apply

Only use --apply when you intend to modify the original repository. The regression command itself executes code; a separate worktree is not an OS sandbox.

ExitMeaning
0Validated candidate, or applied and retested
1Not fixed
2Precondition failed or error

See Commands — fix for the complete prerequisite and option reference.

Terminal window
0sec audit express --package-version 4.18.2
0sec audit requests --ecosystem pypi
0sec audit serde --ecosystem cargo
0sec audit alpine:3.20 --ecosystem oci
0sec review ./my-app
0sec review https://github.com/your-org/your-repository
0sec review ./my-app --diff-base origin/main --changed-only
0sec review --target c-library ./libfoo --depth deep
0sec review --target linux-kernel ./linux

Use the ecosystem and version actually covered by your authorization. --changed-only narrows the documented review path; it is not proof of whole-repository coverage. file-review and deep-review offer different coverage/analysis tradeoffs and do not share all of review’s options.

GitHub export and PR emission are external writes and require repository authorization and credentials:

Terminal window
0sec scan --target https://staging.example.com --scope ./scope.json \
--export github:your-org/security-findings
0sec scan --target https://staging.example.com --scope ./scope.json \
--emit pr --base main --dry-run

--dry-run controls PR emission only. The scan still runs. It is not a network-free preview or cost-free planning mode. Review Integrations and GitHub CI before enabling automatic external writes.

  • Scope refusal: supply a valid engagement scope; do not remove the target protocol to bypass authorization checks.
  • Missing findings or scan: check the run ID, state root, and selected --db-path.
  • Provider error: use API Keys and Configuration; cloud login does not automatically configure a model provider.
  • Interrupted or budget-limited run: inspect completion/error state and retained artifacts before deciding whether resume is supported. Zero findings from an incomplete run is not a clean pass.
  • Verification cannot execute: inspect the mode’s prerequisites and errors. Changing a finding’s human triage state will not repair an executable verification contract.
  • Fix refuses: check the clean Git worktree, source finding, verification evidence, and explicit regression command. Do not bypass preconditions by relabeling a finding.

For detailed runtime diagnosis, see Troubleshooting. For every command’s arguments and options, use Commands or 0sec COMMAND --help for your installed release.