New:Socket for Asana Is Now Available.Learn more
Get Started

@openai/codex-security

Package Overview
Dependencies
Maintainers
18
Versions
22
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@openai/codex-security

TypeScript SDK and CLI for Codex Security

latest
Source
npmnpm
Version
0.1.21
Version published
Weekly downloads
24K
19.03%
Maintainers
18
Weekly downloads
 
Created
Source

@openai/codex-security

Run Codex Security scans from TypeScript or the command line. This ESM-only package includes TypeScript declarations and the Codex runtime.

Before version 1.0.0, minor releases may change the public API.

Install

npm install @openai/codex-security
npx @openai/codex-security --version

Use Node.js 22.13.0+ (22.x), 24.x, or 26.x on macOS, Linux, or Windows. Scans, exports, scan history, and saved findings also need Python 3.10+ (plus tomli on Python 3.10).

Run a scan from TypeScript

Sign in with npx @openai/codex-security login or set OPENAI_API_KEY or CODEX_API_KEY, then scan a repository you own or have permission to assess:

import { CodexSecurity } from "@openai/codex-security";

const security = new CodexSecurity();

try {
  const result = await security.run("/path/to/repository", {
    outputDir: "/path/outside/repository/results",
  });

  console.log(result.reportPath);
  console.log(result.findings.findings.length);
} finally {
  await security.close();
}

result.findings contains this scan's findings; repositoryFindings also includes earlier open findings when available. Matching earlier findings can make one extra model call, even with a cost limit.

Keep results outside the repository and restrict access: reports can contain source code, vulnerability details, and reproduction steps.

Validate an existing finding

const security = new CodexSecurity();
try {
  const result = await security.validate({
    repositoryPath: "/path/to/repository",
    finding: {
      title: "Possible SQL injection",
      location: "src/query.ts:42",
    },
    outputDir: "/path/outside/repository/validation",
  });
  console.log(result.disposition);
  console.log(result.report);
} finally {
  await security.close();
}

Pass literal text or a JSON-serializable object as finding, not a file path. Validation uses the client's settings and credentials without changing repository files or adding a scan to history.

Results include disposition (reportable, suppressed, not_applicable, or deferred), a Markdown report, threadId, and evidence outputDir. reportable may rely on static analysis; deferred means insufficient evidence. Failed, incomplete, or malformed responses reject the promise.

outputDir must be empty and outside the Git worktree; it defaults to validations/ under the state directory. Pass auth to select credentials or signal to cancel.

Import GitHub code scanning alerts

Import alerts, including third-party SARIF uploads, and validate them against the matching local checkout:

import {
  CodexSecurity,
  importGitHubCodeScanningAlerts,
} from "@openai/codex-security";

const findings = await importGitHubCodeScanningAlerts({
  repository: "example/repository",
  alertNumbers: [12, 18], // Omit to list all open alerts on the default branch.
  githubToken: process.env["GH_TOKEN"],
});

const security = new CodexSecurity();
try {
  for (const finding of findings) {
    const result = await security.validate({
      repositoryPath: "/path/to/repository",
      finding,
    });
    console.log(finding.url, result.disposition, result.outputDir);
  }
} finally {
  await security.close();
}

Each result contains source, repository, number, url, and the full upstream alert. Import is read-only and does not start Codex or check out code.

Without alertNumbers, state filters alerts and defaults to "open". It also accepts "closed", "dismissed", "fixed", and "all". Exact alert numbers ignore state and reject a nondefault state. Use ref for another branch or pull-request reference.

Supply githubToken or use your gh auth token credentials, including GitHub CLI token environment variables. githubHost defaults to GH_HOST or github.com. The token needs read access to code scanning alerts; access failures reject the import. Pass signal to cancel.

SDK configuration and scan options

Constructor options:

OptionDescription
pluginPathPlugin directory or ZIP; defaults to the bundled plugin.
pythonPathPython interpreter; overrides PYTHON.
codexOverridesSupported settings to deep-merge into the isolated Codex configuration.

Options for security.run(repository, options) and security.preflight(repository, options):

