White-box design (offat-whitebox)#
A static source-code security review pipeline modeled on the security-harness workflow: recon → code graph + patterns → chain → verify → report.
Run#
# From the repo (no install)
PYTHONPATH=whitebox:triager python3 -m offat_wb /path/to/repo -o offat-report/whitebox
# Installed (the [graph] extra enables the code-graph engine)
pip install ./triager './whitebox[graph]'
offat-whitebox /path/to/repo
| Flag | Default | Description |
|---|---|---|
target |
. |
Path to the codebase |
--classes |
all | Comma-separated classes to hunt |
--out, -o |
offat-report/whitebox |
Output directory |
--no-ai |
false | Heuristic triage only |
--provider |
auto | Triage backend: auto, anthropic, claude-code, codex, heuristic |
--no-graph |
false | Skip the code-graph taint engine |
--specs |
— | Extra source / sink / sanitizer specs (JSON) |
--local-sources |
false | Also treat argv / env / stdin as sources (CLI tools, scripts) |
--graph-out |
false | Export the code graph as JSON + GraphML |
--agent N |
0 | Re-verify the top N graph findings with the graph-tool AI agent |
--infer-specs |
false | Write the taint frontier; with a provider, let AI label missing sinks / sanitizers |
--semgrep |
false | Also run semgrep --config auto (opt-in) |
--no-graft |
false | Skip graft tracing (only used with --no-graph) |
--reachable-only |
false | Spend AI tokens only on endpoint-reachable findings; cap the rest (gray-box policy) |
--no-cache |
false | Do not read/write the AI-verdict cache |
--fail-on |
— | Exit non-zero if an actionable finding is at/above this severity (CI gate) |
AI triage runs against an Anthropic API key (OFFAT_AI_API_KEY) or a local
agent CLI — Claude Code (claude) or OpenAI Codex (codex) — selected with
--provider / OFFAT_AI_PROVIDER. See the shared triager
(../triager) for the full backend list and env vars.
Token discipline#
The verify stage uses the shared token-disciplined triager: verdicts are
cached by a content hash (re-runs pay only for new or changed findings), and
with the Anthropic API backend uncached findings are screened in batches by a
cheap model then only the confirmed/likely subset is verified by a strong
model. Tune with OFFAT_SCREEN_MODEL, OFFAT_VERIFY_MODEL, OFFAT_BATCH_SIZE,
or disable with --no-cache.
Stages#
recon#
Detects languages by file mix, inventories dependency manifests, and — when the tools are installed — generates an SBOM with syft and CVE findings with grype (falling back to trivy, then osv-scanner).
code graph#
The primary engine (overview). It builds a code property graph
of the repository (Python via ast, JavaScript / TypeScript via tree-sitter),
marks attacker-controlled sources and dangerous sinks, and proves source → sink
paths with an interprocedural, call/return-matched search. Every finding
carries its hop-by-hop path, entry points and HTTP route.
patterns#
A dependency-free, multi-language hunter for classes that are not data flows:
hardcoded secrets (AWS / Slack / GitHub / private keys), weak crypto (MD5 /
SHA1), disabled TLS verification and misconfiguration. Pattern hits in
injection classes are fused with the graph: a hit on a proven line is dropped as
a duplicate, a hit with no source reaching it is kept but demoted, and every hit
gains graph reachability. semgrep --config auto can be added with --semgrep.
chain#
Annotates co-located findings (same file, multiple classes) into simple attack paths — e.g. a hardcoded secret next to an outbound request.
verify#
The shared triager adversarially validates each finding (refute first) and
assigns verdict / CVSS / remediation, with caching and model tiering (see Token
discipline). It receives the proven path rather than a snippet. With
--agent N, a graph-tool agent re-verifies the top findings by reading callers,
callees, function bodies and backward slices. Offline heuristic when no key is
set.
report#
report.json, findings.jsonl, results.sarif (with codeFlows), report.md,
report.html, report.junit.xml. Use --fail-on <severity> to gate CI on actionable findings.
Every finding is mapped to a threat taxonomy - OWASP API Security Top 10
(2023), OWASP Top 10 (2021) and a primary CWE (each with names) - in a
threat block, and the report includes a Threat mapping summary counting
findings per OWASP API Top 10 category.
Deepening results#
The pipeline runs with no external tools. The [graph] extra enables the code
graph; syft and grype (or trivy / osv-scanner) add an SBOM and dependency
CVEs; --specs and --infer-specs extend the source / sink catalog for
in-house wrappers.
For a deeper, agentic, multi-pass review, the upstream security-harness Claude Code plugin emits the same finding and report schema.