29| `codex-security scans` | List, inspect, compare, and retrieve saved scan logs. |29| `codex-security scans` | List, inspect, compare, and retrieve saved scan logs. |
30| `codex-security findings` | Review and update saved security findings. |30| `codex-security findings` | Review and update saved security findings. |
31| `codex-security export` | Export completed findings as CSV, JSON, or SARIF. |31| `codex-security export` | Export completed findings as CSV, JSON, or SARIF. |
32| `codex-security publish` | Publish completed scan findings to Linear. |
32| `codex-security validate` | Check one or more candidate security findings. |33| `codex-security validate` | Check one or more candidate security findings. |
33| `codex-security patch` | Patch one or more security issues. |34| `codex-security patch` | Patch one or more security issues. |
34| `codex-security login` | Sign in, store credentials, or check sign-in status. |35| `codex-security login` | Sign in, store credentials, or check sign-in status. |
705 --output /path/outside/repository/exports/findings.csv706 --output /path/outside/repository/exports/findings.csv
706```707```
707 708
709## `codex-security publish scan`
710
711Publish every finding from a completed scan to Linear:
712
713```text
714usage: codex-security publish scan [SCAN_DIR] --to linear
715 [--linear-team TEAM_ID]
716 [--project PROJECT_ID]
717 [--linear-api-key KEY]
718 [--linear-assignee EMAIL_OR_USER_ID]
719 [--dry-run] [--json]
720```
721
722`SCAN_DIR` must contain a completed, sealed scan. Omit it in an interactive
723terminal to select a completed scan from local scan history. Creating issues
724also requires the scan and its findings to exist in local scan history. A dry
725run validates the sealed artifacts without this persistence check.
726
727| Argument | Description |
728| ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
729| `--to linear` | Publish to Linear. This argument is required. |
730| `--linear-team TEAM_ID` | Select the Linear team. Uses `CODEX_SECURITY_LINEAR_TEAM` when omitted; one of them is required. |
731| `--project PROJECT_ID` | Select a Linear project. Uses `CODEX_SECURITY_LINEAR_PROJECT` when omitted. If neither is set, issues are created directly in the team. |
732| `--linear-api-key KEY` | Use a Linear personal API key for direct publication. Uses `CODEX_SECURITY_LINEAR_API_KEY` when omitted. |
733| `--linear-assignee EMAIL_OR_USER_ID` | Assign created issues by email address or Linear user ID. Requires `--linear-api-key` or `CODEX_SECURITY_LINEAR_API_KEY`. Issues remain unassigned when omitted. |
734| `--dry-run` | Prepare issue payloads without starting Codex, contacting Linear, creating issues, or writing publication state. |
735| `--json` | Write structured publication results to stdout. Progress remains on stderr. |
736
737Linear issue descriptions and dry-run output can include source code snippets
738 and vulnerability details. Publish only to an authorized Linear team or
739 project, and treat saved output as sensitive.
740
741Each non-dry-run invocation attempts to create a new issue for every finding.
742Publishing the same scan again doesn't match, update, or reuse existing issues.
743If some findings fail, the command preserves successfully created issues and
744returns exit code `2`.
745With `--json`, review the `created` and `failed` results before retrying to
746avoid duplicates.
747
748Preview the issue payloads before publishing:
749
750```bash
751npx @openai/codex-security publish scan /path/to/completed-scan \
752 --to linear \
753 --linear-team TEAM_ID \
754 --dry-run \
755 --json
756```
757
758### Publish with the connected Linear app
759
760Without a Linear API key, the command starts Codex using your existing
761configuration and connected Linear app. Sign in and connect Linear to your
762Codex account before publishing:
763
764```bash
765npx @openai/codex-security login
766npx @openai/codex-security publish scan /path/to/completed-scan \
767 --to linear \
768 --linear-team TEAM_ID \
769 --project PROJECT_ID
770```
771
772### Publish with a Linear API key
773
774Supplying `--linear-api-key` or `CODEX_SECURITY_LINEAR_API_KEY` publishes
775directly through the Linear API and doesn't start Codex. Direct publication
776leaves issues unassigned unless you select an assignee:
777
778```bash
779export CODEX_SECURITY_LINEAR_API_KEY=YOUR_LINEAR_PERSONAL_API_KEY
780npx @openai/codex-security publish scan /path/to/completed-scan \
781 --to linear \
782 --linear-team TEAM_ID \
783 --linear-assignee teammate@example.com
784```
785
786Command-line values override their matching environment variables. For API
787keys, prefer `CODEX_SECURITY_LINEAR_API_KEY` over `--linear-api-key` because
788command-line arguments can appear in shell history and process listings.
789
708## `codex-security validate` and `codex-security patch`790## `codex-security validate` and `codex-security patch`
709 791
710Check whether a candidate finding is valid:792Check whether a candidate finding is valid:
778```860```
779 861
780When you expose the CLI as an MCP server, `info` is the only available command.862When you expose the CLI as an MCP server, `info` is the only available command.
781Scans, exports, sign-in, validation, and patching remain CLI-only.863Scans, exports, publication, sign-in, validation, and patching remain CLI-only.
782 864
783## Read scan output865## Read scan output
784 866
900The CLI uses these exit codes:982The CLI uses these exit codes:
901 983
902| Exit | Condition |984| Exit | Condition |
903| ----- | --------------------------------------------------------------------------------------------------------------------------------------------- |985| ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
904| `0` | A scan completed with complete coverage and passed its severity policy, a bulk scan completed without failures, or another command succeeded. |986| `0` | A scan completed with complete coverage and passed its severity policy, a bulk scan or publication completed without failures, or another command succeeded. |
905| `1` | A completed scan reports a finding at or above the configured severity. |987| `1` | A completed scan reports a finding at or above the configured severity. |
906| `2` | The CLI found an input, runtime, or export error, a scan has incomplete coverage, or a bulk scan has repositories with errors. |988| `2` | The CLI found an input, runtime, or export error, a scan has incomplete coverage, a bulk scan has repositories with errors, or a publication has one or more failed findings. |
907| `130` | Ctrl-C interrupted a scan. |989| `130` | Ctrl-C interrupted a scan or publication. |
908| `143` | SIGTERM terminated a scan. |990| `143` | SIGTERM terminated a scan or publication. |
909 991
910Any scan with `partial` or `unknown` coverage returns `2`, even without a992Any scan with `partial` or `unknown` coverage returns `2`, even without a
911severity policy. When you request structured output, completed scans still993severity policy. When you request structured output, completed scans and
912write the available results to stdout. The CLI prints the location of any994partial publications still write the available results to stdout. The CLI
913partial output after an interruption or runtime error.995prints the location of any partial output after an interruption or runtime
996error.
914 997
915## Local scan permissions998## Local scan permissions
916 999