OptionDescription
authCredential source: "auto", "chatgpt", or "api-key".
safetyIdentifierStable hashed end-user ID for model requests; requires API-key authentication.
targetRepository, repository-relative paths, committed diff, or working-tree diff.
mode"standard" or "deep"; deep mode supports repositories and paths.
knowledgeBasePathsArchitecture documents, security policies, threat models, or directories.
outputDirArtifact directory outside the enclosing Git worktree.
archiveExistingArchive existing results in outputDir before scanning.
maxCostUsdStop when estimated model cost exceeds this positive USD amount.
maxTimeHoursDeep-scan discovery limit in hours: greater than zero, up to 96.
failureSeverityFinding-severity policy to record in the saved scan recipe.
parentScanIdParent scan ID for a rerun.
expectedPluginVersionRequired original plugin version when replaying a scan.
signalAbortSignal to cancel a scan.

Follow scans with onWorkerStatus and onReconnect. onSessionEvent receives saved events with thread IDs and worker numbers; ScanOptions lists all callbacks.

preflight and CLI --dry-run check local inputs without starting Codex or using the network. They don't authenticate, verify model access, resolve Python, inspect the plugin, or run scan-lifecycle callbacks. Dry runs print effective settings.

Authentication

Sign in with ChatGPT:

npx @openai/codex-security login
npx @openai/codex-security scan .

Use device authentication on remote or headless machines:

npx @openai/codex-security login --device-auth

For CI, set OPENAI_API_KEY or CODEX_API_KEY. To save a key, pass it on stdin:

printenv OPENAI_API_KEY | npx @openai/codex-security login --with-api-key

Environment API keys apply to the current scan; only login --with-api-key saves them. Pass Codex access tokens on stdin to login --with-access-token. Access-token environment variables are not scan API keys.

For other inference providers:

export OPENROUTER_API_KEY="<your-openrouter-api-key>"
npx @openai/codex-security scan . --provider openrouter --model anthropic/claude-sonnet-4.5

export FIREWORKS_API_KEY="<your-fireworks-api-key>"
npx @openai/codex-security scan . --provider fireworks --model accounts/fireworks/models/qwen3-235b-a22b

export AWS_BEARER_TOKEN_BEDROCK="<your-bedrock-api-key>"
export AWS_REGION="us-east-2"
npx @openai/codex-security scan . --provider amazon-bedrock --model openai.gpt-5.6-luna

Bedrock also accepts AWS access keys, profiles, web identity, container credentials, and the default AWS credential chain. Set AWS_REGION and choose a Bedrock model with --model; OpenAI models such as openai.gpt-5.6-luna support --max-cost.

On Windows, set the API key in PowerShell:

$env:OPENAI_API_KEY = "<your-api-key>"
npx @openai/codex-security scan C:\code\repository

Login, logout, and scans share a private credential home: $CODEX_SECURITY_STATE_DIR/codex-home, or $CODEX_HOME/state/plugins/codex-security/codex-home. Codex uses the configured file or keyring storage and managed-device policies. If this home has no credentials, it imports an existing file-based Codex sign-in. Logout disables imports until you log in again.

Finish operations using older versions before upgrading. Runtime preparation holds the credential-home lock through pauses; exit or crash releases it. Compatibility heartbeats protect active locks from older heartbeat-only clients, but those clients can replace a paused client's lock.

Keep .codex-security-scan.sqlite3 between operations; never remove it during an operation. PID reuse can make old PID-only locks appear active and block recovery. Stop all operations using this home before removing an old .codex-security-scan.lock directory manually.

If ChatGPT credentials cannot be refreshed, run login status. Retry if the sign-in recently changed; otherwise run logout, then login.

Interactive scans ask whether to use ChatGPT or an environment API key when both are available. The choice applies to that scan. Noninteractive scans, including CI, JSON output, and dry runs, prefer the API key. Choose with --auth:

npx @openai/codex-security scan . --auth chatgpt
npx @openai/codex-security scan . --auth api-key

--auth chatgpt ignores environment API keys. --auth api-key requires OPENAI_API_KEY or CODEX_API_KEY. The default is --auth auto; unset both variables to default to ChatGPT. The SDK uses the same auth option on run and preflight. Codex may still need ChatGPT credentials to load workspace-managed policies when using an API key.

Some cybersecurity requests and protected findings require Trusted Access for Cyber approval. Apply or check your access at chatgpt.com/cyber.

CLI

npx @openai/codex-security scan .
npx @openai/codex-security scan /path/to/repository --path src --path tests
npx @openai/codex-security scan /path/to/repository --diff origin/main --json
npx @openai/codex-security scan /path/to/repository --output-dir /path/outside/repository/results
npx @openai/codex-security scan /path/to/repository --dry-run

