Codex · Advanced · Part 7 of 8

Automation and teams: scripts, CI, pull request reviews, and team-wide setup

Khairul Alam·October 2026·~31 min read
AdvancedAutomationCI/CDGitHub ActionTeamsManaged configuration

Everything so far assumed you, a terminal and a conversation. The next step is Codex without the conversation: running from a script, a scheduled task or a pull request, and then rolling it out to a whole team with shared conventions and organisation rules. This part covers codex exec, the GitHub Action, automatic code review, scheduled tasks, a short look at the SDK and App Server, and team and admin setup. Automation means Codex acts with nobody watching, so the safety advice here matters more than anywhere else in the series.

Part 7 in 60 seconds
  • codex exec "prompt" runs Codex once, non-interactively. Progress goes to stderr, the final answer goes to stdout, and --json gives you an event stream.
  • By default codex exec runs in a read-only sandbox. Grant only what the job needs, for example --sandbox workspace-write.
  • In GitHub, use the Codex GitHub Action (openai/codex-action@v1) instead of installing and authenticating the CLI yourself. Mention @codex review on a pull request for a review.
  • For a team: commit a shared AGENTS.md, shared .codex/ configuration, rules and skills, and let admins enforce policy with requirements.toml.
  • Never put keys in a repository, treat pull request text as untrusted input, and keep a human in the merge step.

Codex changes quickly. This series was checked against the official documentation on 18 October 2026; always confirm details on the official pages. Team and admin features in particular depend on your plan and workspace settings.

Contents of Part 7
  1. Non-interactive mode: codex exec
  2. Running unattended safely
  3. Scripts, pipes and codex review
  4. Scheduled tasks
  5. The Codex GitHub Action
  6. Automatic code review of pull requests
  7. For builders: the SDK and the App Server
  8. Setting up a team
  9. For admins: requirements, tokens and oversight
  10. A security checklist
  11. A rollout checklist
  12. Wrap-up and glossary
  13. Links and official docs

1. Non-interactive mode: codex exec

Non-interactive mode lets you run Codex from scripts, such as continuous integration (CI) jobs, without opening the interactive terminal screen (the TUI). You start it with codex exec. The short form is codex e. Pass the task as a single argument:

codex exec "summarize the repository structure and list the top 5 risky areas"

While it runs, Codex streams progress to stderr and prints only the final agent message to stdout. That makes the result easy to redirect or pipe:

codex exec "generate release notes for the last 10 commits" | tee release-notes.md

The flags you will use most

These come from the CLI command reference for codex exec. Run codex exec --help for the list your installed version supports.

FlagWhat it does
--sandbox, -sSandbox policy for commands Codex generates: read-only, workspace-write or danger-full-access. Defaults to your configuration.
--jsonPrint newline-delimited JSON events instead of formatted text.
--output-last-message, -oWrite the final message to a file (it is still printed to stdout).
--output-schemaPath to a JSON Schema file describing the shape of the final answer.
--model, -mOverride the configured model for this run.
--cd, -CSet the workspace root before running the task.
--profile, -pLayer a profile file on top of your base user config.
-c, --config key=valueInline configuration override for this run (repeatable).
--ephemeralRun without persisting session files.
--ignore-user-configDo not load $CODEX_HOME/config.toml. Authentication still uses CODEX_HOME.
--ignore-rulesDo not load user or project .rules files for this run.
--approve-for-meUse automatic approval review with on-request approvals and the workspace-write sandbox. Conflicts with --sandbox and --yolo.
--yoloShort for --dangerously-bypass-approvals-and-sandbox. No approvals, no sandbox. Only inside an isolated runner.
--skip-git-repo-checkAllow running outside a Git repository.

--full-auto is no longer supported. If an old script uses it, change it to --sandbox workspace-write, or to --approve-for-me if you want approval requests routed through automatic review.

Machine-readable output

With --json, stdout becomes a stream of JSON objects, one per line (JSON Lines). Event types include thread.started, turn.started, turn.completed, turn.failed, item.* and error. Items cover agent messages, reasoning, command executions, file changes, MCP tool calls, web searches and plan updates. Example (shortened) stream from the docs:

