Use npx @openai/codex-security bulk-scan to review repositories in one
campaign. Discover repositories from your personal GitHub account or an
organization, or provide a CSV that pins every repository to an exact Git
revision.
The @openai/codex-security package is public. Running scans requires Codex
Security access. Follow the CLI quickstart to install
the CLI and sign in.
Choose a repository source
| Source | When to use it |
|---|---|
| GitHub discovery | Choose repositories interactively from your personal GitHub account or an organization. |
| CSV inventory | Run a repeatable, automated campaign against exact repository revisions. |
Both workflows save progress, preserve per-repository results, and let you resume a campaign after an interruption.
Discover GitHub repositories
Sign in with GitHub CLI:
gh auth login
Start an interactive bulk scan:
npx @openai/codex-security bulk-scan
The CLI guides you through these steps:
- Choose your personal GitHub account or an organization.
- Review repositories active within the last 90 days.
- Search the repository list and select repositories to scan.
- Choose a directory for scan results.
- Review the selected repositories and confirm the campaign.
Discovery excludes archived repositories and forks. The CLI records the exact
default-branch commit for each selected repository in
<output-directory>/repositories.csv. No scans start until you confirm the
selection.
To use GitHub Enterprise Server, first sign in to your GitHub host:
gh auth login --hostname github.example.com
Set GH_HOST when you start repository discovery:
GH_HOST=github.example.com npx @openai/codex-security bulk-scan
Interactive discovery requires a terminal. For CI, containers, or a prepared repository list, use a CSV inventory instead.
Create a repository CSV
Create a CSV with one row for each repository and pinned revision:
id,repository,revision,scope,mode,prompt
payments,https://github.com/example/payments.git,0123456789abcdef0123456789abcdef01234567,services/api,standard,Review payment authorization and refunds.
identity,https://github.com/example/identity.git,fedcba9876543210fedcba9876543210fedcba98,,deep,Review session and identity boundaries.
The CSV supports these columns:
| Column | Required | Description |
|---|---|---|
id | Yes | Unique repository identifier. Use letters, numbers, periods, hyphens, or underscores. |
repository | Yes | HTTPS URL, SSH URL, or local repository path. Relative paths resolve from the CSV directory. |
revision | Yes | Full 40- or 64-character Git commit SHA. Branch names, tags, and shortened commit hashes aren’t supported. |
scope | No | A repository-relative directory to scan. Omit the value to scan the full repository. |
mode | No | standard or deep. Omit the value to use the command’s selected mode. |
prompt | No | Scan instructions specific to this repository. |
To find a local repository’s full commit SHA, run:
git -C /path/to/repository rev-parse HEAD
Run a campaign from CSV
Pass the CSV and a private output directory outside the repositories:
npx @openai/codex-security bulk-scan repositories.csv \
--output-dir /path/outside/repositories/security-scans \
--workers 4
--workers controls concurrent repository scans and defaults to 4. It does
not set the number of discovery workers within each deep scan; configure those
limits through [deep_scan].
Use --mode deep to select deep scanning for rows without their own mode.
Each CSV row can still choose its own scan mode and repository scope.
The CLI checks out each pinned revision, scans the selected target, records the result, and removes the temporary repository checkout. A repository counts as complete only when its scan has complete coverage and all required result artifacts exist.
Share security context and instructions
Add architecture documents, threat models, or security policies to every scan
with --knowledge-base. Repeat the flag for more files or directories:
npx @openai/codex-security bulk-scan repositories.csv \
--output-dir /path/outside/repositories/security-scans \
--knowledge-base /path/to/architecture.md \
--knowledge-base /path/to/security-policies
To add shared scan instructions or run a follow-up after each completed scan, provide prompt files:
npx @openai/codex-security bulk-scan repositories.csv \
--output-dir /path/outside/repositories/security-scans \
--scan-prompt-file scan-instructions.md \
--post-scan-prompt-file follow-up.md
The CLI appends each repository’s CSV prompt after the shared scan
instructions. Follow-up instructions run in the same authenticated session only
after a validated scan has complete coverage. Prompt file paths resolve from
your current directory.
Choose a model and reasoning effort
Bulk scans use gpt-5.6-sol with xhigh reasoning effort by default. To
choose another model and effort for a CSV campaign:
npx @openai/codex-security bulk-scan repositories.csv \
--output-dir /path/outside/repositories/security-scans \
--workers 4 \
--model gpt-5.6-terra \
--effort high
The same options work during interactive repository discovery:
npx @openai/codex-security bulk-scan --model gpt-5.6-terra --effort high
Supported effort levels are minimal, low, medium, high, and xhigh.
To use OpenRouter or Fireworks, set OPENROUTER_API_KEY or FIREWORKS_API_KEY,
respectively, and specify --provider and --model. For credentials and
examples, see OpenRouter or Fireworks
setup or Amazon
Bedrock setup.
Review campaign results
The output directory contains the pinned campaign, an append-only results ledger, and separate artifacts for each repository and attempt:
security-scans/
├── manifest.json
├── results.jsonl
├── checkouts/
└── artifacts/
├── payments/
│ └── attempt-1/
│ ├── scan-manifest.json
│ ├── findings.json
│ ├── coverage.json
│ └── report.md
└── identity/
└── attempt-1/
├── scan-manifest.json
├── findings.json
├── coverage.json
└── report.md
manifest.jsonrecords the repositories, pinned revisions, scopes, scan modes, and shared or repository-specific instructions in the campaign.results.jsonlrecords each repository attempt, its status, artifact directory, and any available cost or error details.report.mdprovides a readable report for one repository attempt.findings.jsonandcoverage.jsonrecord that attempt’s findings and reviewed scope.
Export one completed repository scan when you need a portable result:
npx @openai/codex-security export \
/path/outside/repositories/security-scans/artifacts/payments/attempt-1 \
--export-format sarif \
--output /path/outside/repositories/payments.sarif
Results can contain source excerpts and vulnerability details. Keep the output directory private, outside scanned repositories, and subject to an appropriate retention policy.
Resume a campaign
Run the original command with the same CSV and output directory:
npx @openai/codex-security bulk-scan repositories.csv \
--output-dir /path/outside/repositories/security-scans \
--workers 4
The CLI resumes unfinished repository scans and skips completed ones. Scans
with incomplete coverage aren’t retried. Their results remain available, and
the command exits with code 2.
Don’t change the repository inventory or scan and follow-up instructions for an existing output directory. The CLI checks the pinned manifest and rejects a different campaign. Use a new output directory when you change repositories, revisions, scopes, scan modes, or shared or repository-specific instructions.
Retry repository errors
Use --max-attempts to retry a repository after a temporary checkout or scan
error:
npx @openai/codex-security bulk-scan repositories.csv \
--output-dir /path/outside/repositories/security-scans \
--workers 4 \
--max-attempts 3
The default is one attempt per repository. Every attempt receives its own receipt and artifact directory. Retries cover checkout errors, scan failures, and missing required artifacts. Completed scans with incomplete coverage aren’t retried.
Bulk scans use these exit codes:
| Exit code | Meaning |
|---|---|
0 | Every repository completed successfully. |
2 | A repository couldn’t complete, a scan had incomplete coverage, or the command encountered an input or runtime error. |
130 | Ctrl-C interrupted the campaign. |
143 | SIGTERM terminated the campaign. |
Run bulk scans in Docker
The Codex Security repository includes a hardened Compose configuration for automated CSV campaigns on a Linux Docker host. The host must support unprivileged user namespace creation.
Keep the repository CSV, scan results, and sign-in state mounted in persistent
directories. Supply OpenAI credentials through the environment or a secret
manager. For private GitHub repositories, provide GH_TOKEN or GITHUB_TOKEN
the same way.
Run the image with the mounted CSV and output directory:
docker compose run --rm codex-security \
bulk-scan /input/repositories.csv \
--output-dir /output \
--workers 4
Use the same mounted CSV and output directory to resume the campaign. For
GitHub Enterprise Server, set CODEX_SECURITY_GIT_HOST to your GitHub host.
For every available flag, see the bulk-scan command reference. For common questions about scan coverage and findings, see the CLI FAQ.