Use scan --help for options, --version for the installed version, and info --json for package, plugin, runtime, and model details. --dry-run runs local preflight checks.

Scan options and output

--path scopes a scan to one or more paths, --diff scans committed changes, and --working-tree scans staged and unstaged changes. Deep scans support repository and path targets.

Working-tree snapshots include files from untracked nested Git repositories. Initialized submodules must be clean and checked out at the commit recorded by the parent repository.

Repeat --knowledge-base PATH for Markdown, text, PDF, or Word (.docx) files. Directories are searched recursively. Bulk scans share these documents with every repository.

Use an empty output directory outside the scanned directory and enclosing Git worktree. On macOS/Linux, existing directories must be private to you (chmod 700). --archive-existing moves previous results to <output-dir>.previous-<timestamp>-<id>; add --dry-run to preview the move. SARIF output, when produced, is at <scan-dir>/exports/results.sarif.

Scans are report-only by default. Set --fail-on-severity high to exit with 1 if a completed scan finds high or critical issues. Incomplete scans exit with 2, writing available results to stdout and a coverage warning to stderr.

Attribute scans to end users

When scanning on behalf of users, pass each user's stable hashed ID:

await security.run("/path/to/repository", {
  auth: "api-key",
  safetyIdentifier: hashedUserId,
});
codex-security scan /path/to/repository --auth api-key --safety-identifier hashed-user-id

Use a nonblank ID of 1 to 64 characters without NUL or personal data such as email addresses. It applies to the scan, workers, retries, and follow-up work without changing shared configuration. Supply it again for reruns.

The runtime needs native --safety-identifier support, and the plugin must forward it to workers. The bundled runtime doesn't support it yet; choose a compatible build with CODEX_CLI_PATH. The SDK checks the ID's format, not runtime or plugin compatibility. Older versions may omit the ID.

Scan project components

scan --path runs one scan across selected paths. To scan each local project component separately in standard mode, use scan-components:

npx @openai/codex-security scan-components /path/to/project \
  --component apps/api --component apps/web --component packages/shared \
  --workers 4 --output-dir /path/outside/project/results

Use --auto instead of --component for a proposed split. Save a plan to review or edit, then run it with a new output directory:

npx @openai/codex-security scan-components /path/to/project \
  --auto --plan-only --output-dir /path/outside/project/plan
npx @openai/codex-security scan-components /path/to/project \
  --components-file /path/outside/project/plan/components.json \
  --output-dir /path/outside/project/results

Components use repository-relative paths:

{
  "components": [
    { "name": "API", "paths": ["apps/api", "packages/auth"] },
    { "name": "Web", "paths": ["apps/web"] }
  ]
}

Automatic planning respects Git ignore rules and groups omitted files under Other files. Each proposed path must contain an inventoried file. Planning leaves source files unchanged.

Each component saves artifacts under component-N/. Combined findings.json merges high-confidence root-cause matches, keeping the highest severity and original IDs. Uncertain matches stay separate. summary.json records coverage and matching status; report.md links to component reports. Export and publish from the individual scan folders, not the combined summary.

Use an empty output directory outside the project. Failed components don't stop others, but failures, incomplete coverage, or failed matching exit with 2. Retry failed or incomplete components with --components-file retry-components.json and a new output directory.

--max-cost applies per component, excluding planning and matching. --model and --effort also apply to matching; --auth applies throughout. Use --knowledge-base, --scan-prompt-file, and --post-scan-prompt-file as for bulk scans.

From TypeScript, use runComponentScans({ repository, outputDir, components }). Use auto: true for planning, planOnly: true to save the plan without scans, and scanOptions.auth to select credentials.

Configure deep scans

For scan --mode deep, --workers sets discovery concurrency and --subagents sets subagents per worker. --stop-after-no-new stops after that many runs without new issues. --max-discovery-runs and --max-time-hours cap discovery runs and duration. SDK equivalents:

await security.run("/path/to/repository", {
  mode: "deep",
  workers: 2,
  subagents: 0,
  stopAfterNoNew: 3,
  maxDiscoveryRuns: 10,
  maxTimeHours: 1.5,
});

Set defaults in $CODEX_HOME/codex-security/config.toml:

[deep_scan]
workers = 4
subagents = 3
stop_after_no_new = 4
stop_after_consecutive_errors = 3
max_discovery_runs = 40
max_time_hours = 96