codex exec --json "summarize the repo structure" | jq

# example output, one JSON object per line
{"type":"thread.started","thread_id":"0199a213-81c0-7800-8aa1-bbab2a035a53"}
{"type":"turn.started"}
{"type":"item.completed","item":{"id":"item_3","type":"agent_message","text":"Repo contains docs, sdk, and examples directories."}}
{"type":"turn.completed","usage":{"input_tokens":24763,"cached_input_tokens":24448,"output_tokens":122,"reasoning_output_tokens":0}}

A structured answer with --output-schema

When a later step needs stable fields, give Codex a JSON Schema and ask for the answer to match it. First the schema file:

schema.json
{
  "type": "object",
  "properties": {
    "project_name": { "type": "string" },
    "programming_languages": {
      "type": "array",
      "items": { "type": "string" }
    }
  },
  "required": ["project_name", "programming_languages"],
  "additionalProperties": false
}
codex exec "Extract project metadata" \
  --output-schema ./schema.json \
  -o ./project-metadata.json

The docs note that a prompt is required when you use images, --output-schema, --output-last-message or --ephemeral.

Inputlog, diff, file codex execone non-interactive run stdoutfinal message or JSONL Next stepjq, file, CI Progress streams to stderr, so it does not pollute the result you pipe on.
Codex becomes one more command-line tool in a pipeline.

Resume a run

For a two-stage pipeline, continue the previous session with the resume subcommand. --last picks the most recent session from the current directory; you can also pass a session ID.

codex exec "review the change for race conditions"
codex exec resume --last "fix the race conditions you found"

Authentication in automation

codex exec reuses your saved CLI sign-in by default. In CI you usually provide credentials explicitly. The docs give three routes:

RouteHowNotes from the docs
GitHub ActionsUse the Codex GitHub Action (section 5)Designed to reduce API key exposure: it installs Codex, starts a Responses API proxy and runs Codex with a configurable safety strategy.
API keyCODEX_API_KEY=<api-key> codex exec --json "triage open bug reports"The sensible default for automation: simple to provision and rotate. Set it only for the invocation that needs it, and make sure no untrusted code runs in the same environment. CODEX_API_KEY also works with codex review and the TypeScript SDK.
Access tokenCODEX_ACCESS_TOKEN (Business and Enterprise workspaces)Authenticates as a ChatGPT workspace identity. See section 9.
Do not hand the key to repository code

The docs say not to set OPENAI_API_KEY or CODEX_API_KEY as a job-level environment variable in workflows that check out or run repository-controlled code. Build scripts, tests, dependency hooks or a compromised action in the same job could read it.

There is also an advanced path for running CI as your Codex account instead of an API key, for example enterprise teams on trusted runners. It relies on ~/.codex/auth.json, which the docs say to treat like a password, and they say not to use it for public or open-source repositories. Read the official page before trying it (linked in section 13).

2. Running unattended safely

In an interactive session you are the safety net. In a script nobody is watching, so decide in advance what Codex may do. Remember from Part 5 that two controls work together: the sandbox (what Codex can technically do) and the approval policy (when it must ask). For codex exec the docs give these starting points:

GoalSettingEffect
Analyse onlyNothing extra (the default), or --sandbox read-onlyCodex can read files and run commands inside the read-only sandbox.
Let it edit files--sandbox workspace-writeRead files, edit inside the workspace and run commands there. Network access stays off by default.
Edit, with approval requests reviewed automatically--approve-for-meAutomatic approval review, on-request approvals, workspace-write sandbox.
Broad access--sandbox danger-full-accessNo filesystem restriction. Use only in a controlled environment such as an isolated CI runner or container.
No protection at all--yoloBypasses approvals and the sandbox. Only inside an isolated runner.

Two examples built from the docs:

# A run that may edit files in the workspace, and nothing more
codex exec --sandbox workspace-write "fix the failing unit test in the parser module"

