繁體中文

在 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 的每一項更改。 這個最小範例有意省略了完整掃描和修復。

採用生產流水線

  1. 下載完整的 GitLab 流水線, 並將其儲存為儲存庫根目錄中的 .gitlab-ci.yml。如果儲存庫 已有流水線,請將範例中的階段、隱藏模板和 作業合並到現有檔案中。
  2. 保留現有的建置、測試和部署階段。如果專案使用 workflow: rules,請確認它允許你要掃描的流水線事件。

該範例添加了 security_scansecurity_remediationsecurity_publishsecurity_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.json
  • findings.json
  • coverage.json
  • results.sarif
  • scan-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 作業中恢復掃描器的退出狀態。

報告作業接受退出程式碼為 01 的發現。只有當掃描清單證明掃描已完成、覆蓋範圍明確為 partial,且存在非空的 SARIF 報告時,才接受退出 程式碼 2。其他執行時、 設定或匯出失敗仍會阻止流水線。

最終門控會保留以下掃描器退出程式碼:

退出程式碼 含義
0 掃描以完整覆蓋範圍完成,並通過了策略檢查。
1 掃描完成,並發現了達到或超過所設定閾值的問題。
2 掃描覆蓋範圍不完整,或出現輸入或執行時錯誤。

在校準部分覆蓋範圍期間,該範例暫時允許退出程式碼 2。 如果不完整的覆蓋範圍必須阻止流水線,請移除此允許項。

修復和發布會在最終策略門控之前執行。即使門控隨後 導致流水線失敗,符合條件的發現仍可生成經過驗證的草稿合並請求。

啟用經過驗證的修復

自動修復為可選功能,並且僅針對受保護預設分支 流水線執行。Codex 修復程序和儲存庫控制的驗證 命令不會收到 GitLab 專案存取令牌或執行器注入的 憑據。

安全契約包含三個部分:儲存庫控制的命令絕不會 收到 OpenAI 或 GitLab 憑據;只有發布作業會獲得 儲存庫寫入權限;每一項生成的更改都會保持草稿狀態,直到 人工審查並合並。

該工作流程:

  1. 要求掃描覆蓋完整,並存在嚴重性為 highcritical 的 發現。
  2. 確認所設定的迴歸測試在修補前失敗。
  3. 生成聚焦的補丁,並拒絕對 CI、憑據、二進位制檔案或 其他受保護檔案的更改。
  4. 在沒有 OpenAI、GitLab、登錄檔、部署或 作業令牌憑據的情況下執行迴歸測試。
  5. 使用 verify-fix 傳回 fixedstill_vulnerableinconclusive。 只有當 verify-fix 傳回 fixed,且 驗證程序未更改補丁時,作業才會發布補丁。

設定以下受保護變數以啟用修復:

  • CODEX_SECURITY_ENABLE_REMEDIATION 設為 true
  • CODEX_SECURITY_VERIFICATION_COMMAND 設為一個現有的迴歸測試,該測試 在修復前以 1 退出,修復後以 0 退出。
  • 可選擇將 CODEX_SECURITY_SETUP_COMMAND 設為非互動式依賴項 設定命令。

請選擇用於驗證底層安全不變數的迴歸測試,而不是 某種特定實現。對生成的測試和 源程式碼更改應用同等嚴格的審查。

高階:儲存庫命令隔離

validatepatchverify-fix 命令會收到程序作用域的 CODEX_API_KEY。儲存庫控制的設定和測試命令會以 單獨的非特權使用者身份,在已跟蹤原始檔的可寫副本中執行。 該副本有意排除了 Git 後設資料、子模組內容和 下載的構件。需要 .git 或 子模組的設定和測試命令必須在單獨設計的無憑據作業中執行。

只有歸 root 所有的 Codex 步驟可以存取規範檢出目錄或 GitLab 的 相鄰檔案變數目錄。該副本的純淨環境僅包含 PATHHOMELANGCICI_PROJECT_DIR。如果某個命令需要其他 非金鑰值,請在審查該命令後將其新增到允許列表。如果你的 執行器無法切換使用者,請先將驗證移至單獨的無憑據 作業,再啟用修復。

發布草稿合並請求

建立一個 GitLab 專案存取 令牌, 使用 Developer 角色以及 apiwrite_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;允許範圍為 120
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_BINCODEX_SECURITY_EFFORTCODEX_SECURITY_MODECODEX_SECURITY_STATE_DIRCODEX_SECURITY_TARGET;不要將它們設定為 專案變數。對於差異掃描,CLI 會從規範化的基準修訂和頭部修訂 派生規範目標識別。

調整執行策略和成本

為合並請求回饋使用聚焦的差異掃描,為預設分支使用 標準儲存庫掃描,並使用定時深度掃描獲得更廣泛的覆蓋範圍。兩種 完整儲存庫設定預設均處於關閉狀態。定時深度掃描還需要 CODEX_SECURITY_DEEP_MAX_TIME_HOURSCODEX_SECURITY_DEEP_MAX_COST;請讓 CLI 時間預算低於作業的八小時超時限制。設定預算前,請測量 有代表性的執行。請將 --max-cost 視為預估成本保護閾值,而不是 硬性賬單上限。

先從僅報告掃描開始。等團隊審查過 有代表性的發現、覆蓋範圍、成本和執行時間後,再新增 --fail-on-severity。有關嚴重性策略和退出程式碼 的詳情,請參閱在 CI 中執行 Codex Security

當作業失敗時:

  • 缺少掃描構件說明存在設定或執行器問題。
  • 已有構件但覆蓋範圍不完整時,需要檢查 coverage.json
  • 缺少 GitLab 發現時,需要檢查 SARIF 報告作業是否 成功,以及 GitLab 是否接受了報告。
  • 修復被跳過時,需要檢查受保護分支、完整 覆蓋範圍、發現嚴重性、驗證命令和選擇啟用變數。
  • 發布錯誤需要檢查專案令牌的角色、作用域和 環境限制。

有關每個命令、標誌和構件,請參閱 Codex Security CLI 參考