CLI and SDK options override these defaults. Set stop_after_consecutive_errors in the file; --codex cannot configure this section. Worker and run counts must be positive integers; subagents can be zero. Legacy workers = "auto" means four workers. Unknown keys are rejected.

max_time_hours accepts positive values up to 96, including fractional hours. At the deadline, discovery stops; the scan combines and returns completed findings.

scan --workers controls discovery workers within one deep scan; bulk-scan --workers controls how many repositories are scanned concurrently.

Runtime configuration and worker limits

Scans use these isolated Codex defaults instead of your user or repository configuration:

approval_policy = "on-request"
approvals_reviewer = "auto_review"
cli_auth_credentials_store = "auto"
model = "gpt-5.6-sol"
model_reasoning_effort = "xhigh"
model_reasoning_summary = "detailed"
show_raw_agent_reasoning = true

[features]
plugins = true
goals = true

[features.multi_agent_v2]
enabled = true
max_concurrent_threads_per_session = 9

[windows]
sandbox = "unelevated"

Use --model to choose a model and --effort minimal|low|medium|high|xhigh|max for reasoning effort. Repeat --codex KEY=VALUE for other TOML settings:

npx @openai/codex-security scan . \
  --model gpt-5.6-terra \
  --effort high \
  --codex features.multi_agent_v2.max_concurrent_threads_per_session=4

The thread limit of 9 includes the parent and up to eight delegated workers. It is separate from deep-scan and bulk-scan worker counts.

Quote string values as TOML, for example --codex 'model_reasoning_effort="high"'. Do not pass both --model and --codex 'model="..."', or both --effort and --codex 'model_reasoning_effort="..."': conflicting or repeated keys are rejected.

Choose plugins with --plugin-path. Overrides of plugins, marketplaces, or features.plugins are rejected, including in profiles. Multi-agent v2 must stay enabled: agents.max_threads and features.multi_agent_v2.enabled=false are rejected.

validate and patch accept --effort and the model and model_reasoning_effort keys in --codex, but no other runtime overrides.

See Local security model for approval and filesystem restrictions.

Environment variables

VariableEffect
OPENAI_API_KEY, CODEX_API_KEYScan credentials; OPENAI_API_KEY wins if both are set.
CODEX_SECURITY_LINEAR_TEAM, CODEX_SECURITY_LINEAR_PROJECTDefault team and project for completed-scan publication.
CODEX_SECURITY_LINEAR_API_KEYPersonal API key for Linear patching and direct publication.
CODEX_SECURITY_LOG_LEVELCLI-only; debug enables verbose diagnostics.
LOG_LEVELCLI-only fallback when CODEX_SECURITY_LOG_LEVEL is unset.
CODEX_SECURITY_STATE_DIRPrivate scan-history, workbench, and default artifact directory.
CODEX_HOMEAmbient Codex home for file-based sign-in and default state; defaults to ~/.codex.
CODEX_CLI_PATHCodex executable for authentication, plugin setup, scans, and workers.
PYTHONPython interpreter when --python or SDK pythonPath is unset.
GH_HOSTGitHub Enterprise host for interactive bulk-scan discovery.
CODEX_SECURITY_NO_UPDATE_NOTICE, NO_UPDATE_NOTIFIEREither variable disables interactive update notices.
CODEX_SECURITY_NPM_REGISTRY, npm_config_registry, NPM_CONFIG_REGISTRYUpdate-check registry, in precedence order.
CIDisables interactive update notices.
NO_COLOR, TERMDisables colored scan history when NO_COLOR is defined or TERM=dumb.

Custom Codex executables need thread source attribution for exec and app-server (Codex 0.149.1+). On Windows, use a native .exe or .com; command shims such as codex.cmd fall back to the bundled executable.

Python lookup order: --python (on scan, bulk-scan, or export) or SDK pythonPath, then PYTHON, the managed Codex runtime, and python3 or python on PATH (py also works on Windows). CODEX_SECURITY_STATE_DIR overrides CODEX_HOME for state storage. Keep state and results outside the repository.

Progress and cost

Interactive scans show full-screen progress; CI, redirected output, and --headless use plain status lines. Results go to stdout, progress and diagnostics to stderr. Add --verbose for diagnostics. Check logs for sensitive information before sharing them.

JSON results, scan history, and bulk-scan receipts record the model, tokens, and estimated cost. Estimates use standard API token prices, including cached input and cache writes, but exclude fees and surcharges.