# A controlled run that ignores personal config and rule files on the machine
codex exec --ignore-user-config --ignore-rules --sandbox read-only "list TODO comments by file"
Safety rules for automation
  • Least privilege: start read-only, move to workspace-write only when the job must edit, and keep danger-full-access and --yolo for isolated runners.
  • Set the sandbox on purpose. Do not rely on whatever a machine's config file says; pass --sandbox or use --ignore-user-config so every run behaves the same.
  • Untrusted input is dangerous: text from pull requests, commit messages, issues or logs can contain hidden instructions (prompt injection). Do not give a job that reads untrusted input broad write or network permissions.
  • Keep keys away from repository code, as described above.
  • Review what it produced. Unattended does not mean unreviewed: use pull requests, not direct pushes.
  • Add your own limits: set timeouts in your CI system. The docs do not describe a turn or budget cap for codex exec, so do not assume one exists.

3. Scripts, pipes and codex review

Two ways to pipe input

If you give a prompt and pipe input, the prompt is the instruction and the piped text is extra context. If you leave out the prompt (or write -), the piped text is the whole prompt.

# Prompt plus stdin: you write the instruction, the pipe supplies the data
npm test 2>&1 \
  | codex exec "summarize the failing tests and propose the smallest likely fix" \
  | tee test-summary.md

# Stdin is the prompt
cat prompt.txt | codex exec -

More patterns from the docs, all of the same shape (command output in, short text out):

tail -n 200 app.log \
  | codex exec "identify the likely root cause, cite the most important errors, and suggest the next three debugging steps" \
  > log-triage.md

# Draft a pull request comment from CI logs (replace the run and PR numbers)
gh run view 123456 --log \
  | codex exec "summarize the failure in 5 bullets for the pull request thread" \
  | gh pr comment 789 --body-file -

Run a review from the command line

codex review runs a code review non-interactively. Choose exactly one target, or pass custom instructions as the prompt:

OptionReviews
--uncommittedStaged, unstaged and untracked changes
--base BRANCHChanges against a base branch
--commit SHAThe changes introduced by one commit (add --title to set the title in the summary)
PROMPTCustom review instructions (- reads them from stdin)
codex review --base main

Looping over many items

The docs do not describe a built-in batch command for codex exec, so for a repetitive change you can simply loop. This is my own pattern, built from documented flags, not an official recipe:

for file in $(cat files.txt); do
  codex exec --sandbox workspace-write --ephemeral \
    "Migrate $file from the old logging helper to the new one. Reply OK or FAIL."
done

Do what you would do by hand: test the prompt on two or three files first, fix what goes wrong, then run it on the rest, and review the combined diff.

4. Scheduled tasks

If you want Codex to do something repeatedly, such as checking for new issues each morning, the docs describe scheduled tasks. They run in the background on a timetable you choose, and you review the runs in a view called Scheduled.

Scheduled tasks run unattended
  • They use your default sandbox settings. In read-only mode, a tool call that needs to edit files or reach the network fails. In workspace-write mode, calls that need files outside the workspace or network access fail, though you can allow chosen commands to run outside the sandbox with rules.
  • With full access, background tasks carry elevated risk because Codex can change files, run commands and use the network without asking. The docs suggest workspace-write plus rules for specific commands instead.
  • Scheduled tasks use approval_policy = "never" when your organisation policy allows it. If admin requirements forbid that, they fall back to the approval behaviour of your selected permission mode.

Test the prompt in a regular chat before you schedule it, review the first few runs, then adjust the prompt, tools or cadence. A scheduled task cannot ask you clarifying questions mid-run, so say what done looks like and what to report. Also check which model a task uses: the docs say GPT-5.5 retired from Codex with ChatGPT sign-in on 14 October 2026, and ask you to review scheduled tasks that used it.

5. The Codex GitHub Action

The Codex GitHub Action (openai/codex-action@v1) runs Codex inside a GitHub Actions workflow. It installs the Codex CLI, starts the Responses API proxy when you give it an API key, and runs codex exec under the permissions you set. Use it to get Codex feedback on pull requests or releases, to gate changes on Codex-driven checks, or to run repeatable tasks such as code review, release prep and migrations.

Prerequisites

