在 GitHub Actions 中运行 Codex Security
使用 Codex Security Action 扫描拉取请求和仓库、保存报告、上传 SARIF,并配置强制执行。
在 GitHub Actions 中运行 Codex Security,审查拉取请求中的变更,或定时扫描仓库。该 Action 会安装 CLI,保存结构化报告,并添加作业摘要和源代码注解。先将结果仅用作参考,审查覆盖范围和扫描质量后,再配置强制执行。
准备工作流
运行扫描需要 Codex Security 访问权限。按以下步骤添加 OpenAI API key:
- 在 GitHub 仓库中,打开 Settings → Secrets and variables → Actions。
- 选择 New repository secret。
- 输入名称
CODEX_SECURITY_API_KEY,并将 OpenAI API key 粘贴为值。保存该机密。
下方的工作流示例会自动将此机密传递给 Codex Security Action。你无需将 API key 写入工作流文件。
仅对你信任的仓库和拉取请求运行工作流。扫描会使用运行器的本地权限,且不会暂停以等待批准。将无关的凭据和部署步骤放在单独的作业中。
添加 GitHub Actions 工作流
定时扫描仓库
以下工作流会在每周一 UTC 时间 07:23 扫描默认分支。你也可以从 GitHub 的 Actions 选项卡手动运行它。它使用 x64 GitHub 托管的 Ubuntu 24.04 运行器,并自动设置所需的沙箱。
- 在仓库中,选择 Add file → Create new file。
- 将文件命名为
.github/workflows/codex-security-repository.yml。 - 粘贴以下工作流并将其提交到默认分支。
name: Codex Security repository
on:
workflow_dispatch:
schedule:
- cron: "23 7 * * 1" # Mondays at 07:23 UTC
permissions:
contents: read
jobs:
security:
runs-on: ubuntu-24.04
timeout-minutes: 120
steps:
- name: Set up the Ubuntu sandbox
run: |
sudo apt-get update
sudo apt-get install --yes bubblewrap apparmor-profiles
sudo apparmor_parser -r /usr/share/apparmor/extra-profiles/bwrap-userns-restrict
- name: Check out the repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Scan the repository
id: security
uses: openai/codex-security@3f61e5150981a5087c32e4395bbaa8ce5ce0c3e3 # action-v0.3.0
with:
scope: repository
model: gpt-6-sol
# For approved Daybreak Blue access, uncomment the next input.
# cyber-access-program: daybreak_blue
effort: high
fail-on-severity: none
upload-artifacts: "true"
env:
OPENAI_API_KEY: ${{ secrets.CODEX_SECURITY_API_KEY }}
适配运行器: 该 Action 需要 Node.js 24 和 Python 3.11 或更高版本,此运行器已提供这些环境。沙箱设置会安装 bubblewrap 包,并在扫描前加载随附的 AppArmor 配置文件。在此运行器上,仅安装该包还不够。
如需手动运行工作流,请打开 Actions → Codex Security repository → Run workflow。打开一次已完成的运行,查看摘要、注解和可下载的报告。
由于 fail-on-severity 为 none,发现的问题只会记录在报告中。扫描器错误和必需的报告生成错误仍会导致作业失败。
如需扫描指定文件夹,请在扫描步骤的 with 块中添加以换行分隔的字面路径:
paths: |
src/api
src/auth路径要求使用 scope: repository,且不会展开 glob 模式。对于差异扫描,请省略 paths。保留 persist-credentials: false,并在检出代码后立即运行扫描。
扫描拉取请求中的变更
使用同一个机密,创建 .github/workflows/codex-security-pr.yml:
name: Codex Security PR
on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
permissions:
contents: read
concurrency:
group: codex-security-pr-${{ github.event.pull_request.number }}
cancel-in-progress: true
jobs:
security:
if: github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]'
name: Codex Security
runs-on: ubuntu-24.04
timeout-minutes: 60
steps:
- name: Set up the Ubuntu sandbox
run: |
sudo apt-get update
sudo apt-get install --yes bubblewrap apparmor-profiles
sudo apparmor_parser -r /usr/share/apparmor/extra-profiles/bwrap-userns-restrict
- name: Check out the pull request
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
persist-credentials: false
- name: Scan PR changes
id: security
uses: openai/codex-security@3f61e5150981a5087c32e4395bbaa8ce5ce0c3e3 # action-v0.3.0
with:
scope: diff
model: gpt-6-sol
# For approved Daybreak Blue access, uncomment the next input.
# cyber-access-program: daybreak_blue
effort: high
fail-on-severity: none
upload-artifacts: "true"
env:
OPENAI_API_KEY: ${{ secrets.CODEX_SECURITY_API_KEY }}从同一仓库中的分支发起或更新 PR。该 Action 使用完整历史记录查找确切的合并基点,并扫描截至已检出的 PR 头部提交的变更。在 PR 的 Checks 下查看 Codex Security 检查。先将发现的问题仅用作参考,准备好将其作为变更准入条件后,再选择严重性策略。
此示例会跳过来自 fork 的 PR 和由 dependabot[bot] 发起的 PR。作业被跳过并不表示已完成安全审查。如需包含这些机器人 PR,请移除发起者排除条件,并且将 CODEX_SECURITY_API_KEY 配置为供 dependabot[bot] 使用的机密。该 Action 不支持 pull_request_target 或 workflow_run。
扫描器会读取检出代码中适用的 SECURITY.md 指导说明,包括 PR 中的策略变更。请将这些变更与代码一并审查。
配置可选的 Daybreak 访问权限
Daybreak 为可选项。两个工作流示例均使用 gpt-6-sol。如果你的组织已获准使用 Trusted Access for Cyber,请在扫描步骤的 with 块中移除 cyber-access-program 前的 #:
model: gpt-6-sol
cyber-access-program: daybreak_blue使用已启用 Daybreak Blue 且有权访问 gpt-6-sol 的项目中的 API key。
该访问计划的输入也接受 standard。如果没有 Daybreak 访问权限,请使用你的 API key 在标准安全防护措施下有权访问的模型,并省略 cyber-access-program 或将其设为 standard。选择模型或访问计划并不会授予访问权限。请参阅该 Action 的 Daybreak 访问权限指南。
导致扫描中止的拒绝响应或安全拦截会使 Action 失败,即使 fail-on-severity 为 none 也是如此。该输入控制的是问题处理策略,而非扫描器错误。
设置可选的扫描预算
两个工作流示例均省略了 max-cost,因此未设置预估费用停止阈值。如需设置,请通过 max-cost 输入添加一个以美元计的正数金额。对于直接使用 CLI 的扫描,请使用 --max-cost。
费用限制要求 CLI 支持所选模型的定价。预估阈值并非硬性支出上限:正在进行的请求所产生的费用可能使总费用超出阈值。如果扫描因达到阈值而停止,请审查发现的问题和 coverage.json。有关费用限制行为,请参阅输出和策略选项。
保存报告并上传 SARIF
示例设置了 upload-artifacts: "true",以保存可下载的报告,保留期为七天。报告可能包含源代码片段、漏洞证据和修复细节。请根据代码的需要选择合适的保留期和仓库访问权限。该 Action 仅上传其允许列表中经过验证的报告;请勿递归上传其 results-directory 输出。
SARIF 上传为可选项。对于私有或内部仓库,请在上传前启用 GitHub Code Security。将工作流的 permissions 块替换为:
permissions:
contents: read
security-events: write
actions: read # Required for private repositories然后在任一工作流的扫描步骤之后添加以下步骤:
- name: Upload security findings
if: ${{ always() && steps.security.outputs.sarif-upload-ready == 'true' }}
uses: github/codeql-action/upload-sarif@b96794f015dfd88f77b49b1c93e0fa7110f94c63 # v4.38.0
with:
sarif_file: ${{ steps.security.outputs.sarif-path }}
sha: ${{ steps.security.outputs.scanned-sha }}
ref: ${{ steps.security.outputs.analysis-ref }}
category: codex-security-repository对于 PR 工作流,请使用 category: codex-security-pr,以便每个范围都有不同的类别。保留扫描步骤上的 id: security。即使发现的问题导致严重性策略检查失败,完整且经过验证的报告仍可上传。对于失败或中断的扫描、空差异或试运行,不会上传 SARIF。
有关所有设置、状态字段和报告路径,请参阅该 Action 的输入和输出参考。
选择严重性策略
GitHub 工作流最初使用 fail-on-severity: none。如需在已完成的扫描发现高危或严重问题时使作业失败,请更改扫描步骤的输入:
fail-on-severity: high在仓库规则中将 Codex Security 设为必需的状态检查,以便在 PR 作业失败时阻止合并。GitHub 会将因条件而跳过的作业视为成功,即使它是必需的检查也是如此。来自 fork 的 PR 和来自 dependabot[bot] 的 PR 会在未经扫描的情况下通过此检查。如需阻止这些跳过情况,请要求扫描成功完成。
该 Action 遵循 CLI 的执行结果:
- 退出码
0会设置scan-status: completed和policy-status: passed。 - 退出码
1会设置scan-status: completed和policy-status: failed;当发现的问题达到或超过所配置的严重性级别时,该步骤会失败。 - 退出码
2或进程中断会设置scan-status: failed和policy-status: not-evaluated;该步骤会失败。 - 必需报告无效或缺失、检出的代码发生变化、请求的产物上传失败以及运行时清理失败,也会导致该步骤失败。
扫描完成表示所配置的分析生成了有效结果。coverage.json 中的范围排除项、暂缓调查项及其他说明不会产生单独的扫描结果状态,也不会绕过严重性策略。扫描完成并不保证已发现所有漏洞。评估结果时请查看 coverage.json。
要求扫描成功完成
如需更严格的策略,请添加一个单独的门禁,即使扫描作业失败或被 GitHub 跳过,它也会运行。扫描作业中的步骤无法检查被跳过的作业,因为该作业的所有步骤都不会运行。
在 PR 工作流中,将此 outputs 映射添加到现有的 security 作业,使其与 runs-on 和 steps 保持相同缩进:
outputs:
scan-status: ${{ steps.security.outputs.scan-status }}然后在 jobs 下添加此作业,与现有的 security 作业并列:
security-gate:
name: Codex Security gate
needs: security
if: ${{ always() }}
runs-on: ubuntu-24.04
steps:
- name: Require a successful, completed scan
env:
SCAN_RESULT: ${{ needs.security.result }}
SCAN_STATUS: ${{ needs.security.outputs.scan-status }}
run: test "$SCAN_RESULT" = success && test "$SCAN_STATUS" = completed将 Codex Security gate 设为此策略的必需状态检查。它要求扫描作业成功,且满足 scan-status: completed。同时检查这两个条件,可以保留严重性策略、报告生成和清理造成的失败,即使扫描本身已完成也是如此。
按照示例中的排除条件,此门禁会阻止来自 fork 的 PR 和来自 dependabot[bot] 的 PR。它也会阻止空差异和试运行,Action 会将这些情况标记为 skipped。该门禁不会扫描被排除的 PR。仅当这些情况应阻止合并时,才选择此策略。
排查扫描问题
- 未知的 Git 引用或意外的差异: 使用
fetch-depth: 0检出 PR 头部提交。 - 沙箱启动错误: 在 Ubuntu 24.04 上,安装
bubblewrap包,并在 Action 运行前加载 AppArmor 配置文件。仅安装该包不会加载所需的配置文件。 - 缺少凭据: 确认受信任的工作流可以使用
CODEX_SECURITY_API_KEY,且它已映射到扫描步骤的OPENAI_API_KEY环境变量。 - Python 设置错误: 该 Action 需要 Python 3.11 或更高版本。
- 覆盖范围说明: 查看
coverage.json中的范围排除项和暂缓调查项。这些说明不会导致执行失败,也不会绕过严重性策略。 - 缺少 SARIF: 检查
scan-status、report-status和sarif-upload-ready。如果缺少可选的 SARIF,Action 会发出警告,但不会更改扫描结果状态;请求的产物上传失败仍会导致作业失败。 - SARIF 上传错误: 确认你的组织已为仓库启用 GitHub Code Security,且工作流已授予
actions: read、contents: read和security-events: write。