--max-cost USD stops the scan and its workers when estimated cost exceeds the limit, though in-flight requests can finish above it. If deep-scan discovery has finished, the scan returns a sealed partial report without more model calls and lists unvalidated candidates as follow-up work. Bulk scans apply the limit per repository attempt.

Bulk scans

Run gh auth login, then npx @openai/codex-security bulk-scan to select GitHub repositories pushed in the last 90 days. Forks and archived repositories are excluded; private checkouts use your GitHub CLI sign-in. The command asks for an output directory and saves your selection there as repositories.csv. --output-dir requires CSV input.

For CI or an existing repository list, pass a CSV with id, repository, and revision (full commit hash). Optional scope, mode, and prompt columns customize each scan:

id,repository,revision,scope,mode,prompt
service,https://github.com/acme/service.git,0123456789abcdef0123456789abcdef01234567,src,standard,Focus on authentication and authorization.
npx @openai/codex-security bulk-scan repositories.csv \
  --output-dir /path/outside/repositories/security-scans --workers 4

--scan-prompt-file PATH adds instructions to a scan or all bulk scans. Each repository's CSV prompt follows the shared instructions. --post-scan-prompt-file PATH runs a follow-up in the same authenticated session, even after a failed or incomplete scan, but not after cancellation or a cost-limit stop.

--workers defaults to 4. --max-attempts defaults to 1 attempt per pending repository per invocation. Rerun the command to resume; bulk-scan --help lists all options.

Custom validation

Replace the final validation step of a standard or diff scan with a prompt file. Source review still runs; discovery workers do not receive this prompt.

npx @openai/codex-security scan . --validation-prompt-file validation.md

The SDK accepts the same text as validationPrompt:

const result = await security.run(repository, {
  validationPrompt:
    "Run scripts/validate.sh, test each candidate through the local API, and stop the test environment when finished.",
});

Put setup, allowed targets, required evidence, and cleanup in the prompt. There are no separate setup or teardown hooks. Use environment variables for credentials; keep secrets out of prompts and validation output. Deep scans reject this option; scans without candidates skip it.

The SDK supplies the candidate IDs and requires a CustomValidationResult:

{
  "status": "complete",
  "reason": null,
  "validations": [
    {
      "candidateId": "candidate-1",
      "validation": {
        "disposition": "reportable",
        "method": "integration test",
        "confidence": "high",
        "confidence_rationale": "The test reproduced the reported behavior.",
        "rubric": "Check the protected operation.",
        "evidence": ["The unauthorized request succeeded."],
        "counterevidence_or_proof_gap": "",
        "remaining_uncertainty": "",
        "artifact_paths": []
      },
      "severity": null,
      "impact": null
    }
  ]
}

Return one result per candidate with disposition reportable, suppressed, not_applicable, or deferred. Set severity or impact to { "level": "medium", "rationale": "..." } to revise an assessment, or null to retain it. Identity and source locations stay unchanged.

The scan saves candidates and results, including suppressed and deferred cases, under artifacts/custom-validation/. Coverage is incomplete if setup fails, output is incomplete or invalid, or any candidate is deferred. An incompatible plugin stops the scan; validation never falls back to the default. Repeat --validation-prompt-file on reruns.

Publish findings to Cloud

Choose completed scans from local history:

npx @openai/codex-security publish scan --to cloud --dry-run --json

Press Space to select scans, then Enter to submit. Nothing is preselected.

For scripts, repeat --scan with saved IDs or unique prefixes of at least eight characters:

npx @openai/codex-security publish scan \
  --scan SCAN_ID_A --scan SCAN_ID_B \
  --to cloud --dry-run --json

Find IDs with scans list --json, or use --scan latest for the current repository's latest completed scan. You still need the local sealed artifacts.

--dry-run checks inputs and prints findings without logging in or uploading. Uploads need ChatGPT credentials saved to a file. Set this in Codex config.toml, then sign in with ChatGPT again:

cli_auth_credentials_store = "file"

Cloud publication rejects automatic and keyring storage, even if an auth.json file exists: the file may be stale or belong to another account.

For CSV input, use an export from codex-security export --export-format csv:

npx @openai/codex-security publish scan --to cloud \
  --csv /path/outside/repository/findings.csv

The findings CSV template has the required columns; deep-scan exports may add candidate_id. --csv only supports Cloud and cannot be combined with scan IDs or directories.