A working workflow: review every pull request

This is the docs' example. It reviews new pull requests, captures Codex's answer and posts it as a comment. The first job has read-only repository permission; only the second job can write comments.

.github/workflows/codex-review.yml
name: Codex pull request review
on:
  pull_request:
    types: [opened, synchronize, reopened]

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
          fetch-depth: 0
          persist-credentials: false

      - 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

  post_feedback:
    runs-on: ubuntu-latest
    needs: codex
    if: needs.codex.outputs.final_message != ''
    permissions:
      issues: write
      pull-requests: write
    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 }}

Replace .github/codex/prompts/review.md with your own prompt file, or use the prompt input for inline text.

Pull requestopened orupdated Job 1: Codexcontents: read only,holds the API key Job 2: postcan write comments,has no API key Commenton the PR A human reviews and merges.Split the job that holds the key from the job that holds write permission.
The two-job pattern the docs use: the job that sees the key cannot write, and the job that can write never sees the key.

Action inputs worth knowing

InputWhat it does
prompt / prompt-fileThe task, inline or from a file such as .github/codex/prompts/.
codex-argsExtra CLI flags, as a JSON array (["--ephemeral"]) or a shell string (--profile ci). Pass --output-schema here for structured output.
model, effortPick the model and reasoning effort; leave empty for defaults.
sandboxworkspace-write, read-only or danger-full-access. Choose the narrowest that lets the task finish.
output-fileSave the final message to disk. The action also exposes it as the final-message output.
codex-versionPin a CLI release. Blank means the latest.
safety-strategyDefault drop-sudo: removes sudo before Codex runs (irreversible for that job, and it protects secrets in memory). unprivileged-user (with codex-user) runs Codex as a specific account. unsafe is required on Windows.
allow-users, allow-botsWho may trigger the workflow. By default only users with write access can.

Two cautions from the docs. First, read-only keeps Codex from changing files or using the network, but it still runs with elevated privileges, so do not rely on it alone to protect secrets. Second, Codex has broad access on GitHub-hosted runners unless you restrict it.

Pattern: propose a fix when CI fails

Non-interactive mode in the docs also includes a longer example that proposes a fix when your main CI workflow fails. The idea, in plain steps:

  1. Trigger a follow-up workflow (workflow_run) when the workflow named “CI” completes with a failure.
  2. Check out the failing commit with read-only permission and without persisting credentials.
  3. Run setup commands first, such as installing dependencies, before the Codex step, so they never see the API key.
  4. Run the action with a prompt that says to reproduce the failure, make the minimal change, run the tests again and not refactor unrelated files.
  5. Save the result as a patch artifact (git diff uploaded as an artifact).
  6. In a separate job, which has write permission but no OPENAI_API_KEY, apply the patch and open a pull request that says “Review the changes before merging.”

Copy the full YAML from the Non-interactive mode page (section 13) rather than retyping it, and adjust the setup and test commands to your stack.

6. Automatic code review of pull requests

Separate from the Action, Codex can review GitHub pull requests as a built-in feature. Codex reads the pull request diff, follows your repository guidance and posts a standard GitHub code review. In GitHub it flags only the most serious issues (the docs say P0 and P1) so the comments stay focused. A deeper Security Review is available in research preview.

  1. Connect your GitHub repository to Codex. You need push or admin permission for the repository's settings.
  2. Open Codex settings (code review) at chatgpt.com/settings/code-review, choose the repository and turn on Automatic review under Review code.
  3. Or ask on demand: comment @codex review on a pull request. Codex reacts and posts a review. You can add a focus, such as @codex review for issues in the database migration.

Personal preferences in the same settings page include Review trigger, which decides when automatic reviews run.

Teach it your rules in AGENTS.md

Codex searches the repository for AGENTS.md files (Part 2) and follows the code review rules it finds. Add a ## Code Review Rules section to the file closest to the code the rules govern. Put repository-wide rules in the root file and service-specific rules in a nested one, such as services/experiment_reporting/AGENTS.md.

AGENTS.md
## Code Review Rules

### Experiment cohorts

