What is the Codex GitHub Action?
The Codex GitHub Action is openai/codex-action, an official OpenAI action that runs Codex inside a GitHub Actions workflow. It installs the Codex CLI, starts a proxy to the Responses API with your API key, and runs codex exec with the prompt and permissions you set. Codex's last message comes back as a step output you can post as a comment, save as a file or feed into later jobs.
OpenAI's GitHub Action docs list typical uses: automated pull request feedback, quality gates in CI, and repeatable jobs such as code review, release prep or migrations. The openai/codex-action repository holds the README, a security guide and the changelog. It is licensed under Apache 2.0.
If you already use Codex locally, think of the action as codex exec with guard rails for a shared runner. Our Codex CLI guide covers the command itself.
What do you need before you start?
The action has a short list of prerequisites, per the official docs:
- An API key stored as a secret. Use
OPENAI_API_KEY, orAZURE_OPENAI_API_KEYif you run OpenAI models on Azure. Pass it to theopenai-api-keyinput. - A Linux or macOS runner. Windows works only with
safety-strategy: unsafe. - A checkout step first. Run
actions/checkout@v5before the action so Codex can see your code. - A prompt. Give it inline with
promptor as a committed file withprompt-file. Provide exactly one. The docs suggest keeping prompt files in.github/codex/prompts/.
Every run uses that key, so think about who can trigger the workflow. The security guide warns that opening the action to everyone can invite people to use your key's quota for their own work.
How do you set up a pull request review workflow?
The README's main example builds a review bot in two jobs. The first job runs Codex with read-only repository permissions. The second job, which has write permissions, posts the result. This split keeps Codex away from the token that can comment on your PR.
name: Codex PR review
on:
pull_request:
types: [opened]
jobs:
codex:
runs-on: ubuntu-latest
permissions:
contents: read
outputs:
final_message: ${{ steps.run_codex.outputs.final-message }}
steps:
- uses: actions/checkout@v5
with:
ref: refs/pull/${{ github.event.pull_request.number }}/merge
persist-credentials: false
- name: Run Codex
id: run_codex
uses: openai/codex-action@v1
with:
openai-api-key: ${{ secrets.OPENAI_API_KEY }}
permission-profile: ":workspace"
prompt-file: .github/codex/prompts/review.md
post_feedback:
runs-on: ubuntu-latest
needs: codex
if: needs.codex.outputs.final_message != ''
permissions:
issues: write
pull-requests: write
steps:
- uses: actions/github-script@v7
env:
CODEX_FINAL_MESSAGE: ${{ needs.codex.outputs.final_message }}
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,
});
This is a trimmed and adapted version of the official example. The original also fetches the base and head refs so Codex can run git log across the PR range, and it passes an inline prompt with the PR details instead of prompt-file. Write your review instructions in .github/codex/prompts/review.md: what to check, how strict to be, and how to format findings.
Two details matter in that example. persist-credentials: false stops the checkout from leaving a Git token on disk for Codex to find. And the README notes that the recommended :workspace permission profile has no network access, so install any dependencies in a step before Codex runs.
Which inputs does the action accept?
All inputs are optional strings. These are the ones you will reach for most, as listed in the README:
| Input | What it does |
|---|---|
openai-api-key |
Starts the Responses API proxy. Store it in secrets. |
prompt / prompt-file |
The task, inline or from a file. Use one, not both. |
permission-profile |
Built-in or configured Codex permission profile, such as :workspace or :read-only. |
sandbox |
Legacy sandbox mode. Cannot be combined with permission-profile. |
model / effort |
Model and reasoning effort. Leave empty for Codex defaults. |
codex-args |
Extra flags for codex exec, as a JSON array or a shell string. |
output-file |
Writes the final message to a file. |
output-schema / output-schema-file |
Passed to codex exec --output-schema for structured output. |
working-directory |
Passed to codex exec --cd. Defaults to the repo root. |
codex-version |
Pins the @openai/codex version. Empty means latest. |
codex-home |
A Codex home directory for config, profiles or MCP setup. |
safety-strategy |
How the action limits Codex's privileges. Default drop-sudo. |
allow-users / allow-bots / allow-bot-users |
Who besides users with write access can trigger the run. |
The only output is final-message, the last message from codex exec. Map it to a job output, as in the example above, to use it in another job. For a full transcript, combine output-file with an artifact upload step.
What is the difference between permission profiles and safety strategies?
These are two separate layers, and the security guide is explicit that one does not replace the other.
Permission profiles limit what the commands Codex runs can touch: files and network. The README prefers permission-profile: ":workspace" for workflows that edit the checkout and :read-only for review-only jobs. You can also name a custom profile defined in the config.toml under codex-home. Profiles are beta and need Codex CLI 0.138.0 or later. If you set neither a profile nor sandbox, Codex falls back to the legacy workspace-write sandbox. The Codex permissions docs describe the profile schema.
Safety strategies limit the privileges of the Codex process itself on the runner:
| Strategy | What it does |
|---|---|
drop-sudo (default) |
Revokes the runner user's sudo on Linux and macOS before Codex starts. Irreversible for the job. |
unprivileged-user |
Runs Codex as the account named in codex-user, which you create yourself. |
read-only |
Read-only sandbox with no direct network. Cannot be combined with a permission profile. |
unsafe |
No privilege reduction. Required on Windows. Use only with fully trusted prompts. |
The reason this matters is your API key. The security guide shows that read-only file access plus passwordless sudo, which GitHub-hosted runners have by default, can expose OPENAI_API_KEY through process memory. Its advice, in bold: "Be sure to use either drop-sudo or unprivileged-user to ensure it stays secret!"
How do you keep the workflow safe?
The official docs and security guide agree on a short checklist:
- Limit who can trigger it. By default only users with write access can run the action. Widen that with
allow-usersorallow-bot-usersonly for accounts you trust.allow-bot-usersdoes not accept*. - Treat PR content as untrusted. Titles, bodies, commit messages, screenshots and even
AGENTS.mdfiles from a PR branch can carry prompt injection. A PR body can hide instructions in an HTML comment that the model reads and a reviewer never sees. - Pass GitHub expressions through
env. Splicing${{ github.event... }}straight into arun:script can break shell quoting. Put values inenv:and quote the shell variables. - Run Codex as the last step in a job. Codex may leave processes running or change files that later steps trust. Pass its output to a fresh job instead.
- Keep config trusted. Do not point
codex-homeat aconfig.tomlfrom an untrusted checkout. The action does not sanitize it. - Rotate keys if anything leaks. If a key shows up in logs or output, revoke it on the OpenAI Platform.
The README also notes that calling codex directly from a later script step skips the action's protections. Run Codex through the action's prompt or prompt-file inputs instead.
How is the action different from @codex review?
OpenAI offers two ways to get Codex reviews on GitHub, and they suit different needs.
Codex code review is a hosted feature. You connect the repository to Codex, turn on reviews in settings, and comment @codex review on a pull request, or enable automatic reviews. It reads review rules from a ## Code Review Rules section in your AGENTS.md. You do not write any workflow YAML.
The GitHub Action is a building block. You write the workflow, choose the trigger, the prompt, the model and the permissions, and decide what happens with the output. The README describes it as the option "if you want to have more control over the experience." That control lets you run Codex on events other than pull requests, produce structured JSON, or chain the result into deployment or labeling steps.
| @codex review | openai/codex-action | |
|---|---|---|
| Setup | Codex settings, no YAML | Workflow file you write |
| Auth | Connected Codex account | API key in GitHub secrets |
| Prompt | Built in, plus AGENTS.md rules | Fully yours |
| Output | GitHub review | final-message and optional file |
| Triggers | PR comments or automatic | Any GitHub Actions event |
If you also use Claude Code, the Claude Code GitHub Actions guide covers Anthropic's equivalent.
Where should you keep your CI prompts?
A review prompt in .github/codex/prompts/ tends to get copied from repo to repo and drift. Kipt keeps prompts and Agent Skills as Markdown in a private GitHub repo you own, with {{name}} blanks for the parts that change, so one reviewed version of your CI prompt lives in a single place. To turn a prompt into a skill Codex can load, try the free SKILL.md generator.