For artifacts outside local history, pass a directory or repeat --scan-dir PATH. Each directory must contain one completed, sealed scan. Bulk-run directories and results.jsonl files aren't accepted. Don't mix directories with --scan.

Multiple scans return:

  • results: receipts or dry-run previews, each with its scanId and scanDir.
  • failed: errors with scanDir and, for saved selections, scanId.
  • notAttempted: saved scan IDs, or paths for directory inputs, that the command did not reach before cancellation.

One scan returns its result directly. Uploads run sequentially. A failed upload doesn't stop the rest, but the command exits with 2 if any failed. Cancellation stops new requests and returns results so far with 130 (Ctrl-C) or 143 (SIGTERM), unless all publications were already confirmed.

Save the output: Cloud receipts aren't stored in scan history. They contain Cloud finding IDs in request order, not local IDs. Uploads aren't retried automatically. Cloud may have accepted an upload even if its receipt is missing or invalid. Check Cloud before retrying; never resend a scan with a confirmed receipt.

Publish completed scans to Linear

Linear publication accepts one completed scan:

npx @openai/codex-security publish scan --scan SCAN_ID \
  --to linear \
  --linear-team TEAM_ID

Choose a scan by ID, unique prefix, latest, or directory (positional or --scan-dir PATH). Omit the selector for an interactive picker. Live publication and --skip-existing require the scan in local history; a directory-based --dry-run alone does not.

Add --linear-project PROJECT_ID (--project is an alias) to place issues in a project. Destination flags override CODEX_SECURITY_LINEAR_TEAM and CODEX_SECURITY_LINEAR_PROJECT. --dry-run previews issue titles without contacting Linear; --json returns structured results.

Sign in to Codex and connect Linear to publish with your existing Codex configuration; publication doesn't use the isolated scan home. To use the Linear API directly, set a personal API key:

export CODEX_SECURITY_LINEAR_API_KEY=YOUR_LINEAR_PERSONAL_API_KEY
npx @openai/codex-security publish scan /path/to/completed-scan \
  --to linear \
  --linear-team TEAM_ID

Direct API publication leaves issues unassigned unless --linear-assignee specifies a user ID or email. --linear-api-key KEY overrides the environment variable, but exposes the key in shell history and process listings. Keys are omitted from saved results and artifacts; error messages are returned unchanged.

Check scan integrity and recorded publications before publishing:

npx @openai/codex-security publish check /path/to/completed-scan \
  --to linear --linear-team TEAM_ID --json

publish check is read-only. With an API key it also checks authentication, team, project, and assignee access; connected-app access is not-checked. Issue-creation permission is always not-tested.

Each finding becomes an issue titled [Codex Security][HIGH] Finding title with source locations, code, evidence, and remediation. Choose a destination authorized to receive these details. Local history stores successful issue IDs separately from sealed scan artifacts.

Republishing creates duplicates by default. --skip-existing skips recorded successes for the same occurrence, team, and project, without checking remote issues. Results distinguish created and skipped issues. Add --dry-run to preview the remaining findings.

After an interrupted or indeterminate publication, check the retained handoff, evidence, and Linear destination before retrying. Issues may exist without a local record. The CLI can't recover those issues, and --skip-existing can't prevent duplicates from them or concurrent publications.

import { publishScan } from "@openai/codex-security";

const publication = await publishScan("/path/to/completed-scan", {
  destination: "linear",
  teamId: "TEAM_ID",
});

console.log(publication.scanId);
console.log(publication.created.length);

Options include projectId, skipExisting, linearApiKey for direct API publication, and assigneeId (user ID or email). checkScanPublication accepts the same destination options for a read-only check.

Scan history and reruns

Commands default to the current repository. Select scans by full ID or a unique prefix of at least eight characters.

CommandPurpose
scans list [REPOSITORY]List scans. Filter by artifact root with --scan-root DIR.
scans show [SCAN_ID]Show a scan; defaults to the latest completed one. --show-linked-findings includes earlier finding links.
scans logs [SCAN_ID]Show session events; defaults to the latest scan, including active scans.
scans rerun [SCAN_ID]Repeat a scan on the current checkout; defaults to the latest completed scan.
scans match BEFORE AFTERLink findings with the same root cause.
scans match --allMatch completed scans across the repository's worktrees and clones.
scans compare [BEFORE] [AFTER]Compare scans; defaults to the latest two completed scans.
findings list [REPOSITORY]List open findings. findings is an alias.
findings false-positive OCCURRENCE_ID --reason TEXTMark a false positive. Later scans dismiss matches only while the reason applies.