- Do not filter treatment comparisons on post-exposure behavior, including conversion or retention.
  Safe path: build cohorts from assignment or exposure; report conversion as an outcome.

The docs' advice on writing such rules: start with two or three concise ones, focus on consequential and repository-specific behaviour, state the safe path or exception, keep rules scoped and durable, and leave mechanical checks such as formatting and lint to CI. They also say review rules guide Codex but do not replace tests, branch protections or required approvals.

Other places Codex can be started from

These integrations depend on your plan and workspace settings, so confirm availability on the official pages before planning around them.

7. For builders: the SDK and the App Server

Most readers can skip this section. If you want to control Codex from your own program rather than from a shell script, the docs describe two options:

OptionWhat it isUse it for
Codex SDKA TypeScript library (npm install @openai/codex-sdk, Node.js 18 or later, used server-side) and a Python library (pip install openai-codex, Python 3.10 or later).Automating coding tasks, including CI jobs, and building Codex into your own tools.
App ServerThe interface Codex uses to power rich clients such as the VS Code extension. It speaks JSON-RPC 2.0 over stdio by default; a WebSocket transport exists but is experimental and unsupported for production.Deep integrations that need authentication, conversation history, approvals and streamed agent events.

The docs' rule of thumb: automating jobs or running in CI means the SDK; building a custom client means the App Server. A minimal TypeScript example from the docs:

import { Codex } from "@openai/codex-sdk";

const codex = new Codex();
const thread = codex.startThread();
const result = await thread.run(
  "Make a plan to diagnose and fix the CI failures"
);

console.log(result.finalResponse);

Call run() again on the same thread to continue, or resume an earlier thread with codex.resumeThread(threadId). The Python SDK exposes sandbox presets (Sandbox.read_only, Sandbox.workspace_write, Sandbox.full_access) that mirror the CLI sandbox modes. One removal to know about: the docs say the codex mcp-server command was removed, and existing integrations should use the App Server instead. For the full API, follow the SDK and App Server pages in section 13.

8. Setting up a team

A team gets the most from Codex when everyone starts from the same baseline and each person can still personalise. The building blocks are things you have already met:

