Jalankan Codex Security di CI
Pindai perubahan pull request dan merge request, pertahankan hasil terstruktur, unggah SARIF, dan tetapkan kebijakan tingkat keparahan.
Jalankan Codex Security CLI di CI untuk meninjau perubahan persis dalam pull request atau merge request, mempertahankan temuan dan cakupan, serta secara opsional menggagalkan pemeriksaan pada tingkat keparahan yang dipilih. Mulailah dengan hasil yang bersifat saran, tinjau kualitas dan waktu proses pemindaian, lalu tambahkan kebijakan tingkat keparahan yang sesuai dengan repositori Anda.
Panduan ini menyertakan contoh untuk GitHub Actions dan GitLab CI/CD. Perintah pemindaian dan ekspor yang sama dapat digunakan di sistem CI lainnya.
Siapkan alur kerja
Simpan API key OpenAI di penyimpanan rahasia penyedia CI Anda sebagai
CODEX_SECURITY_API_KEY.
Petakan rahasia ini secara langsung ke variabel lingkungan OPENAI_API_KEY milik langkah
pemindaian. Batasi kredensial hanya untuk proses pemindaian dan gunakan
--auth api-key untuk memilihnya secara eksplisit.
Runner memerlukan:
- Node.js 22 atau yang lebih baru.
- Python 3.10 atau yang lebih baru.
- Paket
@openai/codex-securityyang telah dipublikasikan, diinstal di luar checkout repositori. - Riwayat head dan base pull request atau merge request agar Git dapat menghitung merge base.
Tambahkan alur kerja GitHub Actions
Untuk repositori privat atau internal, aktifkan GitHub Code Security sebelum Anda mengunggah SARIF.
Buat .github/workflows/codex-security.yml. Sebelum melakukan checkout pull
request, instal @openai/codex-security di bawah
$RUNNER_TEMP/codex-security agar berkas yang dapat dieksekusi dan tepercaya tersedia di
$RUNNER_TEMP/codex-security/node_modules/.bin/codex-security:
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: 7Alur kerja melakukan checkout head pull request, menghitung merge base-nya, dan
memindai perubahan yang telah di-commit di antara revisi tersebut. Riwayat lengkap menjaga
target tetap akurat. persist-credentials: false mencegah token repositori masuk ke
konfigurasi Git yang telah di-checkout. Menginstal CLI sebelum checkout dan
menjalankannya melalui path absolut menjauhkan berkas yang dapat dieksekusi dan dikendalikan repositori dari
kredensial pemindaian. --auth api-key secara eksplisit memilih API key yang dibatasi cakupannya.
Pemindaian menyimpan riwayatnya dalam direktori status yang dapat ditulisi di luar
repositori.
--json menulis satu dokumen JSON lengkap ke stdout, sehingga alur kerja dapat menyimpannya
secara langsung. Progres, ringkasan penyelesaian, dan kesalahan tetap berada di stderr. Ini
berbeda dari codex exec --json, yang menghasilkan aliran peristiwa JSON Lines.
Langkah ekspor membaca pemindaian yang telah selesai dan disegel, lalu menulis SARIF. Langkah ini tidak mengubah runtime dan kredensial Codex. Artefak pemindaian dapat memuat cuplikan kode sumber yang rentan, bukti, dan detail remediasi. Pilih kontrol akses dan periode retensi singkat yang sesuai untuk repositori Anda.
Tambahkan pipeline GitLab CI/CD
GitLab dapat menyerap
laporan SARIF 2.1.0
di GitLab Ultimate 19.2 atau yang lebih baru. Tambahkan variabel CI/CD
CODEX_SECURITY_API_KEY yang disamarkan dan disembunyikan sebelum Anda menjalankan pipeline.
Tambahkan tahap security dan job Codex Security ke .gitlab-ci.yml tingkat root.
Pertahankan semua tahap dan job yang sudah ada dalam berkas tersebut. Secara default, contoh ini memindai perubahan
merge request. Tetapkan CODEX_SECURITY_FULL_SCAN_DEFAULT_BRANCH ke "true"
untuk turut memindai seluruh branch default:
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.sarifSecara default, job hanya berjalan untuk merge request dari branch dalam proyek yang sama,
sehingga pipeline fork tidak menerima kredensial pemindaian. Tetapkan
CODEX_SECURITY_FULL_SCAN_DEFAULT_BRANCH ke "true" pada tingkat grup, proyek, atau
pipeline untuk turut menjalankan pemindaian penuh standar pada branch default. Pemindaian penuh
memerlukan waktu lebih lama dan biaya lebih besar daripada pemindaian diff.
GIT_DEPTH: "0" menyediakan riwayat yang diperlukan untuk menghitung merge base dari
CI_MERGE_REQUEST_DIFF_BASE_SHA dan CI_COMMIT_SHA untuk pemindaian merge request.
Job menginstal CLI di bawah /tmp, menjalankannya melalui path absolut, dan hanya mengekspos
API key kepada proses pemindaian. artifacts: when: always mempertahankan laporan SARIF
ketika pemindaian gagal, sedangkan artifacts:access: maintainer membatasi akses
ke hasil pemindaian terperinci.
Perubahan pada .gitlab-ci.yml dapat mengekspos variabel CI/CD, jadi tinjau perubahan pipeline
sebelum menjalankan job. Jika Anda
melindungi CODEX_SECURITY_API_KEY,
GitLab menyediakannya hanya untuk merge request dalam proyek yang sama di antara
branch yang dilindungi dan hanya ketika pengguna dapat mengakses branch target.
Pilih kebijakan tingkat keparahan
Kedua contoh hanya membuat laporan karena tidak menyertakan --fail-on-severity. Setelah Anda
siap menjadikan temuan memengaruhi pemeriksaan, tambahkan ambang batas ke perintah
pemindaian:
"$CODEX_SECURITY_BIN" scan . \
--diff origin/main \
--output-dir /path/outside/repository/results \
--fail-on-severity highAmbang batas yang didukung adalah critical, high, medium, dan low. Sebuah
ambang batas mencakup temuan pada tingkat keparahan tersebut dan yang lebih tinggi.
Langkah pemindaian menggunakan kode keluar berikut:
| Keluar | Arti |
|---|---|
0 |
Pemindaian selesai dengan cakupan lengkap dan semua kebijakan yang dikonfigurasi terpenuhi. |
1 |
Pemindaian yang selesai memuat temuan pada atau di atas ambang batas. |
2 |
CLI menemukan kesalahan input atau runtime, atau pemindaian yang selesai memiliki cakupan tidak lengkap. |
130 |
Ctrl-C menghentikan pemindaian. |
143 |
SIGTERM mengakhiri pemindaian. |
Pemindaian dengan cakupan partial atau unknown mengembalikan 2, bahkan tanpa kebijakan
tingkat keparahan. CLI tetap menulis temuan dan cakupan yang tersedia. Tinjau
area yang ditangguhkan dalam coverage.json sebelum menganggap pemeriksaan tersebut konklusif.
Coba lagi dengan direktori hasil yang sudah ada
Gunakan direktori runner baru untuk setiap job CI. Untuk runner persisten atau yang di-host sendiri,
pertahankan hasil sebelumnya dengan --archive-existing:
"$CODEX_SECURITY_BIN" scan . \
--diff origin/main \
--output-dir /path/outside/repository/results \
--archive-existingPerintah tersebut mengarsipkan hasil sebelumnya dan memulai dengan direktori pemindaian kosong.
Atasi masalah pemindaian CI
- Ref Git tidak dikenal atau diff tidak sesuai harapan: Ambil riwayat base dan head, hitung merge base, lalu teruskan kedua revisi secara eksplisit.
- Direktori output dilindungi atau tidak kosong: Pilih direktori privat
di luar worktree Git yang menaunginya. Gunakan
--archive-existingketika direktori sudah memuat hasil. - Kredensial tidak ada: Pastikan
CODEX_SECURITY_API_KEYtersedia untuk alur kerja atau pipeline tepercaya dan dipetakan secara langsung ke variabel lingkunganOPENAI_API_KEYmilik proses pemindaian. - Kesalahan riwayat pemindaian: Tetapkan
CODEX_SECURITY_STATE_DIRke direktori yang dapat ditulisi di luar repositori. - Kesalahan penyiapan Python: Pastikan runner menggunakan Python 3.10 atau yang lebih baru.
- Cakupan tidak lengkap: Tinjau
coverage.json, termasuk permukaan yang ditangguhkan dan pertanyaan terbuka, lalu jalankan ulang dengan target atau lingkungan yang sesuai. - Kesalahan ekspor SARIF: Pastikan pemindaian selesai dan seluruh direktori pemindaian tersedia. Ekspor memvalidasi artefak yang disegel sebelum menulis SARIF.
- Kesalahan unggah SARIF: Untuk GitHub Actions, pastikan organisasi Anda
mengaktifkan GitHub Code Security untuk repositori dan alur kerja memberikan
actions: read,contents: read, dansecurity-events: write. Untuk GitLab CI/CD, pastikan proyek menggunakan GitLab Ultimate 19.2 atau yang lebih baru dan job mengunggah berkas SARIF 2.1.0 melaluiartifacts:reports:sarif.
Untuk setiap perintah, flag, artefak, dan field output, lihat referensi CLI. Untuk peninjauan CI interaktif berbasis plugin, lihat Tinjau perubahan kode untuk keamanan.