Skip to content

Codex GitHub Action

Every pull request in your repository gets reviewed by a human, but the human often catches the same categories of issues: missing error handling, inconsistent naming, security anti-patterns. Before the human even looks at the PR, Codex has already reviewed it, posted findings as a comment, and sometimes proposed a fix. The Codex GitHub Action makes this a zero-maintenance part of your CI pipeline.

  • A complete GitHub Actions workflow that reviews PRs with Codex and posts feedback automatically
  • Configuration patterns for prompts, sandboxing, and privilege management
  • Security hardening that protects your API key and limits Codex’s blast radius on CI runners
  • Troubleshooting techniques for common Action failures
  • An OpenAI API key stored as a GitHub secret (e.g., OPENAI_API_KEY)
  • A Linux or macOS runner (Windows requires safety-strategy: unsafe)
  • Your code checked out before invoking the action
name: Codex Pull Request Review
on:
pull_request:
types: [opened, synchronize, reopened]
jobs:
codex:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
outputs:
final_message: ${{ steps.run_codex.outputs.final-message }}
steps:
- uses: actions/checkout@v5
with:
ref: refs/pull/${{ github.event.pull_request.number }}/merge
- name: Pre-fetch base and head refs
run: |
git fetch --no-tags origin \
${{ github.event.pull_request.base.ref }} \
+refs/pull/${{ github.event.pull_request.number }}/head
- name: Run Codex
id: run_codex
uses: openai/codex-action@v1
with:
openai-api-key: ${{ secrets.OPENAI_API_KEY }}
prompt-file: .github/codex/prompts/review.md
output-file: codex-output.md
safety-strategy: drop-sudo
sandbox: workspace-write
post_feedback:
runs-on: ubuntu-latest
needs: codex
if: needs.codex.outputs.final_message != ''
steps:
- name: Post Codex feedback
uses: actions/github-script@v7
with:
github-token: ${{ github.token }}
script: |
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
body: process.env.CODEX_FINAL_MESSAGE,
});
env:
CODEX_FINAL_MESSAGE: ${{ needs.codex.outputs.final_message }}

Store your review prompt in .github/codex/prompts/review.md:

Review this pull request for:
1. Security vulnerabilities (SQL injection, XSS, auth bypasses)
2. Performance regressions (N+1 queries, missing indexes, unbounded loops)
3. Missing error handling and edge cases
4. Breaking API changes not documented in the changelog
Format findings as a numbered list with severity (Critical, Warning, Info).
Include file paths and line numbers for each finding.
InputDescription
prompt or prompt-fileInline text or path to a Markdown file with your instructions
openai-api-keyYour OpenAI API key (from GitHub secrets)
sandboxread-only, workspace-write, or danger-full-access
safety-strategydrop-sudo (default), unprivileged-user, or unsafe
codex-argsExtra CLI flags as JSON array or shell string
modelModel override (leave empty for default)
output-fileSave the final message to disk for artifacts

The safety-strategy input is your primary security control:

  • drop-sudo (default): Irreversibly removes sudo before running Codex. Protects secrets in memory.
  • unprivileged-user: Runs Codex as a specific non-root account. Pair with codex-user input.
  • unsafe: No privilege restrictions. Required on Windows. Never use on shared runners.

For downstream steps that need structured data, pass --output-schema through codex-args:

- uses: openai/codex-action@v1
with:
openai-api-key: ${{ secrets.OPENAI_API_KEY }}
prompt: "Extract project metadata and list all public API endpoints"
codex-args: '["--output-schema", ".github/codex/schemas/metadata.json"]'
output-file: metadata.json
sandbox: read-only
  • “You set both prompt and prompt-file”: Choose one. Remove the duplicate input.
  • “responses-api-proxy didn’t write server info”: Your API key is missing or invalid. Check the secret name and value.
  • Permission errors after drop-sudo: Grant write access before the action runs with chmod -R g+rwX "$GITHUB_WORKSPACE".
  • Unauthorized trigger blocked: Adjust allow-users or allow-bots inputs to permit service accounts.
  • Expected sudo removal but sudo succeeded: Ensure no earlier step restored sudo. Re-run with a fresh job.