GitHub Actions で Codex Security を実行する

Codex Security Action でプルリクエストやリポジトリをスキャンし、レポートの保存、SARIF のアップロード、ポリシーの適用を設定します。

GitHub Actions で Codex Security を実行すると、プルリクエストの変更をレビューしたり、リポジトリを定期的にスキャンしたりできます。この Action は CLI をインストールし、構造化されたレポートを保存して、ジョブのサマリーとソースコードへの注釈を追加します。まずは結果を参考情報として確認する運用から始め、カバレッジとスキャンの品質を確認してからポリシーの適用を設定してください。

ワークフローを準備する

スキャンの実行には Codex Security へのアクセスが必要です。OpenAI API key を追加するには、次の手順に従います。

  1. GitHub リポジトリで Settings → Secrets and variables → Actions を開きます。
  2. New repository secret を選択します。
  3. 名前に CODEX_SECURITY_API_KEY を入力し、値として OpenAI API key を貼り付けます。シークレットを保存します。

以下のワークフロー例では、このシークレットが Codex Security Action に自動的に渡されます。ワークフローファイルに API key を記載する必要はありません。

ワークフローは、信頼できるリポジトリとプルリクエストに対してのみ実行してください。スキャンはランナーのローカル権限を使用し、承認を求めて一時停止することはありません。無関係な認証情報とデプロイ手順は別のジョブに分けてください。

GitHub Actions ワークフローを追加する

リポジトリを定期的にスキャンする

以下のワークフローは、毎週月曜日の 07:23 UTC にデフォルトブランチをスキャンします。 GitHub の Actions タブから手動で実行することもできます。x64 の GitHub ホステッド Ubuntu 24.04 ランナーを使用し、必要なサンドボックスを自動的に設定します。

  1. リポジトリで Add file → Create new file を選択します。
  2. ファイル名を .github/workflows/codex-security-repository.yml にします。
  3. 以下のワークフローを貼り付けて、デフォルトブランチにコミットします。
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 チェックを確認してください。まずは検出結果を参考情報として確認し、変更をブロックする準備ができたら重大度ポリシーを選びます。

この例では、フォークからの 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" を設定し、ダウンロード可能なレポートを 7 日間保持します。レポートには、ソースコードの抜粋、脆弱性の証拠、修正の詳細が含まれる場合があります。コードに適した保持期間とリポジトリのアクセス権を選んでください。この 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 から始めます。完了したスキャンで重大度が high または critical の検出結果があった場合に失敗させるには、スキャンステップの入力を変更します。

fail-on-severity: high

PR ジョブが失敗した場合にマージをブロックするには、リポジトリのルールで Codex Security を必須のステータスチェックにします。GitHub は、必須チェックであっても条件によってスキップされたジョブを成功として扱います。フォークからの 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 ワークフローで、既存の security ジョブにこの outputs マッピングを、 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 の両方が必要です。両方を確認することで、スキャン自体が完了していても、重大度ポリシー、レポート処理、クリーンアップによる失敗が確実に反映されます。

この例の除外設定では、このゲートはフォークからの PR と dependabot[bot] による PR をブロックします。また、Action が skipped とマークする空の差分やドライランもブロックします。このゲートは、除外された PR をスキャンしません。これらの場合にマージを阻止する必要があるときにのみ、このポリシーを選んでください。

スキャンのトラブルシューティング

  • 不明な Git ref または予期しない差分: PR の先端を fetch-depth: 0 でチェックアウトします。
  • サンドボックス起動エラー: Ubuntu 24.04 では、Action の実行前に bubblewrap パッケージをインストールし、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 を付与していることを確認してください。

すべてのコマンド、フラグ、アーティファクト、出力フィールドについては、CLI リファレンスを参照してください。他のプロバイダーについては、 CI/CD の概要を参照してください。