codex-manual.md +198 −40
7202 7202
7203Source: [Run Codex Security in CI](https://learn.chatgpt.com/docs/security/cli/ci.md)7203Source: [Run Codex Security in CI](https://learn.chatgpt.com/docs/security/cli/ci.md)
7204 7204
72057205Run the Codex Security CLI in CI to review the exact changes in a pull request,Run the Codex Security CLI in CI to review the exact changes in a pull request
72067206keep findings and coverage, and optionally fail the check at a chosenor merge request, keep findings and coverage, and optionally fail the check at
72077207severity. Start with advisory results, review scan quality and runtime, thena chosen severity. Start with advisory results, review scan quality and
72087208add a severity policy that fits your repository.runtime, then add a severity policy that fits your repository.
7209 7209
7210Install the public `@openai/codex-security` package. Running scans still7210Install the public `@openai/codex-security` package. Running scans still
7211requires Codex Security access.7211requires Codex Security access.
7212 7212
72137213This guide uses GitHub Actions. The same scan and export commands work in otherThis guide includes examples for GitHub Actions and GitLab CI/CD. The same scan
72147214CI systems.and export commands work in other CI systems.
7215 7215
7216#### Prepare the workflow7216#### Prepare the workflow
7217 7217
72187218Store an OpenAI API key as a repository or organization secret namedStore an OpenAI API key in your CI provider's secret store as
7219`CODEX_SECURITY_API_KEY`.7219`CODEX_SECURITY_API_KEY`.
7220 7220
7221Map this secret directly to the scan step's `OPENAI_API_KEY` environment7221Map this secret directly to the scan step's `OPENAI_API_KEY` environment
7228- Python 3.10 or later.7228- Python 3.10 or later.
7229- The published `@openai/codex-security` package, installed outside the7229- The published `@openai/codex-security` package, installed outside the
7230 repository checkout.7230 repository checkout.
72317231- The pull-request head and base history so Git can calculate the merge base.- The pull-request or merge-request head and base history so Git can calculate
72327232- [GitHub Code Security](https://docs.github.com/en/code-security/code-scanning/integrating-with-code-scanning/uploading-a-sarif-file-to-github) the merge base.
7233 enabled for private or internal repositories when you upload SARIF.
7234 7233
7235#### Add the GitHub Actions workflow7234#### Add the GitHub Actions workflow
7236 7235
7236For private or internal repositories, enable
7237[GitHub Code Security](https://docs.github.com/en/code-security/code-scanning/integrating-with-code-scanning/uploading-a-sarif-file-to-github)
7238before you upload SARIF.
7239
7237Create `.github/workflows/codex-security.yml`. Before checking out the pull7240Create `.github/workflows/codex-security.yml`. Before checking out the pull
72387241request, install `@openai/codex-security@0.1.3` underrequest, install `@openai/codex-security` under
7239`$RUNNER_TEMP/codex-security` so the trusted executable is available at7242`$RUNNER_TEMP/codex-security` so the trusted executable is available at
7240`$RUNNER_TEMP/codex-security/node_modules/.bin/codex-security`:7243`$RUNNER_TEMP/codex-security/node_modules/.bin/codex-security`:
7241 7244
7272 --ignore-scripts \7275 --ignore-scripts \
7273 --no-audit \7276 --no-audit \
7274 --no-fund \7277 --no-fund \
72757278 @openai/codex-security@0.1.3 @openai/codex-security
7276 7279
7277 - name: Verify Codex Security7280 - name: Verify Codex Security
7278 env:7281 env:
7363source snippets, evidence, and remediation details. Choose access controls and a7366source snippets, evidence, and remediation details. Choose access controls and a
7364short retention window appropriate for your repository.7367short retention window appropriate for your repository.
7365 7368
7369#### Add the GitLab CI/CD pipeline
7370
7371GitLab can ingest
7372[SARIF 2.1.0 reports](https://docs.gitlab.com/ci/yaml/artifacts_reports/#artifactsreportssarif)
7373on GitLab Ultimate 19.2 or later. Add a masked and hidden
7374`CODEX_SECURITY_API_KEY` CI/CD variable before you run the pipeline.
7375
7376Add the `security` stage and Codex Security job to the root `.gitlab-ci.yml`.
7377Keep any existing stages and jobs in the file. The example scans merge-request
7378changes by default. Set `CODEX_SECURITY_FULL_SCAN_DEFAULT_BRANCH` to `"true"`
7379to also scan the complete default branch:
7380
7381```yaml
7382variables:
7383 CODEX_SECURITY_FULL_SCAN_DEFAULT_BRANCH: "false"
7384
7385stages:
7386 - test
7387 - security
7388
7389codex-security:
7390 stage: security
7391 image: node:26-bookworm-slim
7392 rules:
7393 - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_SOURCE_PROJECT_ID == $CI_PROJECT_ID'
7394 variables:
7395 CODEX_SECURITY_SCAN_SCOPE: "diff"
7396 - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CODEX_SECURITY_FULL_SCAN_DEFAULT_BRANCH == "true"'
7397 variables:
7398 CODEX_SECURITY_SCAN_SCOPE: "full"
7399 variables:
7400 GIT_DEPTH: "0"
7401 CODEX_SECURITY_CLI_DIR: "/tmp/codex-security-cli"
7402 before_script:
7403 - |
7404 set -eu
7405 apt-get update -qq
7406 apt-get install -y -qq --no-install-recommends \
7407 ca-certificates \
7408 git \
7409 python3 \
7410 ripgrep
7411 npm install \
7412 --prefix "$CODEX_SECURITY_CLI_DIR" \
7413 --ignore-scripts \
7414 --no-audit \
7415 --no-fund \
7416 @openai/codex-security
7417 export CODEX_SECURITY_BIN="$CODEX_SECURITY_CLI_DIR/node_modules/.bin/codex-security"
7418 test -x "$CODEX_SECURITY_BIN"
7419 "$CODEX_SECURITY_BIN" --version
7420 script:
7421 - |
7422 set -eu
7423 if test -z "${CODEX_SECURITY_API_KEY:-}"; then
7424 echo "Set the CODEX_SECURITY_API_KEY CI/CD variable." >&2
7425 exit 2
7426 fi
7427
7428 codex_security_api_key="$CODEX_SECURITY_API_KEY"
7429 unset CODEX_SECURITY_API_KEY
7430
7431 case "${CODEX_SECURITY_SCAN_SCOPE:-}" in
7432 diff)
7433 BASE_SHA="$CI_MERGE_REQUEST_DIFF_BASE_SHA"
7434 HEAD_SHA="$CI_COMMIT_SHA"
7435 BASE_REVISION="$(git merge-base "$BASE_SHA" "$HEAD_SHA")"
7436 set -- --diff "$BASE_REVISION" --head "$HEAD_SHA"
7437 echo "Scanning committed changes from $BASE_REVISION to $HEAD_SHA."
7438 ;;
7439 full)
7440 set -- --mode standard
7441 echo "Scanning the complete default branch at $CI_COMMIT_SHA."
7442 ;;
7443 *)
7444 echo "Unsupported Codex Security scan scope: ${CODEX_SECURITY_SCAN_SCOPE:-unset}" >&2
7445 exit 2
7446 ;;
7447 esac
7448
7449 export CODEX_SECURITY_STATE_DIR="/tmp/codex-security-state-$CI_JOB_ID"
7450 SCAN_DIR="/tmp/codex-security-results-$CI_JOB_ID"
7451 JSON_FILE="/tmp/codex-security-$CI_JOB_ID.json"
7452 SARIF_FILE="/tmp/codex-security-$CI_JOB_ID.sarif"
7453
7454 install -d -m 700 "$CODEX_SECURITY_STATE_DIR" "$SCAN_DIR"
7455
7456 set +e
7457 OPENAI_API_KEY="$codex_security_api_key" \
7458 "$CODEX_SECURITY_BIN" scan . \
7459 "$@" \
7460 --auth api-key \
7461 --output-dir "$SCAN_DIR" \
7462 --json > "$JSON_FILE"
7463 scan_exit="$?"
7464 set -e
7465 unset codex_security_api_key
7466
7467 install -d -m 700 codex-security-artifacts/results
7468 cp -R "$SCAN_DIR"/. codex-security-artifacts/results/
7469 if test -s "$JSON_FILE"; then
7470 cp "$JSON_FILE" codex-security-artifacts/codex-security.json
7471 fi
7472 printf '%s\n' "$scan_exit" > codex-security-artifacts/scan-exit-code.txt
7473
7474 export_exit=0
7475 if test -f "$SCAN_DIR/scan-manifest.json"; then
7476 set +e
7477 "$CODEX_SECURITY_BIN" export "$SCAN_DIR" \
7478 --export-format sarif \
7479 --source-root "$CI_PROJECT_DIR" \
7480 --output "$SARIF_FILE"
7481 export_exit="$?"
7482 set -e
7483 if test -s "$SARIF_FILE"; then
7484 cp "$SARIF_FILE" codex-security-artifacts/codex-security.sarif
7485 fi
7486 fi
7487
7488 if test "$scan_exit" -ne 0; then
7489 exit "$scan_exit"
7490 fi
7491 exit "$export_exit"
7492 artifacts:
7493 when: always
7494 access: maintainer
7495 expire_in: 7 days
7496 paths:
7497 - codex-security-artifacts/
7498 reports:
7499 sarif: codex-security-artifacts/codex-security.sarif
7500```
7501
7502By default, the job runs only for merge requests from branches in the same
7503project, so fork pipelines don't receive the scan credential. Set
7504`CODEX_SECURITY_FULL_SCAN_DEFAULT_BRANCH` to `"true"` at the group, project, or
7505pipeline level to also run a standard full scan on the default branch. Full
7506scans take longer and cost more than diff scans.
7507
7508`GIT_DEPTH: "0"` provides the history needed to calculate the merge base from
7509`CI_MERGE_REQUEST_DIFF_BASE_SHA` and `CI_COMMIT_SHA` for merge-request scans.
7510
7511The job installs the CLI under `/tmp`, runs it by absolute path, and exposes the
7512API key only to the scan process. `artifacts: when: always` preserves the SARIF
7513report when the scan fails, while `artifacts:access: maintainer` limits access
7514to detailed scan results.
7515
7516Changes to `.gitlab-ci.yml` can expose CI/CD variables, so review pipeline
7517changes before running the job. If you
7518[protect `CODEX_SECURITY_API_KEY`](https://docs.gitlab.com/ci/pipelines/merge_request_pipelines/#control-access-to-protected-variables-and-runners),
7519GitLab makes it available only for same-project merge requests between
7520protected branches and only when the user can access the target branch.
7521
7366#### Choose a severity policy7522#### Choose a severity policy
7367 7523
73687524The above workflow is report-only because it omits `--fail-on-severity`.Both examples are report-only because they omit `--fail-on-severity`. Once you
73697525Once you are ready to make findings affect the check, add a threshold to theare ready to make findings affect the check, add a threshold to the scan
73707526scan command:command:
7371 7527
7372```bash7528```bash
7373"$CODEX_SECURITY_BIN" scan . \7529"$CODEX_SECURITY_BIN" scan . \
7414- **Protected or non-empty output directory:** Choose a private directory7570- **Protected or non-empty output directory:** Choose a private directory
7415 outside the enclosing Git worktree. Use `--archive-existing` when the7571 outside the enclosing Git worktree. Use `--archive-existing` when the
7416 directory already contains results.7572 directory already contains results.
74177573- **Missing credentials:** Confirm the `CODEX_SECURITY_API_KEY` repository- **Missing credentials:** Confirm that `CODEX_SECURITY_API_KEY` is available to
74187574 secret is available to the trusted workflow and mapped directly to the scan the trusted workflow or pipeline and mapped directly to the scan process's
74197575 step's `OPENAI_API_KEY` environment variable. `OPENAI_API_KEY` environment variable.
7420- **Scan history error:** Set `CODEX_SECURITY_STATE_DIR` to a writable7576- **Scan history error:** Set `CODEX_SECURITY_STATE_DIR` to a writable
7421 directory outside the repository.7577 directory outside the repository.
7422- **Python setup error:** Confirm that the runner uses Python 3.10 or later.7578- **Python setup error:** Confirm that the runner uses Python 3.10 or later.
7425- **SARIF export error:** Confirm that the scan completed and the full scan7581- **SARIF export error:** Confirm that the scan completed and the full scan
7426 directory is available. Export validates the sealed artifacts before writing7582 directory is available. Export validates the sealed artifacts before writing
7427 SARIF.7583 SARIF.
74287584- **SARIF upload error:** For a private or internal repository, confirm that- **SARIF upload error:** For GitHub Actions, confirm that your organization
74297585 your organization turned on GitHub Code Security for the repository and the turned on GitHub Code Security for the repository and the workflow grants
74307586 workflow grants `actions: read`, `contents: read`, and `actions: read`, `contents: read`, and `security-events: write`. For GitLab
74317587 `security-events: write`. CI/CD, confirm that the project uses GitLab Ultimate 19.2 or later and that
7588 the job uploads a SARIF 2.1.0 file through `artifacts:reports:sarif`.
7432 7589
7433For every command, flag, artifact, and output field, see the [CLI7590For every command, flag, artifact, and output field, see the [CLI
7434reference](https://learn.chatgpt.com/docs/security/cli/reference). For an interactive plugin-based CI7591reference](https://learn.chatgpt.com/docs/security/cli/reference). For an interactive plugin-based CI
7438 7595
7439Source: [Security Review](https://learn.chatgpt.com/docs/security/security-review.md)7596Source: [Security Review](https://learn.chatgpt.com/docs/security/security-review.md)
7440 7597
74417598Security Review is available in research preview.Codex Security Review is available in research preview.
7442It is available to ChatGPT Enterprise, Business, Edu, and Pro customers; it is7599It is available to ChatGPT Enterprise, Business, Edu, and Pro customers; it is
74437600not available on Plus. During the introductory period, Security Review does notnot available on Plus. During the introductory period, Codex Security Review does
74447601consume ChatGPT credits. Usage limits may apply.not consume ChatGPT credits. Usage limits may apply.
7445 7602
74467603Security Review is an additional review for customers that want toCodex Security Review is an additional review for customers that want to
7447pay particular attention to security issues in pull requests.7604pay particular attention to security issues in pull requests.
7448 7605
74497606Security Review goes deeper than [CodeCodex Security Review goes deeper than [Code
7450Review](https://learn.chatgpt.com/docs/third-party/github) on security-specific risks by analyzing the7607Review](https://learn.chatgpt.com/docs/third-party/github) on security-specific risks by analyzing the
7451pull request diff, supporting repository context, and configured threat models7608pull request diff, supporting repository context, and configured threat models
7452or security guidance. Code Review can also identify security-related issues as7609or security guidance. Code Review can also identify security-related issues as
7454 7611
7455#### Before you start7612#### Before you start
7456 7613
74577614To configure automatic Security Review, you need:To configure automatic Codex Security Review, you need:
7458 7615
74597616- Security Review research preview access for your workspace- Codex Security Review research preview access for your workspace
7460- [Codex cloud](https://learn.chatgpt.com/docs/cloud) set up with a connected GitHub repository7617- [Codex cloud](https://learn.chatgpt.com/docs/cloud) set up with a connected GitHub repository
7461- GitHub push or admin permission for the repository settings7618- GitHub push or admin permission for the repository settings
7462 7619
7463An existing Codex Security scan is optional.7620An existing Codex Security scan is optional.
7464 7621
74657622#### Configure Security Review#### Configure Codex Security Review
7466 7623
74671. Go to [Codex settings](https://chatgpt.com/codex/settings/code-review).76241. Go to [Codex settings](https://chatgpt.com/codex/settings/code-review).
746876252. Under **Repository preferences**, choose which pull requests get Security2. Under **Repository preferences**, choose which pull requests get Codex
74697626 Review: Security Review:
7470 - **Follow personal** lets each contributor opt in with their personal7627 - **Follow personal** lets each contributor opt in with their personal
74717628 Security Review settings. Codex Security Review settings.
7472 - **Review all PRs** applies to every pull request in the repository.7629 - **Review all PRs** applies to every pull request in the repository.
7473 - **Review team PRs**, when available, applies to pull requests opened by7630 - **Review team PRs**, when available, applies to pull requests opened by
7474 members of your ChatGPT workspace, not members of a GitHub team.7631 members of your ChatGPT workspace, not members of a GitHub team.
747576323. Choose when Security Review runs:3. Choose when Codex Security Review runs:
7476 - **On PR open** runs independently when a pull request is opened.7633 - **On PR open** runs independently when a pull request is opened.
7477 - **Every push** runs independently after new commits are pushed.7634 - **Every push** runs independently after new commits are pushed.
74787635 - **Whenever code review runs** requires Code Review and runs Security Review - **Whenever code review runs** requires Code Review and runs Codex Security
74797636 alongside it. Review alongside it.
7480 7637
7481#### Add threat-model context7638#### Add threat-model context
7482 7639
7489 7646
7490#### Set reporting thresholds7647#### Set reporting thresholds
7491 7648
74927649By default, automatic Security Reviews report **High** and **Critical**By default, automatic Codex Security Reviews report **High** and **Critical**
7493findings, while manually requested reviews report **Medium**, **High**, and7650findings, while manually requested reviews report **Medium**, **High**, and
7494**Critical** findings. You can change the minimum severity independently for7651**Critical** findings. You can change the minimum severity independently for
7495automatic and manual reviews, and add path-based overrides.7652automatic and manual reviews, and add path-based overrides.
7499including on public repositories or pull requests from contributors outside7656including on public repositories or pull requests from contributors outside
7500your workspace. Choose reporting thresholds carefully for repositories where7657your workspace. Choose reporting thresholds carefully for repositories where
7501pull request comments may be broadly visible. The reporting threshold controls7658pull request comments may be broadly visible. The reporting threshold controls
75027659what Codex posts to GitHub; the full Security Review report remains in Codex.what Codex posts to GitHub; the full Codex Security Review report remains in
7660Codex.
7503 7661
75047662#### Request a Security Review#### Request a Codex Security Review
7505 7663
75067664To request a Security Review manually, add this comment to a pull request:To request a Codex Security Review manually, add this comment to a pull request:
7507 7665
7508`@codex security review`7666`@codex security review`
7509 7667