在 GitLab CI/CD 中執行 Codex Security
在 GitLab CI/CD 中執行 Codex Security,以掃描已提交的更改和受保護 分支、將發現發布到 GitLab Security,並可選擇在草稿合並請求中提出經過驗證的 修復。
該工作流程將掃描憑據與儲存庫寫入權限分離。 生成的更改在合並前始終需要人工審查。
先從僅掃描報告開始。只有在檢查專案的 執行器、發現和憑據邊界後,才啟用修復。
開始之前
你需要:
- 一個配有可信執行器的 GitLab 專案,該執行器需支援 Codex 沙箱的 使用者名稱空間。
- GitLab 專案的 Maintainer 或 Owner 角色,以便設定 專案 CI/CD 變數和受保護 資源。
- 一個擁有 Codex Security 存取權限的 OpenAI API key。使用 Platform API key 的組織可以申請 Cyber 的 Trusted Access。 使用 ChatGPT 身份驗證的個人可以使用個人 Trusted Access 流程。某些帳戶或儲存庫需要此 權限才能執行完整儲存庫掃描。
- GitLab Ultimate 19.2 或更高版本,用於攝取 SARIF 2.1.0 。
- 完整的 Git 歷史記錄,以便合並請求作業計算合並基點。
流水線映象會安裝 Node.js 26、Python 3、Git、rg 和固定版本的
Codex Security CLI。自動修復還需要一個現有的
迴歸測試,以及一個無需受保護憑據即可執行儲存庫所控制命令的執行器。
從僅掃描流水線開始
建立一個名為
CODEX_SECURITY_API_KEY 的已掩碼、隱藏且受保護的 GitLab CI/CD 變數。使用具有 Codex Security
存取權限的 OpenAI Platform API key,並將其環境作用域設為 codex-security/openai。請參閱
具有環境作用域的 CI/CD 變數。
先將這個最小流水線新增到測試專案。它會掃描符合條件的受保護合並請求中 已提交的更改,從成功的報告 作業發布 SARIF,並在單獨的門控中恢復掃描器結果:
stages:
- security_scan
- security_gate
.codex-security-merge-request:
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_SOURCE_PROJECT_ID == $CI_PROJECT_ID && $CI_MERGE_REQUEST_SOURCE_BRANCH_PROTECTED == "true" && $CI_MERGE_REQUEST_TARGET_BRANCH_PROTECTED == "true"'
codex-security:
extends: .codex-security-merge-request
stage: security_scan
image: node:26-bookworm-slim
environment:
name: codex-security/openai
action: access
variables:
GIT_DEPTH: "0"
before_script:
- npm install --prefix /tmp/codex-security-cli --ignore-scripts --no-audit --no-fund @openai/codex-security@0.1.20
script:
- |
set -eu
test -n "${CODEX_SECURITY_API_KEY:-}"
CODEX_SECURITY_BIN="/tmp/codex-security-cli/node_modules/.bin/codex-security"
RESULTS_DIR="/tmp/codex-security-results-$CI_JOB_ID"
ARTIFACT_DIR="codex-security-artifacts"
BASE_REVISION="$(git merge-base \
"$CI_MERGE_REQUEST_DIFF_BASE_SHA" "$CI_COMMIT_SHA")"
install -d -m 700 "$RESULTS_DIR" "$ARTIFACT_DIR/results"
codex_security_api_key="$CODEX_SECURITY_API_KEY"
unset CODEX_SECURITY_API_KEY
set +e
OPENAI_API_KEY="$codex_security_api_key" \
"$CODEX_SECURITY_BIN" scan . \
--diff "$BASE_REVISION" \
--head "$CI_COMMIT_SHA" \
--auth api-key \
--output-dir "$RESULTS_DIR" \
--json
scan_exit="$?"
set -e
unset codex_security_api_key
case "$scan_exit" in
0|1|2) ;;
*) exit "$scan_exit" ;;
esac
"$CODEX_SECURITY_BIN" export "$RESULTS_DIR" \
--export-format sarif \
--source-root "$CI_PROJECT_DIR" \
--output "$ARTIFACT_DIR/results.sarif"
test -s "$ARTIFACT_DIR/results.sarif"
cp -R "$RESULTS_DIR"/. "$ARTIFACT_DIR/results/"
printf '%s\n' "$scan_exit" > "$ARTIFACT_DIR/scan-exit-code.txt"
exit 0
artifacts:
when: always
access: maintainer
expire_in: 7 days
paths:
- codex-security-artifacts/
reports:
sarif: codex-security-artifacts/results.sarif
codex-security-gate:
extends: .codex-security-merge-request
stage: security_gate
image: alpine:3.20
needs:
- job: codex-security
artifacts: true
script:
- exit "$(cat codex-security-artifacts/scan-exit-code.txt)"執行包含金鑰的作業前,請審查對 .gitlab-ci.yml 的每一項更改。
這個最小範例有意省略了完整掃描和修復。
採用生產流水線
- 下載完整的 GitLab 流水線,
並將其儲存為儲存庫根目錄中的
.gitlab-ci.yml。如果儲存庫 已有流水線,請將範例中的階段、隱藏模板和 作業合並到現有檔案中。 - 保留現有的建置、測試和部署階段。如果專案使用
workflow: rules,請確認它允許你要掃描的流水線事件。
該範例添加了 security_scan、security_remediation、security_publish
和 security_gate 階段。僅掃描報告只需要
CODEX_SECURITY_API_KEY。
預設情況下,掃描作業僅針對受保護分支之間同一專案內的合並請求執行。
設定 CODEX_SECURITY_FULL_SCAN_DEFAULT_BRANCH=true,以掃描
受保護預設分支的推送和手動流水線。設定
CODEX_SECURITY_SCHEDULED_DEEP_SCAN=true 並設定明確的時間和成本
預算,以便在受保護的預設分支上啟用定時深度掃描。
只有滿足以下條件時,合並請求流水線才能存取受保護變數和執行器:
- 你在同一專案中保護了源分支和目標分支。
- 專案允許合並請求流水線存取受保護變數和 執行器。
- 啟動流水線的使用者可以推送到目標分支或合並至目標分支。
來自 fork 儲存庫的流水線和不受保護的合並請求不會收到掃描
憑據。執行包含金鑰的作業前,請審查對 .gitlab-ci.yml 的每一項
更改。對變數進行掩碼和隱藏並不能讓不可信的 CI 程式碼
變得安全。
執行掃描並審查發現
建立一個符合條件的受保護合並請求,或在 受保護的預設分支上執行流水線。在執行需要付費的 完整儲存庫掃描前,先從較小的差異開始。
開啟 codex-security 作業,並確認其構件包括:
scan-manifest.jsonfindings.jsoncoverage.jsonresults.sarifscan-exit-code.txt
然後開啟流水線的 Security 選項卡,檢視攝取警告,並確認 發現識別符、嚴重性級別和源程式碼位置。預設分支掃描 還會建立專案漏洞記錄。合並請求發現會顯示在 流水線的 Security 選項卡或合並請求安全小元件中,但不會建立 專案級漏洞記錄。
請限制構件存取權限,因為掃描結果可能包含易受攻擊的源程式碼 片段、證據和修復詳情。
選擇掃描設定
流水線會根據觸發方式選擇設定:
| 觸發方式 | 目標 | 模式 | 工作量 |
|---|---|---|---|
| 受保護的同項目合並請求 | 已提交的差異 | standard |
low |
| 選擇啟用的受保護預設分支推送或手動流水線 | 完整儲存庫 | standard |
high |
| 受保護預設分支上選擇啟用的計劃任務 | 完整儲存庫 | deep |
xhigh |
合並請求掃描將回饋聚焦於已提交的更改。 預設分支掃描檢查已整合的儲存庫。定時深度掃描 提供更廣泛的週期性覆蓋。完成一次差異掃描只適用於該項 更改,並不表示整個儲存庫沒有問題。
工作流程會將 CLI 安裝在儲存庫外,並通過絕對 路徑執行。其試執行預檢會使用程序作用域的 API key,但不會啟動 付費掃描,也不會驗證 API 身份驗證、Codex Security 存取權限、配額或模型 可用性。
工作流程會將掃描狀態和結果寫入工作樹外部,並將
OPENAI_API_KEY 限定在掃描程序內。CLI 接收一組精簡且明確的
環境變數,而不會繼承每一個 GitLab 變數。對於差異掃描,
工作流程會計算合並基點,並將掃描繫結到已審查的基準修訂和
頭部修訂。
該範例將 @openai/codex-security 固定為 0.1.20。更改固定版本前,請重新測試身份驗證、
構件、SARIF 攝取和策略門控。
將報告與策略執行分離
GitLab 從成功的報告作業中攝取 SARIF。流水線會先發布
報告,然後在單獨的
codex-security-gate 作業中恢復掃描器的退出狀態。
報告作業接受退出程式碼為 0 和 1 的發現。只有當掃描清單證明掃描已完成、覆蓋範圍明確為
partial,且存在非空的 SARIF 報告時,才接受退出
程式碼 2。其他執行時、
設定或匯出失敗仍會阻止流水線。
最終門控會保留以下掃描器退出程式碼:
| 退出程式碼 | 含義 |
|---|---|
0 |
掃描以完整覆蓋範圍完成,並通過了策略檢查。 |
1 |
掃描完成,並發現了達到或超過所設定閾值的問題。 |
2 |
掃描覆蓋範圍不完整,或出現輸入或執行時錯誤。 |
在校準部分覆蓋範圍期間,該範例暫時允許退出程式碼 2。
如果不完整的覆蓋範圍必須阻止流水線,請移除此允許項。
修復和發布會在最終策略門控之前執行。即使門控隨後 導致流水線失敗,符合條件的發現仍可生成經過驗證的草稿合並請求。
啟用經過驗證的修復
自動修復為可選功能,並且僅針對受保護預設分支 流水線執行。Codex 修復程序和儲存庫控制的驗證 命令不會收到 GitLab 專案存取令牌或執行器注入的 憑據。
安全契約包含三個部分:儲存庫控制的命令絕不會 收到 OpenAI 或 GitLab 憑據;只有發布作業會獲得 儲存庫寫入權限;每一項生成的更改都會保持草稿狀態,直到 人工審查並合並。
該工作流程:
- 要求掃描覆蓋完整,並存在嚴重性為
high或critical的 發現。 - 確認所設定的迴歸測試在修補前失敗。
- 生成聚焦的補丁,並拒絕對 CI、憑據、二進位制檔案或 其他受保護檔案的更改。
- 在沒有 OpenAI、GitLab、登錄檔、部署或 作業令牌憑據的情況下執行迴歸測試。
- 使用
verify-fix傳回fixed、still_vulnerable或inconclusive。 只有當verify-fix傳回fixed,且 驗證程序未更改補丁時,作業才會發布補丁。
設定以下受保護變數以啟用修復:
- 將
CODEX_SECURITY_ENABLE_REMEDIATION設為true。 - 將
CODEX_SECURITY_VERIFICATION_COMMAND設為一個現有的迴歸測試,該測試 在修復前以1退出,修復後以0退出。 - 可選擇將
CODEX_SECURITY_SETUP_COMMAND設為非互動式依賴項 設定命令。
請選擇用於驗證底層安全不變數的迴歸測試,而不是 某種特定實現。對生成的測試和 源程式碼更改應用同等嚴格的審查。
高階:儲存庫命令隔離
validate、patch 和 verify-fix 命令會收到程序作用域的
CODEX_API_KEY。儲存庫控制的設定和測試命令會以
單獨的非特權使用者身份,在已跟蹤原始檔的可寫副本中執行。
該副本有意排除了 Git 後設資料、子模組內容和
下載的構件。需要 .git 或
子模組的設定和測試命令必須在單獨設計的無憑據作業中執行。
只有歸 root 所有的 Codex 步驟可以存取規範檢出目錄或 GitLab 的
相鄰檔案變數目錄。該副本的純淨環境僅包含
PATH、HOME、LANG、CI 和 CI_PROJECT_DIR。如果某個命令需要其他
非金鑰值,請在審查該命令後將其新增到允許列表。如果你的
執行器無法切換使用者,請先將驗證移至單獨的無憑據
作業,再啟用修復。
發布草稿合並請求
建立一個 GitLab 專案存取
令牌,
使用 Developer 角色以及 api 和 write_repository 作用域。將其儲存為
僅限 codex-security/publish 環境作用域的
受保護、已掩碼且隱藏的 GITLAB_REMEDIATION_TOKEN。
設定 CODEX_SECURITY_CREATE_MR=true 以啟用發布。還要將非金鑰的
CODEX_SECURITY_MR_TEST_COMMAND 設為專案專用的安全迴歸
測試,每個生成的修復分支都必須通過該測試。請勿保護此變數,
以便生成的不受保護合並請求可以讀取該命令。
發布工作流程:
- 接收儲存庫寫入令牌,但不會收到 OpenAI 憑據。
- 建立一個
codex-security/fix-<finding-hash>分支。 - 開啟草稿合並請求,並複用已有的開放草稿,而不會 建立重複項。
- 以非特權使用者身份,在沒有受保護憑據的僅含已跟蹤檔案的副本中, 執行不受保護的修復分支的迴歸測試。
- 絕不會自動合並生成的更改。
請勿使用 CI_JOB_TOKEN 替代專案存取令牌。它無法執行
所需的合並請求建立操作。合並前,請審查建議的補丁、
驗證證據和發現。
設定可選變數
僅設定已啟用功能所需的變數:
| 變數 | 需要它的情形 | 預設值或用途 |
|---|---|---|
CODEX_SECURITY_API_KEY |
每次掃描 | 受保護、已掩碼、隱藏;作用域限定為 codex-security/openai |
CODEX_SECURITY_VERSION |
CLI 升級 | 固定為 0.1.20;更改前請重新測試 |
CODEX_SECURITY_FULL_SCAN_DEFAULT_BRANCH |
預設分支完整掃描 | 明確選擇啟用;預設關閉 |
CODEX_SECURITY_SCHEDULED_DEEP_SCAN |
定時深度掃描 | 明確選擇啟用;預設關閉 |
CODEX_SECURITY_DEEP_MAX_TIME_HOURS |
定時深度掃描 | 所需時間預算必須大於 0 且小於 8 |
CODEX_SECURITY_DEEP_MAX_COST |
定時深度掃描 | 所需的預估美元成本保護閾值必須大於 0 |
CODEX_SECURITY_ENABLE_REMEDIATION |
生成補丁 | 受保護的選擇啟用項;預設關閉 |
CODEX_SECURITY_VERIFICATION_COMMAND |
生成補丁 | 受保護的迴歸測試 |
CODEX_SECURITY_SETUP_COMMAND |
可選的修復設定 | 受保護的依賴項安裝 |
CODEX_SECURITY_REMEDIATION_EFFORT |
可選的修復調優 | high |
CODEX_SECURITY_MAX_CHANGED_FILES |
可選的補丁大小限制 | 8;允許範圍為 1 到 20 |
CODEX_SECURITY_CREATE_MR |
建立草稿合並請求 | 受保護的選擇啟用項;預設關閉 |
GITLAB_REMEDIATION_TOKEN |
建立草稿合並請求 | 作用域限定為 codex-security/publish 的 Developer 專案令牌 |
CODEX_SECURITY_GITLAB_INTERNAL_URL |
可選的自託管發布 | 執行器可以存取 GitLab 源站 |
CODEX_SECURITY_MR_TEST_COMMAND |
發布草稿合並請求 | 必需的非金鑰、專案專用迴歸測試 |
CODEX_SECURITY_MR_SETUP_COMMAND |
可選的修復分支設定 | 非金鑰依賴項設定 |
GitLab 提供 CI_* 變數。流水線會管理
CODEX_SECURITY_BIN、CODEX_SECURITY_EFFORT、CODEX_SECURITY_MODE、
CODEX_SECURITY_STATE_DIR 和 CODEX_SECURITY_TARGET;不要將它們設定為
專案變數。對於差異掃描,CLI 會從規範化的基準修訂和頭部修訂
派生規範目標識別。
調整執行策略和成本
為合並請求回饋使用聚焦的差異掃描,為預設分支使用
標準儲存庫掃描,並使用定時深度掃描獲得更廣泛的覆蓋範圍。兩種
完整儲存庫設定預設均處於關閉狀態。定時深度掃描還需要
CODEX_SECURITY_DEEP_MAX_TIME_HOURS 和 CODEX_SECURITY_DEEP_MAX_COST;請讓
CLI 時間預算低於作業的八小時超時限制。設定預算前,請測量
有代表性的執行。請將 --max-cost 視為預估成本保護閾值,而不是
硬性賬單上限。
先從僅報告掃描開始。等團隊審查過
有代表性的發現、覆蓋範圍、成本和執行時間後,再新增 --fail-on-severity。有關嚴重性策略和退出程式碼
的詳情,請參閱在 CI 中執行 Codex
Security。
當作業失敗時:
- 缺少掃描構件說明存在設定或執行器問題。
- 已有構件但覆蓋範圍不完整時,需要檢查
coverage.json。 - 缺少 GitLab 發現時,需要檢查 SARIF 報告作業是否 成功,以及 GitLab 是否接受了報告。
- 修復被跳過時,需要檢查受保護分支、完整 覆蓋範圍、發現嚴重性、驗證命令和選擇啟用變數。
- 發布錯誤需要檢查專案令牌的角色、作用域和 環境限制。
有關每個命令、標誌和構件,請參閱 Codex Security CLI 參考。