Matching requires sealed artifacts and reuses saved matches unless you pass --force. Comparisons classify findings as new, persisting, reopened, resolved, or unknown. Missing findings aren't resolved if the later scan is incomplete or excludes their original scope. With one ID, scans compare compares it to the latest completed scan.

History lives in $CODEX_SECURITY_STATE_DIR/workbench.sqlite3, or $CODEX_HOME/state/plugins/codex-security/workbench.sqlite3. The CLI and workbench maintain the database and its journal files as the current user. Keep state private, writable, and outside the scanned repository.

On Windows, an older sandboxed run can leave an invalid credential-home ancestor ACL. Preserve that state and its reports, and select a new, private CODEX_SECURITY_STATE_DIR outside both the old state and the repository. Sign in again if needed and keep using the new setting; it starts separate scan history. Existing ancestor ACLs are not rewritten.

Scan configurations don't store credentials; session logs and live details can contain them. Press d during a scan for details, then a for all sources, m for the main scan, or 1 through 9 for a worker.

Exports and CI

export writes CSV, JSON, or SARIF from a completed, sealed scan, defaulting to the current repository's latest completed scan. It doesn't start Codex or load credentials. Use --output - for stdout and --source-root PATH to add SARIF source-line fingerprints. export --help lists all options.

JSON preserves the sealed findings document. CSV marks findings as open, omits local triage state, and cannot go to stdout when JSON output is requested.

For CI, save output outside the checkout and set a severity threshold:

SCAN_ROOT="$(mktemp -d)"
npx @openai/codex-security scan . \
  --diff origin/main \
  --output-dir "$SCAN_ROOT/results" \
  --json \
  --fail-on-severity high > "$SCAN_ROOT/findings.json"

Scan exit codes are 0 for a completed report-only scan or passing policy, 1 for a policy violation, 2 for invalid input, incomplete coverage, or a runtime/export error, 130 for interruption, and 143 for termination. JSON scans do not use interactive controls. validate, login, and logout reject --json.

install-hook scans staged and unstaged changes before each commit. It blocks on high-severity findings or failed scans, respects core.hooksPath, and leaves existing hooks alone. Change the threshold with --fail-on-severity.

Import alerts from the CLI

import github OWNER/REPO reads open code scanning alerts from the default branch. Repeat --github-alert NUMBER for exact alerts. Filter with --github-state open|closed|dismissed|fixed|all or select a reference with --github-ref REF. Authentication follows the SDK import options.

# Import all open alerts, or a selected subset, as complete JSON.
npx @openai/codex-security import github example/repository --format json \
  > /path/outside/repository/github-alerts.json
npx @openai/codex-security import github example/repository \
  --github-alert 12 --github-alert 18 --format json
# Run from the corresponding local repository; imported contents are data.
npx @openai/codex-security validate /path/outside/repository/github-alerts.json

Import is read-only and returns an array ([] when empty). --json aliases --format json. Save validation inputs without output filters or token limits. Use the SDK loop for a disposition per alert.

Validate and patch findings

validate assesses candidates; patch fixes and verifies them. Both accept files or literal text and work in the current directory. Pass a saved finding or occurrence ID to patch to use its original repository.

Add --assess-patch-risk to a patch command to run the bundled patch-risk assessment skill once on the completed patch. The assessment is advisory and does not change the patch or its merge state. Human-readable commands print the report after the patch results; saved-finding JSON output returns it as patchRisk.report in the same result object. When combined with --create-pr, the draft pull request body includes only the concise Markdown summary from the assessment; the validated JSON remains in the command result.

npx @openai/codex-security validate "Possible SQL injection" --effort high
npx @openai/codex-security patch OCCURRENCE_ID
npx @openai/codex-security patch --scan SCAN_ID --severity high --json
npx @openai/codex-security patch --scan SCAN_ID --severity high --create-pr
npx @openai/codex-security patch --scan SCAN_ID --assess-patch-risk --create-pr
npx @openai/codex-security patch --linear-issue SEC-123 --assess-patch-risk --create-pr

--scan latest selects the current repository's latest scan. Saved-finding patch commands support --json; literal-text and file inputs don't. Change the model with --codex 'model="gpt-5.6-sol"' or effort with --effort high. Each finding gets its own saved Codex desktop task.

