Codex Security in CI ausführen
Änderungen aus Pull Requests und Merge Requests scannen, strukturierte Ergebnisse aufbewahren, SARIF hochladen und eine Schweregradrichtlinie festlegen.
Führen Sie die Codex Security CLI in CI aus, um genau die Änderungen in einem Pull Request oder Merge Request zu prüfen, Befunde und Abdeckung beizubehalten und die Prüfung optional ab einem ausgewählten Schweregrad fehlschlagen zu lassen. Beginnen Sie mit informativen Ergebnissen, prüfen Sie Scanqualität und Laufzeit und fügen Sie anschließend eine zu Ihrem Repository passende Schweregradrichtlinie hinzu.
Dieser Leitfaden enthält Beispiele für GitHub Actions und GitLab CI/CD. Dieselben Scan- und Exportbefehle funktionieren auch in anderen CI-Systemen.
Workflow vorbereiten
Speichern Sie einen OpenAI API key im Secret-Speicher Ihres CI-Anbieters als
CODEX_SECURITY_API_KEY.
Ordnen Sie dieses Secret direkt der Umgebungsvariable OPENAI_API_KEY
des Scan-Schritts zu. Beschränken Sie die Anmeldedaten auf den Scanprozess und verwenden Sie
--auth api-key, um sie ausdrücklich auszuwählen.
Der Runner benötigt:
- Node.js 22 oder höher.
- Python 3.10 oder höher.
- Das veröffentlichte Paket
@openai/codex-security, das außerhalb des Repository-Checkouts installiert ist. - Den Verlauf des Head- und Base-Branches des Pull Requests oder Merge Requests, damit Git die Merge-Basis berechnen kann.
GitHub-Actions-Workflow hinzufügen
Aktivieren Sie für private oder interne Repositorys GitHub Code Security, bevor Sie SARIF hochladen.
Erstellen Sie .github/workflows/codex-security.yml. Installieren Sie vor dem Auschecken des Pull
Requests @openai/codex-security unter
$RUNNER_TEMP/codex-security, damit die vertrauenswürdige ausführbare Datei unter
$RUNNER_TEMP/codex-security/node_modules/.bin/codex-security verfügbar ist:
name: Codex Security scan
on:
pull_request:
jobs:
codex-security:
if: github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]'
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
steps:
- name: Set up Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
with:
node-version: "26"
- name: Set up Python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7
with:
python-version: "3.14"
- name: Install Codex Security
run: |
set -euo pipefail
npm install \
--prefix "$RUNNER_TEMP/codex-security" \
--ignore-scripts \
--no-audit \
--no-fund \
@openai/codex-security
- name: Verify Codex Security
env:
CODEX_SECURITY_BIN: ${{ runner.temp }}/codex-security/node_modules/.bin/codex-security
run: |
set -euo pipefail
test -x "$CODEX_SECURITY_BIN"
"$CODEX_SECURITY_BIN" --version
- name: Check out the pull request
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
persist-credentials: false
- name: Scan the pull request
env:
OPENAI_API_KEY: ${{ secrets.CODEX_SECURITY_API_KEY }}
CODEX_SECURITY_BIN: ${{ runner.temp }}/codex-security/node_modules/.bin/codex-security
CODEX_SECURITY_STATE_DIR: ${{ runner.temp }}/codex-security-state
BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
SCAN_DIR: ${{ runner.temp }}/codex-security-results
run: |
set -euo pipefail
BASE_REVISION="$(git merge-base "$BASE_SHA" "$HEAD_SHA")"
"$CODEX_SECURITY_BIN" scan . \
--diff "$BASE_REVISION" \
--head "$HEAD_SHA" \
--auth api-key \
--output-dir "$SCAN_DIR" \
--json > "$RUNNER_TEMP/codex-security.json"
- name: Export SARIF
id: export-sarif
if: always()
env:
CODEX_SECURITY_BIN: ${{ runner.temp }}/codex-security/node_modules/.bin/codex-security
SCAN_DIR: ${{ runner.temp }}/codex-security-results
SARIF_FILE: ${{ runner.temp }}/codex-security.sarif
run: |
set -euo pipefail
if test -f "$SCAN_DIR/scan-manifest.json"; then
"$CODEX_SECURITY_BIN" export "$SCAN_DIR" \
--export-format sarif \
--source-root "$GITHUB_WORKSPACE" \
--output "$SARIF_FILE"
echo "available=true" >> "$GITHUB_OUTPUT"
fi
- name: Upload SARIF
if: always() && steps.export-sarif.outputs.available == 'true'
uses: github/codeql-action/upload-sarif@e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81 # v4
with:
sarif_file: ${{ runner.temp }}/codex-security.sarif
ref: refs/pull/${{ github.event.pull_request.number }}/head
sha: ${{ github.event.pull_request.head.sha }}
category: codex-security
- name: Preserve scan results
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: codex-security-results
path: |
${{ runner.temp }}/codex-security-results
${{ runner.temp }}/codex-security.json
if-no-files-found: warn
retention-days: 7Der Workflow checkt den Head des Pull Requests aus, berechnet dessen Merge-Basis und
scannt die committeten Änderungen zwischen diesen Revisionen. Der vollständige Verlauf stellt sicher, dass das
Ziel exakt ist. persist-credentials: false hält das Repository-Token aus
der ausgecheckten Git-Konfiguration heraus. Indem die CLI vor dem Checkout installiert und
über ihren absoluten Pfad ausgeführt wird, bleiben vom Repository kontrollierte ausführbare Dateien von
den Scan-Anmeldedaten getrennt. --auth api-key wählt den eingeschränkten API key ausdrücklich aus.
Der Scan speichert seinen Verlauf in einem beschreibbaren Zustandsverzeichnis außerhalb des
Repositorys.
--json schreibt ein vollständiges JSON-Dokument nach stdout, sodass der Workflow es
direkt speichern kann. Fortschritt, Abschlusszusammenfassungen und Fehler verbleiben auf stderr. Dies
unterscheidet sich von codex exec --json, das einen JSON-Lines-Ereignisstrom ausgibt.
Der Exportschritt liest einen abgeschlossenen, versiegelten Scan und schreibt SARIF. Die Codex-Laufzeit und die Anmeldedaten bleiben unverändert. Scan-Artefakte können anfällige Quelltextausschnitte, Nachweise und Details zur Behebung enthalten. Wählen Sie Zugriffskontrollen und ein kurzes Aufbewahrungsfenster, die für Ihr Repository angemessen sind.
GitLab-CI/CD-Pipeline hinzufügen
GitLab kann
SARIF-2.1.0-Berichte
ab GitLab Ultimate 19.2 verarbeiten. Fügen Sie eine maskierte und ausgeblendete
CI/CD-Variable CODEX_SECURITY_API_KEY hinzu, bevor Sie die Pipeline ausführen.
Fügen Sie die Stufe security und den Codex-Security-Job zur .gitlab-ci.yml im Stammverzeichnis hinzu.
Behalten Sie alle vorhandenen Stufen und Jobs in der Datei bei. Das Beispiel scannt standardmäßig
Änderungen aus Merge Requests. Setzen Sie CODEX_SECURITY_FULL_SCAN_DEFAULT_BRANCH auf "true",
um zusätzlich den vollständigen Standard-Branch zu scannen:
variables:
CODEX_SECURITY_FULL_SCAN_DEFAULT_BRANCH: "false"
stages:
- test
- security
codex-security:
stage: security
image: node:26-bookworm-slim
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_SOURCE_PROJECT_ID == $CI_PROJECT_ID'
variables:
CODEX_SECURITY_SCAN_SCOPE: "diff"
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CODEX_SECURITY_FULL_SCAN_DEFAULT_BRANCH == "true"'
variables:
CODEX_SECURITY_SCAN_SCOPE: "full"
variables:
GIT_DEPTH: "0"
CODEX_SECURITY_CLI_DIR: "/tmp/codex-security-cli"
before_script:
- |
set -eu
apt-get update -qq
apt-get install -y -qq --no-install-recommends \
ca-certificates \
git \
python3 \
ripgrep
npm install \
--prefix "$CODEX_SECURITY_CLI_DIR" \
--ignore-scripts \
--no-audit \
--no-fund \
@openai/codex-security
export CODEX_SECURITY_BIN="$CODEX_SECURITY_CLI_DIR/node_modules/.bin/codex-security"
test -x "$CODEX_SECURITY_BIN"
"$CODEX_SECURITY_BIN" --version
script:
- |
set -eu
if test -z "${CODEX_SECURITY_API_KEY:-}"; then
echo "Set the CODEX_SECURITY_API_KEY CI/CD variable." >&2
exit 2
fi
codex_security_api_key="$CODEX_SECURITY_API_KEY"
unset CODEX_SECURITY_API_KEY
case "${CODEX_SECURITY_SCAN_SCOPE:-}" in
diff)
BASE_SHA="$CI_MERGE_REQUEST_DIFF_BASE_SHA"
HEAD_SHA="$CI_COMMIT_SHA"
BASE_REVISION="$(git merge-base "$BASE_SHA" "$HEAD_SHA")"
set -- --diff "$BASE_REVISION" --head "$HEAD_SHA"
echo "Scanning committed changes from $BASE_REVISION to $HEAD_SHA."
;;
full)
set -- --mode standard
echo "Scanning the complete default branch at $CI_COMMIT_SHA."
;;
*)
echo "Unsupported Codex Security scan scope: ${CODEX_SECURITY_SCAN_SCOPE:-unset}" >&2
exit 2
;;
esac
export CODEX_SECURITY_STATE_DIR="/tmp/codex-security-state-$CI_JOB_ID"
SCAN_DIR="/tmp/codex-security-results-$CI_JOB_ID"
JSON_FILE="/tmp/codex-security-$CI_JOB_ID.json"
SARIF_FILE="/tmp/codex-security-$CI_JOB_ID.sarif"
install -d -m 700 "$CODEX_SECURITY_STATE_DIR" "$SCAN_DIR"
set +e
OPENAI_API_KEY="$codex_security_api_key" \
"$CODEX_SECURITY_BIN" scan . \
"$@" \
--auth api-key \
--output-dir "$SCAN_DIR" \
--json > "$JSON_FILE"
scan_exit="$?"
set -e
unset codex_security_api_key
install -d -m 700 codex-security-artifacts/results
cp -R "$SCAN_DIR"/. codex-security-artifacts/results/
if test -s "$JSON_FILE"; then
cp "$JSON_FILE" codex-security-artifacts/codex-security.json
fi
printf '%s\n' "$scan_exit" > codex-security-artifacts/scan-exit-code.txt
export_exit=0
if test -f "$SCAN_DIR/scan-manifest.json"; then
set +e
"$CODEX_SECURITY_BIN" export "$SCAN_DIR" \
--export-format sarif \
--source-root "$CI_PROJECT_DIR" \
--output "$SARIF_FILE"
export_exit="$?"
set -e
if test -s "$SARIF_FILE"; then
cp "$SARIF_FILE" codex-security-artifacts/codex-security.sarif
fi
fi
if test "$scan_exit" -ne 0; then
exit "$scan_exit"
fi
exit "$export_exit"
artifacts:
when: always
access: maintainer
expire_in: 7 days
paths:
- codex-security-artifacts/
reports:
sarif: codex-security-artifacts/codex-security.sarifStandardmäßig wird der Job nur für Merge Requests aus Branches desselben
Projekts ausgeführt, sodass Fork-Pipelines keine Scan-Anmeldedaten erhalten. Setzen Sie
CODEX_SECURITY_FULL_SCAN_DEFAULT_BRANCH auf Gruppen-, Projekt- oder
Pipeline-Ebene auf "true", um zusätzlich einen regulären vollständigen Scan auf dem Standard-Branch auszuführen. Vollständige
Scans dauern länger und kosten mehr als Diff-Scans.
GIT_DEPTH: "0" stellt den Verlauf bereit, der benötigt wird, um bei Merge-Request-Scans die Merge-Basis aus
CI_MERGE_REQUEST_DIFF_BASE_SHA und CI_COMMIT_SHA zu berechnen.
Der Job installiert die CLI unter /tmp, führt sie über ihren absoluten Pfad aus und stellt den
API key nur dem Scanprozess bereit. artifacts: when: always bewahrt den SARIF-
Bericht auf, wenn der Scan fehlschlägt, während artifacts:access: maintainer den Zugriff
auf detaillierte Scanergebnisse beschränkt.
Änderungen an .gitlab-ci.yml können CI/CD-Variablen offenlegen. Prüfen Sie daher Pipeline-
Änderungen, bevor Sie den Job ausführen. Wenn Sie
CODEX_SECURITY_API_KEY schützen,
stellt GitLab die Variable nur für projektinterne Merge Requests zwischen
geschützten Branches bereit und nur dann, wenn der Benutzer auf den Ziel-Branch zugreifen kann.
Schweregradrichtlinie auswählen
Beide Beispiele dienen nur der Berichterstellung, da sie --fail-on-severity weglassen. Sobald
Befunde die Prüfung beeinflussen sollen, fügen Sie dem Scanbefehl einen
Schwellenwert hinzu:
"$CODEX_SECURITY_BIN" scan . \
--diff origin/main \
--output-dir /path/outside/repository/results \
--fail-on-severity highDie unterstützten Schwellenwerte sind critical, high, medium und low. Ein
Schwellenwert umfasst Befunde dieses und höherer Schweregrade.
Der Scan-Schritt verwendet diese Exitcodes:
| Exit | Bedeutung |
|---|---|
0 |
Der Scan wurde mit vollständiger Abdeckung abgeschlossen und alle konfigurierten Richtlinien wurden erfüllt. |
1 |
Der abgeschlossene Scan enthält einen Befund auf oder über dem Schwellenwert. |
2 |
Die CLI hat einen Eingabe- oder Laufzeitfehler gefunden oder der abgeschlossene Scan weist eine unvollständige Abdeckung auf. |
130 |
Strg-C hat den Scan unterbrochen. |
143 |
SIGTERM hat den Scan beendet. |
Ein Scan mit der Abdeckung partial oder unknown gibt auch ohne Schweregrad-
richtlinie 2 zurück. Die CLI schreibt dennoch die verfügbaren Befunde und Abdeckungsdaten. Prüfen Sie die
zurückgestellten Bereiche in coverage.json, bevor Sie die Prüfung als aussagekräftig betrachten.
Mit einem vorhandenen Ergebnisverzeichnis erneut versuchen
Verwenden Sie für jeden CI-Job ein neues Runner-Verzeichnis. Bewahren Sie bei einem persistenten oder selbst gehosteten
Runner ein früheres Ergebnis mit --archive-existing auf:
"$CODEX_SECURITY_BIN" scan . \
--diff origin/main \
--output-dir /path/outside/repository/results \
--archive-existingDer Befehl archiviert die früheren Ergebnisse und beginnt mit einem leeren Scanverzeichnis.
Fehler bei einem CI-Scan beheben
- Unbekannte Git-Referenz oder unerwarteter Diff: Rufen Sie den Verlauf von Base und Head ab, berechnen Sie die Merge-Basis und übergeben Sie beide Revisionen ausdrücklich.
- Geschütztes oder nicht leeres Ausgabeverzeichnis: Wählen Sie ein privates Verzeichnis
außerhalb des umgebenden Git-Worktrees. Verwenden Sie
--archive-existing, wenn das Verzeichnis bereits Ergebnisse enthält. - Fehlende Anmeldedaten: Vergewissern Sie sich, dass
CODEX_SECURITY_API_KEYfür den vertrauenswürdigen Workflow oder die Pipeline verfügbar und direkt der UmgebungsvariableOPENAI_API_KEYdes Scanprozesses zugeordnet ist. - Fehler im Scanverlauf: Setzen Sie
CODEX_SECURITY_STATE_DIRauf ein beschreibbares Verzeichnis außerhalb des Repositorys. - Fehler bei der Python-Einrichtung: Vergewissern Sie sich, dass der Runner Python 3.10 oder höher verwendet.
- Unvollständige Abdeckung: Prüfen Sie
coverage.jsoneinschließlich zurückgestellter Bereiche und offener Fragen und führen Sie den Scan anschließend mit einem geeigneten Ziel oder einer geeigneten Umgebung erneut aus. - SARIF-Exportfehler: Vergewissern Sie sich, dass der Scan abgeschlossen wurde und das vollständige Scanverzeichnis verfügbar ist. Der Export validiert die versiegelten Artefakte, bevor er SARIF schreibt.
- SARIF-Uploadfehler: Vergewissern Sie sich bei GitHub Actions, dass Ihre Organisation
GitHub Code Security für das Repository aktiviert hat und der Workflow
actions: read,contents: readundsecurity-events: writegewährt. Vergewissern Sie sich bei GitLab CI/CD, dass das Projekt GitLab Ultimate 19.2 oder höher verwendet und der Job überartifacts:reports:sarifeine SARIF-2.1.0-Datei hochlädt.
Informationen zu allen Befehlen, Flags, Artefakten und Ausgabefeldern finden Sie in der CLI- Referenz. Informationen zu einer interaktiven, Plugin-basierten CI- Prüfung finden Sie unter Codeänderungen auf Sicherheitsprobleme prüfen.