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 exakt die Änderungen in einem Pull Request oder Merge Request zu prüfen, Befunde und Abdeckung aufzubewahren und die Prüfung optional ab einem gewählten Schweregrad fehlschlagen zu lassen. Beginnen Sie mit informativen Ergebnissen, prüfen Sie Scanqualität und Laufzeit und ergänzen Sie anschließend eine zu Ihrem Repository passende Schweregradrichtlinie.
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 Scan-Prozess und verwenden Sie
--auth api-key, um sie ausdrücklich auszuwählen.
Führen Sie den Workflow nur für vertrauenswürdige Repositories und Pull Requests aus. Scans verwenden die lokalen Berechtigungen des Runners und halten nicht für eine Genehmigung an. Scan-Prozesse können die Jobumgebung übernehmen; halten Sie daher nicht benötigte Tokens und Cloud- Anmeldedaten davon fern.
Der Runner benötigt:
- Node.js 22 (22.13.0 oder höher), 24 oder 26.
- Python 3.10 oder höher.
- Das veröffentlichte Paket
@openai/codex-security, installiert außerhalb des Repository-Checkouts. - Den Verlauf des Heads und der Basis 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 Repositories 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 zwischen diesen Revisionen committeten Änderungen. Der vollständige Verlauf hält das
Ziel exakt. persist-credentials: false hält das Repository-Token aus
der ausgecheckten Git-Konfiguration heraus. Wenn Sie die CLI vor dem Checkout installieren und
über ihren absoluten Pfad ausführen, bleiben vom Repository kontrollierte ausführbare Dateien von
den Scan-Anmeldedaten getrennt. --auth api-key wählt ausdrücklich den eingeschränkten API key aus.
Der Scan speichert seinen Verlauf in einem beschreibbaren Zustandsverzeichnis außerhalb des
Repositories.
--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-Ereignisstream ausgibt.
Der Exportschritt liest einen abgeschlossenen, versiegelten Scan und schreibt SARIF. Codex- Laufzeit und Anmeldedaten bleiben dabei unverändert. Scan-Artefakte können anfällige Quelltextausschnitte, Nachweise und Behebungsdetails enthalten. Wählen Sie Zugriffskontrollen und ein kurzes Aufbewahrungsfenster, die für Ihr Repository angemessen sind.
GitLab-CI/CD-Pipeline hinzufügen
Verwenden Sie für einen Produktionsworkflow mit Scans des geschützten Standard-Branches, optional aktivierten geplanten Tiefenscans, einer separaten SARIF-Richtlinienprüfung und optionalen verifizierten Entwurfs-Merge-Requests den Leitfaden Codex Security in GitLab CI/CD ausführen.
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.
Das folgende Minimalbeispiel fügt der Stammdatei einen reinen Scan-Job namens security
hinzu: .gitlab-ci.yml. Behalten Sie alle bereits in der Datei vorhandenen Stages und Jobs bei. Standardmäßig werden
Änderungen aus Merge Requests gescannt. 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@0.1.20
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 von Branches desselben
Projekts ausgeführt, sodass Fork-Pipelines die Scan-Anmeldedaten nicht 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 zum Berechnen der Merge-Basis aus
CI_MERGE_REQUEST_DIFF_BASE_SHA und CI_COMMIT_SHA für Merge-Request-Scans erforderlich ist.
Der Job installiert die CLI unter /tmp, führt sie über den absoluten Pfad aus und stellt den
API key nur dem Scan-Prozess bereit. artifacts: when: always bewahrt den SARIF-
Bericht auf, wenn der Scan fehlschlägt, während artifacts:access: maintainer den Zugriff
auf detaillierte Scan-Ergebnisse einschrä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 es nur für Merge Requests desselben Projekts zwischen
geschützten Branches bereit und nur dann, wenn der Benutzer auf den Ziel-Branch zugreifen kann.
Der spezielle GitLab-Leitfaden erweitert diesen Minimaljob zu dem am Anfang dieses Abschnitts verlinkten Produktionsworkflow.
Schweregradrichtlinie auswählen
Beide Beispiele dienen ausschließlich der Berichterstellung, da sie --fail-on-severity auslassen. Sobald
Befunde die Prüfung beeinflussen sollen, ergänzen Sie den Scan-
Befehl um einen Schwellenwert:
"$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 des aktuellen Scans mit diesem oder einem höheren Schweregrad.
Frühere offene Befunde in der Repository-Zusammenfassung wirken sich nicht auf die Richtlinie aus.
Der Scan-Schritt verwendet folgende Exitcodes:
| Exit | Bedeutung |
|---|---|
0 |
Der Scan wurde mit vollständiger Abdeckung abgeschlossen und jede konfigurierte Richtlinie eingehalten. |
1 |
Der abgeschlossene Scan enthält einen Befund ab dem festgelegten Schwellenwert. |
2 |
Die CLI hat einen Eingabe- oder Laufzeitfehler festgestellt oder der abgeschlossene Scan weist eine unvollständige Abdeckung auf. |
130 |
Der Scan wurde durch Ctrl-C unterbrochen. |
143 |
Der Scan wurde durch SIGTERM beendet. |
Ein Scan mit Abdeckung vom Typ partial oder unknown gibt 2 zurück, auch ohne eine Schweregrad-
richtlinie. Die CLI schreibt weiterhin die verfügbaren Befunde und Abdeckungsdaten. Prüfen Sie die
zurückgestellten Bereiche in coverage.json, bevor Sie die Prüfung als abschließend 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 Scan-Verzeichnis.
Fehler bei einem CI-Scan beheben
- Unbekannte Git-Referenz oder unerwarteter Diff: Rufen Sie den Verlauf von Basis 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 vertrauenswürdige Pipeline verfügbar und direkt der UmgebungsvariableOPENAI_API_KEYdes Scan-Prozesses zugeordnet ist. - Fehler im Scan-Verlauf: Setzen Sie
CODEX_SECURITY_STATE_DIRauf ein beschreibbares Verzeichnis außerhalb des Repositories. - 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 dann mit einem geeigneten Ziel oder einer geeigneten Umgebung erneut aus. - Fehler beim SARIF-Export: Vergewissern Sie sich, dass der Scan abgeschlossen wurde und das vollständige Scan- Verzeichnis verfügbar ist. Der Export validiert die versiegelten Artefakte, bevor er SARIF schreibt.
- Fehler beim SARIF-Upload: 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 pluginbasierten CI- Prüfung finden Sie unter Codeänderungen auf Sicherheitsprobleme prüfen.