scan --patch patches after a complete scan. --patch-severity defaults to low; high selects high and critical findings. Use the interactive browser to select findings and add patch instructions. Results include a patches entry per finding with status verified, no_change, blocked, or failed. Verified and already-fixed findings no longer fail --fail-on-severity.

--create-pr commits generated patch files and opens a draft PR with gh. Supplied-issue pull requests require a clean working tree before patching so existing work is never included. If publication fails, run the printed patch --resume-pr BRANCH command in the same repository. It reuses the saved commit without rerunning Codex, but refuses to publish if the branch changed.

To patch Linear issues, repeat --linear-issue ISSUE (ID or URL), or use --linear-project "PROJECT" with an optional native JSON --linear-filter. Completed and canceled issues are excluded unless the filter sets state. Use CODEX_SECURITY_LINEAR_API_KEY or LINEAR_API_KEY for an API key, or LINEAR_ACCESS_TOKEN for OAuth. --linear-api-key KEY overrides these; prefer environment variables to keep keys out of shell history. Intake is read-only, includes comments, and keeps Linear credentials out of the patch subprocess. Issue URLs must match the selected workspace.

Verify fixes

verify-fix checks fixes in a read-only sandbox. Pass a description, saved finding ID, --scan SCAN_ID, --linear-issue ISSUE, or --linear-project "PROJECT". Linear credentials and filters work as for patch. To check a finished backlog, explicitly filter for completed issues.

Results include evidence and a status: fixed, still_vulnerable, or inconclusive. Use --json for structured output. Exit codes are 0 if all findings are fixed, 1 if any remain vulnerable, and 2 if verification is inconclusive or couldn't finish.

Command discovery and integrations

The CLI uses Incur. Use --llms for the command manifest, scan --schema --format json for a command schema, and completions bash|zsh|fish for shell completions. Scan output supports --format toon|json|yaml|jsonl and --full-output.

skills add syncs agent skills; mcp add registers the CLI as an MCP server. MCP exposes only the read-only info command because the transport cannot cancel active scans.

Containerized bulk scans

Create repositories.csv as described under Bulk scans. With a published image, run from the Codex Security repository root:

mkdir -p results state
chmod 700 results state
export CODEX_SECURITY_USER="$(id -u):$(id -g)"
export CODEX_SECURITY_IMAGE=ghcr.io/openai/codex-security:latest
docker compose pull codex-security
docker compose run --rm codex-security login --device-auth
docker compose run --rm codex-security

Results go to results/; device login stays in state/. For unattended scans, set OPENAI_API_KEY or CODEX_API_KEY. Private GitHub checkouts use GH_TOKEN or GITHUB_TOKEN; GitHub Enterprise uses CODEX_SECURITY_GIT_HOST. The container requires CSV input, without interactive discovery.

Compose accepts CODEX_SECURITY_IMAGE, CODEX_SECURITY_USER, CODEX_SECURITY_SECCOMP, CODEX_SECURITY_CSV, CODEX_SECURITY_RESULTS, and CODEX_SECURITY_STATE for the image, user, seccomp profile, and mounts.

On Ubuntu hosts that restrict unprivileged user namespaces, an administrator can install the optional AppArmor profile:

sudo install -m 0644 docker/codex-security.apparmor /etc/apparmor.d/codex-security-container
sudo apparmor_parser -r -W /etc/apparmor.d/codex-security-container
docker compose -f compose.yaml -f compose.apparmor.yaml run --rm codex-security

The override keeps the nonroot user, dropped capabilities, no-new-privileges, and seccomp policy. Other Docker hosts don't need it.

Local security model

Codex Security runs with your operating-system permissions. Only scan repositories you trust and are authorized to assess. Local tools and scans under the same account aren't separate security principals.

The codex_security_scan profile allows reads across the local filesystem and writes to workspace roots. Execution approvals are reviewed automatically and may grant extra permissions for one operation. Set --codex 'approval_policy="never"', directly or in a selected profile, to deny requests. Other overrides can't replace the reviewer or filesystem profile. Saved scans keep their approval policy; older scans stay deny-all on rerun. Host and network restrictions still apply.

Start scans with only the credentials they need. Scan and workbench subprocesses can inherit your environment, including unrelated API tokens and cloud credentials.

Repository contents, model output, and imported artifacts do not authorize access to other targets, disclosure of credentials, or writes outside approved paths. See the security policy below for the full threat model.

Documentation and security

FAQs

Package last updated on 27 Aug 2026

Related posts