116 [--provider {openai,openrouter,fireworks,amazon-bedrock}]116 [--provider {openai,openrouter,fireworks,amazon-bedrock}]
117 [--path PATH | --diff BASE | --working-tree]117 [--path PATH | --diff BASE | --working-tree]
118 [--head HEAD] [--base BASE]118 [--head HEAD] [--base BASE]
119 [--knowledge-base PATH]119 [--knowledge-base PATH] [--scan-prompt-file FILE]
120 [--mode {standard,deep}] [--model MODEL]120 [--post-scan-prompt-file FILE]
121 [--mode {standard,deep}] [--workers N]
122 [--subagents N] [--stop-after-no-new N]
123 [--max-discovery-runs N] [--model MODEL]
121 [--effort {minimal,low,medium,high,xhigh}]124 [--effort {minimal,low,medium,high,xhigh}]
122 [--output-dir DIR]125 [--output-dir DIR]
123 [--archive-existing]126 [--archive-existing]
124 [--plugin-path PATH] [--python PATH]127 [--plugin-path PATH] [--python PATH]
125 [--codex KEY=VALUE] [--fail-on-severity LEVEL]128 [--codex KEY=VALUE] [--fail-on-severity LEVEL]
126 [--max-cost USD] [--dry-run] [--verbose]129 [--max-cost USD] [--dry-run] [--headless] [--verbose]
127 [--json] [--format {toon,json,yaml,jsonl}]130 [--json] [--format {toon,json,yaml,jsonl}]
128 [--full-output] [repository]131 [--full-output] [repository]
129```132```
153To make stored credentials the automatic default, run156To make stored credentials the automatic default, run
154`unset OPENAI_API_KEY CODEX_API_KEY`.157`unset OPENAI_API_KEY CODEX_API_KEY`.
155 158
159### Use OpenRouter or Fireworks
160
161Select OpenRouter with its API key and an explicit model:
162
163```bash
164export OPENROUTER_API_KEY="your-openrouter-api-key"
165npx @openai/codex-security scan . \
166 --provider openrouter \
167 --model anthropic/claude-sonnet-4.5
168```
169
170Select Fireworks with its API key and an explicit model:
171
172```bash
173export FIREWORKS_API_KEY="your-fireworks-api-key"
174npx @openai/codex-security scan . \
175 --provider fireworks \
176 --model accounts/fireworks/models/qwen3-235b-a22b
177```
178
179Both providers also support `bulk-scan`.
180
156### Use Amazon Bedrock181### Use Amazon Bedrock
157 182
158Select Amazon Bedrock with `--provider amazon-bedrock` and specify an explicit183Select Amazon Bedrock with `--provider amazon-bedrock` and specify an explicit
220npx @openai/codex-security scan . --mode deep245npx @openai/codex-security scan . --mode deep
221```246```
222 247
248### Configure deep scans
249
250Use these options with `--mode deep` to control discovery concurrency and
251runtime:
252
253| Argument | Description |
254| ------------------------ | ----------------------------------------------------------------------- |
255| `--workers N` | Limit on concurrent discovery workers. Defaults to automatic selection. |
256| `--subagents N` | Subagents available to each discovery worker. Defaults to `3`. |
257| `--stop-after-no-new N` | Stop after `N` consecutive runs find no new issues. Defaults to `6`. |
258| `--max-discovery-runs N` | Limit on total discovery runs. Defaults to `60`. |
259
260`--subagents` accepts zero or a positive integer. The other options require a
261positive integer. These options aren't available for standard scans.
262
263For example, limit a deep scan to two discovery workers and ten total runs:
264
265```bash
266npx @openai/codex-security scan . \
267 --mode deep \
268 --workers 2 \
269 --subagents 0 \
270 --stop-after-no-new 3 \
271 --max-discovery-runs 10
272```
273
274Set persistent defaults in `~/.codex/codex-security/config.toml`, or in
275`$CODEX_HOME/codex-security/config.toml` when you set `CODEX_HOME`:
276
277```toml
278[deep_scan]
279workers = 2
280subagents = 0
281stop_after_no_new = 3
282max_discovery_runs = 10
283```
284
285Command-line options override these defaults. `scan --workers` controls
286discovery workers within one scan; `bulk-scan --workers` controls concurrent
287repository scans.
288
223### Add security context289### Add security context
224 290
225Use `--knowledge-base PATH` to provide architecture documents, threat models,291Use `--knowledge-base PATH` to provide architecture documents, threat models,
236skips linked directory entries, and keeps extracted document content302skips linked directory entries, and keeps extracted document content
237outside the saved scan results.303outside the saved scan results.
238 304
305### Add scan instructions
306
307To add scan instructions, provide a text or Markdown file with
308`--scan-prompt-file`. Use `--post-scan-prompt-file` to run follow-up
309instructions in the same authenticated session after a completed scan with
310complete coverage:
311
312```bash
313npx @openai/codex-security scan . \
314 --scan-prompt-file security-focus.md \
315 --post-scan-prompt-file follow-up.md
316```
317
318For example, use the scan prompt to focus on authorization boundaries and ask
319the follow-up to write a new `post-scan-summary.md` in the scan directory.
320
239### Set output and policy options321### Set output and policy options
240 322
241Use these options to keep artifacts, preserve earlier results, or create a323Use these options to keep artifacts, preserve earlier results, or create a
247| `--archive-existing` | Move existing results to `DIR.previous-<timestamp>-<id>` and start with an empty output directory. Requires `--output-dir`. |329| `--archive-existing` | Move existing results to `DIR.previous-<timestamp>-<id>` and start with an empty output directory. Requires `--output-dir`. |
248| `--fail-on-severity LEVEL` | Return exit `1` when a completed scan reports a finding at or above `critical`, `high`, `medium`, or `low`. |330| `--fail-on-severity LEVEL` | Return exit `1` when a completed scan reports a finding at or above `critical`, `high`, `medium`, or `low`. |
249| `--max-cost USD` | Stop a scan when its estimated model cost exceeds the specified USD amount. |331| `--max-cost USD` | Stop a scan when its estimated model cost exceeds the specified USD amount. |
250| `--dry-run` | Check the repository, target, output directory, and Codex configuration without starting a scan. |332| `--dry-run` | Check the repository, target, knowledge base, output directory, and Codex configuration without starting a scan. |
333| `--headless` | Show plain-text progress instead of the interactive scan dashboard. |
251| `--verbose` | Print redacted lifecycle, authentication, progress, and cost diagnostics to stderr. |334| `--verbose` | Print redacted lifecycle, authentication, progress, and cost diagnostics to stderr. |
252| `--json` | Print manifest, findings, coverage, paths, and turn metadata as one JSON document. |335| `--json` | Print manifest, findings, coverage, paths, and turn metadata as one JSON document. |
253| `--format FORMAT` | Print the complete scan result as `toon`, `json`, `yaml`, or `jsonl`. |336| `--format FORMAT` | Print the complete scan result as `toon`, `json`, `yaml`, or `jsonl`. |
254| `--full-output` | Print the complete result using the default structured output format. |337| `--full-output` | Print the complete result using the default structured output format. |
255 338
256The cost limit is an estimate, not a hard spending cap. Requests already in339The cost limit is an estimate, not a hard spending cap. Requests already in
257progress can finish above the limit, and partial scan results remain available.340progress can finish slightly above the limit. If a scan aborts due to the cost
341limit, partial scan results remain available on disk.
258 342
259When you omit `--output-dir`, results persist under343When you omit `--output-dir`, results persist under
260`$CODEX_HOME/state/plugins/codex-security/scans/<repository>`. `CODEX_HOME`344`$CODEX_HOME/state/plugins/codex-security/scans/<repository>`. `CODEX_HOME`
291 > /path/outside/repository/codex-security.json375 > /path/outside/repository/codex-security.json
292```376```
293 377
294A dry run checks local inputs without loading credentials, starting Codex, or378A dry run checks local inputs, including knowledge-base documents, without
295probing the plugin's Python interpreter:379loading credentials, starting Codex, or probing the plugin's Python
380interpreter:
296 381
297```bash382```bash
298npx @openai/codex-security scan . \383npx @openai/codex-security scan . \
309| --------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |394| --------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
310| `--auth {auto,chatgpt,api-key}` | Select the scan credentials. The default is `auto`. |395| `--auth {auto,chatgpt,api-key}` | Select the scan credentials. The default is `auto`. |
311| `--provider {openai,openrouter,fireworks,amazon-bedrock}` | Select the inference provider. The default is `openai`. |396| `--provider {openai,openrouter,fireworks,amazon-bedrock}` | Select the inference provider. The default is `openai`. |
312| `--model MODEL` | Select the model. The default is `gpt-5.6-sol`. Required with `--provider amazon-bedrock`. |397| `--model MODEL` | Select the model. The default is `gpt-5.6-sol`. Required for OpenRouter, Fireworks, and Amazon Bedrock. |
313| `--effort {minimal,low,medium,high,xhigh}` | Select the model's reasoning effort. The default is `xhigh`. |398| `--effort {minimal,low,medium,high,xhigh}` | Select the model's reasoning effort. The default is `xhigh`. |
314| `--plugin-path PATH` | Use a Codex Security plugin directory or ZIP to override the bundled plugin. |399| `--plugin-path PATH` | Use a Codex Security plugin directory or ZIP to override the bundled plugin. |
315| `--python PATH` | Select the Python interpreter for the plugin runtime. |400| `--python PATH` | Select the Python interpreter for the plugin runtime. |
360 [--provider {openai,openrouter,fireworks,amazon-bedrock}]445 [--provider {openai,openrouter,fireworks,amazon-bedrock}]
361 [--model MODEL]446 [--model MODEL]
362 [--effort {minimal,low,medium,high,xhigh}]447 [--effort {minimal,low,medium,high,xhigh}]
448 [--knowledge-base PATH]
449 [--scan-prompt-file FILE]
450 [--post-scan-prompt-file FILE]
363 [--max-attempts N] [--plugin-path PATH]451 [--max-attempts N] [--plugin-path PATH]
364 [--python PATH] [--codex KEY=VALUE]452 [--python PATH] [--codex KEY=VALUE]
365```453```
382```470```
383 471
384The CSV requires `id`, `repository`, and `revision` columns. Revisions must be472The CSV requires `id`, `repository`, and `revision` columns. Revisions must be
385full commit hashes. Optional `scope` and `mode` columns configure individual473full commit hashes. Optional `scope`, `mode`, and `prompt` columns configure
386repositories:474individual repositories:
387 475
388```csv476```csv
389id,repository,revision,scope,mode477id,repository,revision,scope,mode,prompt
390service,https://github.com/example/service.git,0123456789abcdef0123456789abcdef01234567,src,standard478service,https://github.com/example/service.git,0123456789abcdef0123456789abcdef01234567,src,standard,Review authorization boundaries.
391```479```
392 480
393`--workers` limits simultaneous scans and defaults to `4`. `--mode` defaults to481Use `--knowledge-base PATH` to share security documents across every
394`standard`, and `--max-attempts` defaults to `1`. Set `--max-attempts` when482repository. Use `--scan-prompt-file FILE` to add shared scan instructions; the
395you want to retry a repository after an error. Run the same command again to483CSV `prompt` column adds repository-specific instructions after that shared
396resume a bulk scan from its existing output directory. The CLI skips completed484prompt. `--post-scan-prompt-file FILE` runs follow-up instructions after each
397repositories only when their recorded result artifacts are still present.485completed scan with complete coverage.
486
487`--workers` limits simultaneous repository scans and defaults to `4`. `--mode`
488defaults to `standard`, and `--max-attempts` defaults to `1`. Set
489`--max-attempts` to retry repository or scan errors. Completed scans with
490incomplete coverage aren't retried. Their results remain available, and the
491command returns exit code `2`.
492
493Run the same command again to resume from an existing output directory. The CLI
494skips completed scans, including scans with incomplete coverage.
398 495
399For containerized campaigns, see [Run bulk scans in496For containerized campaigns, see [Run bulk scans in
400Docker](https://learn.chatgpt.com/docs/security/cli/bulk-scans#run-bulk-scans-in-docker).497Docker](https://learn.chatgpt.com/docs/security/cli/bulk-scans#run-bulk-scans-in-docker).
437 534
438### Match and compare findings535### Match and compare findings
439 536
440Match findings that share the same root cause across two scans:537Compare two scans to find new, persisting, reopened, resolved, and unknown
538findings:
441 539
442```bash540```bash
443npx @openai/codex-security scans match PREVIOUS_SCAN_ID CURRENT_SCAN_ID541npx @openai/codex-security scans compare PREVIOUS_SCAN_ID CURRENT_SCAN_ID
444```542```
445 543
446Compare the matched scans to find new, persisting, reopened, resolved, and544The comparison automatically matches findings that share the same root cause
447unknown findings:545and reuses saved matches. To save matches explicitly, use `scans match`:
448 546
449```bash547```bash
450npx @openai/codex-security scans compare PREVIOUS_SCAN_ID CURRENT_SCAN_ID548npx @openai/codex-security scans match PREVIOUS_SCAN_ID CURRENT_SCAN_ID
451```549```
452 550
453A finding is unknown when the later scan has incomplete coverage or doesn't551A finding is unknown when the later scan has incomplete coverage or doesn't
639without writing the complete scan result to stdout. Request `--json`,737without writing the complete scan result to stdout. Request `--json`,
640`--format`, or `--full-output` to send structured scan results to stdout.738`--format`, or `--full-output` to send structured scan results to stdout.
641 739
740Interactive terminals show a live dashboard with the current scan phase,
741reviewed files, activity, token usage, and estimated cost. CI and redirected
742output use plain-text progress. Add `--headless` to use plain-text progress in
743an interactive terminal:
744
745```bash
746npx @openai/codex-security scan . --headless
747```
748
642### Verbose diagnostics749### Verbose diagnostics
643 750
644Add `--verbose` to print redacted lifecycle, authentication, progress, and cost751Add `--verbose` to print redacted lifecycle, authentication, progress, and cost
758 865
759Set `OPENAI_API_KEY` or `CODEX_API_KEY`, sign in with866Set `OPENAI_API_KEY` or `CODEX_API_KEY`, sign in with
760`npx @openai/codex-security login`, or use an existing file-backed Codex867`npx @openai/codex-security login`, or use an existing file-backed Codex
761sign-in. For Amazon Bedrock, use a Bedrock API key or the standard AWS868sign-in. For OpenRouter or Fireworks, set the provider's API key and select a
869model. For Amazon Bedrock, use a Bedrock API key or the standard AWS
762credential chain instead.870credential chain instead.
763 871
764For credential selection, see [Select scan872For credential selection, see [Select scan
766 874
767For CI, keep the API key scoped to the scan step and use a trusted workflow.875For CI, keep the API key scoped to the scan step and use a trusted workflow.
768 876
769The CLI requires Node.js 22 or later. Running a scan or exporting findings also877The CLI requires Node.js 22.13.0 or later. Running a scan or exporting findings
770requires Python 3.10 or later. Python 3.10 also requires `tomli`. Use `--python`878also requires Python 3.10 or later. Python 3.10 also requires `tomli`. Use
771or `PYTHON` to select an interpreter when automatic discovery is unsuitable.879`--python` or `PYTHON` to select an interpreter when automatic discovery is
880unsuitable.
772 881
773Continue with the [CLI quickstart](https://learn.chatgpt.com/docs/security/cli), [bulk-scan882Continue with the [CLI quickstart](https://learn.chatgpt.com/docs/security/cli), [bulk-scan
774guide](https://learn.chatgpt.com/docs/security/cli/bulk-scans), [CLI FAQ](https://learn.chatgpt.com/docs/security/cli/faq), [CI883guide](https://learn.chatgpt.com/docs/security/cli/bulk-scans), [CLI FAQ](https://learn.chatgpt.com/docs/security/cli/faq), [CI