WhatWhereCommitted?Who it affects
Project conventions, commands, gotchas, review rulesAGENTS.md (nested files for subfolders)YesEveryone on the repository
Shared defaults (model, approvals, sandbox, MCP servers).codex/config.toml in the repoYesEveryone who trusts the project
Command rules (what may run outside the sandbox).codex/rules/*.rulesYesEveryone who trusts the project
Shared workflows and know-howSkills (Part 6)YesEveryone
Personal preferences~/.codex/AGENTS.md, ~/.codex/config.toml, ~/.codex/rules/No (your home folder)Only you

Three facts from the docs explain how these layers combine:

requirements.toml: admin-enforced limits that cap every layer below 1. CLI flags and --config overrides 2. Project .codex/config.toml (trusted projects, closest folder wins) 3. Profile file chosen with --profile 4. User config: ~/.codex/config.toml 5. Cloud-managed config.toml defaults 6. System config: /etc/codex/config.toml (Unix) 7. Built-in defaults
Higher layers win for ordinary settings. Requirements are different: they constrain what the other layers may choose. Order from the config basics page.

Habits that work, mostly from the docs and Parts 2 and 3:

9. For admins: requirements, tokens and oversight

Shared files are conventions. If your organisation needs limits that users cannot override, the docs offer managed configuration for ChatGPT Enterprise. It has three pieces:

PieceWhat it is
RequirementsAdmin-enforced constraints, in a requirements.toml file. Users cannot override them.
Configuration defaultsSystem or cloud-managed config.toml settings that users can still change.
Legacy managed defaultsmanaged_config.toml starting values, re-applied each time a supported client starts.

Managed configuration does not grant a seat or feature access; that comes from workspace roles and permissions.

What requirements can constrain

Requirements cover security-sensitive settings: approval policy, approvals reviewer, sandbox mode, permission profiles, web search mode, managed hooks, which MCP servers users can enable, and which plugin marketplaces they can use. If a user's configuration conflicts with a requirement, the local client falls back to a compatible value and tells the user. With an mcp_servers allowlist, a server is enabled only when both its name and identity match an approved entry.

This example from the docs blocks --ask-for-approval never and --sandbox danger-full-access (including --yolo):

requirements.toml
allowed_approval_policies = ["untrusted", "on-request"]
allowed_sandbox_modes = ["read-only", "workspace-write"]

For Codex 0.138.0 or later, the docs prefer permission profiles over the older sandbox-mode allowlist. This policy allows read-only and workspace access but not full access, because anything omitted from the table is denied:

requirements.toml
default_permissions = ":workspace"

[allowed_permission_profiles]
":read-only" = true
":workspace" = true
# ":danger-full-access" is omitted, so it is denied.

Version matters: Codex 0.137.0 and earlier ignore allowed_permission_profiles and the managed default_permissions. The docs say to deploy these only after every managed client has upgraded. Also, approval_policy = "untrusted" is retired as an explicit setting; see the managed configuration page if an old config still uses it.

Admins can also force command prompts. This requirement makes common shell entry points ask first:

requirements.toml
allowed_approval_policies = ["on-request"]
allowed_sandbox_modes = ["read-only", "workspace-write"]

[rules]
prefix_rules = [
  { pattern = [{ any_of = ["bash", "sh", "zsh"] }], decision = "prompt", justification = "Require explicit approval for shell entry points" },
]

How requirements are delivered

For local clients, requirements are applied from lower to higher priority in this order:

  1. System requirements.toml: /etc/codex/requirements.toml on Linux and macOS, or %ProgramData%\OpenAI\Codex\requirements.toml on Windows.
  2. Requirements delivered in the cloud, from Agent Security in the Admin Console, when a user signs in with ChatGPT on a supported plan.
  3. Legacy managed_config.toml fields that the client reinterprets as requirements.
  4. macOS managed preferences (MDM), under com.openai.codex:requirements_toml_base64.

Higher layers override lower ones for ordinary values, while some fields (rules, hooks, filesystem restrictions) have their own merge behaviour, so read the reference rather than guessing. Authentication requirements are special: allowed_login_methods, allowed_chatgpt_workspaces, cli_auth_credentials_store and chatgpt_base_url must be set locally (system file or macOS MDM), because Codex ignores them when they arrive from the cloud. The docs recommend testing one allowed and one blocked workflow on a real client before you roll out.

Access tokens and service accounts

Automation needs an identity. The docs describe two ways to use a ChatGPT workspace identity instead of an API key (both for ChatGPT Business and Enterprise; service accounts only on pay-as-you-go plans):

Access tokenService account
RepresentsThe workspace member who created itA non-human workspace identity, for example release-automation
CreatedIn the admin console under Access tokensUnder Service accounts; a token is then created from the account's detail page
Good forcodex exec jobs, local scripts and trusted app-server automationCI runners, scheduled jobs and shared integrations that should not depend on an employee

Using one is simple:

# Ephemeral: nothing is saved on the machine
export CODEX_ACCESS_TOKEN="<access-token>"
codex exec --json "review this repository and summarize the top risks"

# Or save a login (not for shared or temporary runners)
printf '%s' "$CODEX_ACCESS_TOKEN" | codex login --with-access-token

Rules the docs give for tokens:

Seeing usage and cost

Where to look depends on how your team pays:

QuestionWhere the docs point
Interactive usage and Codex analyticsWorkspace analytics in the admin console
Programmatic, aggregated reportingThe Analytics API
Audit and investigation recordsThe Compliance API
Spend on eligible Codex activity under a workspace planChatGPT usage limits and spend controls (user guardrails, workspace-level spend controls, notifications, depending on plan)
Spend on the OpenAI API PlatformPlatform billing, which the workspace spend controls do not govern

The docs are explicit that workspace usage controls apply only to eligible activity and do not cover all Codex usage. One more item: GPT-6 Astra Ultrafast is off by default in eligible Enterprise workspaces, existing per-user spend limits apply to it, and its higher usage rates can use up a budget faster. Plans and prices change, so use the pricing page rather than any number you read in an article. The admin rollout guide also suggests reviewing access, credit use and real workflows after launch.

10. A security checklist

This list is my own summary, built from the docs above and the security sections of the GitHub Action and non-interactive pages.

Before you let Codex run unattended
  • Least privilege. Read-only by default, workspace-write when it must edit, full access only in an isolated runner or container. Give the workflow token only the permissions the job needs (for example contents: read).
  • Secrets. Keep keys in GitHub Secrets or a secret manager. Never commit them, never set them as job-level environment variables in a job that runs repository code, and rotate quickly if you suspect exposure. Treat ~/.codex/auth.json and access tokens like passwords.
  • Network access. The agent runs with network access off by default. Turn it on only when required, and check the destinations your jobs really need.
  • Who can trigger it. Restrict the workflow to trusted events and users. By default the Action only allows users with write access; use allow-users and allow-bots deliberately.
  • Untrusted text. Sanitise or avoid feeding pull request bodies, commit messages and issue text to a privileged job, and review hidden text such as HTML comments, to reduce prompt injection.
  • Order of steps. Run Codex as the last step of a job, so later steps do not inherit unexpected state.
  • Separate jobs by privilege. The job with the key should not hold write permission, and the job with write permission should not hold the key.
  • Review before merge. Output goes to a pull request or a comment. A human reads it and runs your normal tests, branch protections and required approvals.
  • Protect the fleet. Use requirements.toml so nobody can quietly pick a looser sandbox, and test that a blocked action is really blocked.

For a deeper list, the docs link to the Action's security guidance on GitHub (section 13). Part 5 explained sandboxing and approvals in more detail.

11. A rollout checklist

This list is my own suggestion, built from the docs above:

  1. Pilot with a few people and a small project, and measure cost and time saved before widening.
  2. Commit a shared baseline: a short AGENTS.md (including code review rules), safe defaults in .codex/config.toml, a few rules, and the skills your team actually repeats.
  3. Choose an identity for automation: API key, access token or a service account, and keep it in a secret store with a rotation date.
  4. Decide the guardrails: which sandbox and approval choices, which MCP servers, which plugins, and whether event-triggered scheduled tasks are allowed. Write them as requirements.toml and test on one machine.
  5. Set up cost visibility before launch: analytics, spend controls and the right billing view for your plan.
  6. Automate carefully: start with a read-only review job before any job that writes, and keep humans in the merge step.
  7. Review and prune monthly: AGENTS.md, rules, skills, plugins and tokens all drift.

12. Wrap-up and glossary

  1. codex exec turns Codex into a command-line tool with text or JSON output, read-only by default.
  2. Unattended runs need explicit, narrow sandbox settings and keys kept away from repository code.
  3. The GitHub Action and @codex review bring Codex to pull requests, with humans reviewing the result.
  4. Teams share conventions in committed files and enforce policy with requirements.toml.
  5. Give automation its own identity, track cost from day one, and keep keys out of repositories.

Part 6 covered extending Codex with skills, MCP servers and plugins, which you can now share with a team. Part 8, the last in the series, steps back from code: using Codex and ChatGPT for everyday work, plus a first-week learning plan and where to keep learning.

TermIn plain words
codex execRun Codex once without a conversation and print the final answer.
JSONLJSON Lines: one JSON object per line, used for the --json event stream.
SandboxThe technical limit on what commands Codex can touch.
Approval policyThe rule for when Codex must stop and ask you.
RunnerThe machine (for example a GitHub-hosted one) that executes a CI job.
WorkflowA GitHub Actions file describing when and how a job runs.
Prompt injectionHidden instructions in text that Codex reads, trying to steer it.
requirements.tomlAn admin-enforced policy file that users cannot override.
Access tokenA workspace credential scoped to Codex, for scripts and CI.
Service accountA non-human workspace identity for automation.
MDMMobile device management: tools that push policy to company computers.
SDKA code library for controlling Codex from your own program.

13. Links and official docs

Codex changes quickly. This series was checked against the official documentation on 18 October 2026; always confirm details on the official pages.

← Back to all writing