Codex · Advanced · Part 7 of 8
Automation and teams: scripts, CI, pull request reviews, and team-wide setup
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.
codex exec "prompt"runs Codex once, non-interactively. Progress goes tostderr, the final answer goes tostdout, and--jsongives you an event stream.- By default
codex execruns 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 reviewon 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 withrequirements.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
- Non-interactive mode: codex exec
- Running unattended safely
- Scripts, pipes and codex review
- Scheduled tasks
- The Codex GitHub Action
- Automatic code review of pull requests
- For builders: the SDK and the App Server
- Setting up a team
- For admins: requirements, tokens and oversight
- A security checklist
- A rollout checklist
- Wrap-up and glossary
- 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
- Use it for: pipelines (CI, pre-merge checks, scheduled jobs), output you pipe into other tools, and runs with explicit, pre-set sandbox and approval settings.
- No saved session: add
--ephemeralif you do not want session files written to disk. - Git repository required: Codex wants to run inside a Git repository, to prevent destructive changes.
--skip-git-repo-checkoverrides that when you are sure the environment is safe. - Required MCP server: if you mark an MCP server
required = trueand it fails to start,codex execexits with an error instead of carrying on without it (Part 6).
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.
| Flag | What it does |
|---|---|
--sandbox, -s | Sandbox policy for commands Codex generates: read-only, workspace-write or danger-full-access. Defaults to your configuration. |
--json | Print newline-delimited JSON events instead of formatted text. |
--output-last-message, -o | Write the final message to a file (it is still printed to stdout). |
--output-schema | Path to a JSON Schema file describing the shape of the final answer. |
--model, -m | Override the configured model for this run. |
--cd, -C | Set the workspace root before running the task. |
--profile, -p | Layer a profile file on top of your base user config. |
-c, --config key=value | Inline configuration override for this run (repeatable). |
--ephemeral | Run without persisting session files. |
--ignore-user-config | Do not load $CODEX_HOME/config.toml. Authentication still uses CODEX_HOME. |
--ignore-rules | Do not load user or project .rules files for this run. |
--approve-for-me | Use automatic approval review with on-request approvals and the workspace-write sandbox. Conflicts with --sandbox and --yolo. |
--yolo | Short for --dangerously-bypass-approvals-and-sandbox. No approvals, no sandbox. Only inside an isolated runner. |
--skip-git-repo-check | Allow 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:
{
"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.
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:
| Route | How | Notes from the docs |
|---|---|---|
| GitHub Actions | Use 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 key | CODEX_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 token | CODEX_ACCESS_TOKEN (Business and Enterprise workspaces) | Authenticates as a ChatGPT workspace identity. See section 9. |
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:
| Goal | Setting | Effect |
|---|---|---|
| Analyse only | Nothing extra (the default), or --sandbox read-only | Codex can read files and run commands inside the read-only sandbox. |
| Let it edit files | --sandbox workspace-write | Read files, edit inside the workspace and run commands there. Network access stays off by default. |
| Edit, with approval requests reviewed automatically | --approve-for-me | Automatic approval review, on-request approvals, workspace-write sandbox. |
| Broad access | --sandbox danger-full-access | No filesystem restriction. Use only in a controlled environment such as an isolated CI runner or container. |
| No protection at all | --yolo | Bypasses 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"
- Least privilege: start read-only, move to
workspace-writeonly when the job must edit, and keepdanger-full-accessand--yolofor isolated runners. - Set the sandbox on purpose. Do not rely on whatever a machine's config file says; pass
--sandboxor use--ignore-user-configso 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:
| Option | Reviews |
|---|---|
--uncommitted | Staged, unstaged and untracked changes |
--base BRANCH | Changes against a base branch |
--commit SHA | The changes introduced by one commit (add --title to set the title in the summary) |
PROMPT | Custom 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.
- Where you manage them: in ChatGPT on the web or in the ChatGPT desktop app. The CLI and the IDE extension do not provide the Scheduled management screen, but they are good places to prepare and test the prompt, skill or script first.
- Desktop app: tasks can work with local projects and run in the project folder or in an isolated Git worktree. Keep the computer on and the app running when a task needs local files. Worktrees keep scheduled changes apart from your unfinished work; running in the local project can modify files you are still editing. Archive runs you no longer need, because frequent schedules can create many worktrees.
- Web: tasks can use uploaded files, connected tools, skills and plugins, but they cannot work in a folder on your computer and keep no local folder between runs.
- Standalone or in a chat: a standalone task starts a fresh chat each run. A task inside a chat returns to that chat and its context, which suits checking a long-running operation or continuing a review loop.
- Schedules: use the custom schedule controls, or for an advanced schedule edit the recurrence rule (RFC 5545 RRULE), for example
RRULE:FREQ=MONTHLY;BYMONTHDAY=1;BYHOUR=9;BYMINUTE=0. - Event triggers: on eligible plans, ChatGPT on the web and mobile can run a task when a supported Gmail, Slack or GitHub event happens (for GitHub, pull request activity that you can filter). One task can use several event triggers but cannot combine them with a time schedule. Admins in managed workspaces can control this with the Allow event-triggered scheduled tasks permission.
- Skills: use a skill to define what the task does, and invoke it in the prompt (in the desktop app, with
$skill-name) when you do not want automatic tool selection.
- 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
- Store your OpenAI key as a GitHub secret, for example
OPENAI_API_KEY. - Use a Linux or macOS runner. On Windows you must set
safety-strategy: unsafe. - Check out your code before the action, so Codex can read the repository.
- Provide the task with either
prompt(inline text) orprompt-file(a file in the repo), not both.
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.
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.
Action inputs worth knowing
| Input | What it does |
|---|---|
prompt / prompt-file | The task, inline or from a file such as .github/codex/prompts/. |
codex-args | Extra CLI flags, as a JSON array (["--ephemeral"]) or a shell string (--profile ci). Pass --output-schema here for structured output. |
model, effort | Pick the model and reasoning effort; leave empty for defaults. |
sandbox | workspace-write, read-only or danger-full-access. Choose the narrowest that lets the task finish. |
output-file | Save the final message to disk. The action also exposes it as the final-message output. |
codex-version | Pin a CLI release. Blank means the latest. |
safety-strategy | Default 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-bots | Who 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:
- Trigger a follow-up workflow (
workflow_run) when the workflow named “CI” completes with a failure. - Check out the failing commit with read-only permission and without persisting credentials.
- Run setup commands first, such as installing dependencies, before the Codex step, so they never see the API key.
- 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.
- Save the result as a patch artifact (
git diffuploaded as an artifact). - 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.
- Connect your GitHub repository to Codex. You need push or admin permission for the repository's settings.
- Open Codex settings (code review) at
chatgpt.com/settings/code-review, choose the repository and turn on Automatic review under Review code. - Or ask on demand: comment
@codex reviewon 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.
## 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
- GitLab merge requests: there is a similar review integration. The docs describe it as a beta available on all ChatGPT plans, running in Codex cloud. Self-managed or Dedicated GitLab needs workspace-admin setup. See the official page for the steps.
- Slack: mention
@ChatGPTin a channel. If your workspace has Cloud delegation enabled, repository work can be sent to a Codex cloud task and the result returned to the thread. A workspace owner or admin sets up the Slack app first. - Linear: assign an issue to Codex or mention
@Codexin a comment, and Codex creates a cloud chat and replies with progress. It is available on paid plans, and on Enterprise an admin must turn it on.
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:
| Option | What it is | Use it for |
|---|---|---|
| Codex SDK | A 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 Server | The 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:
| What | Where | Committed? | Who it affects |
|---|---|---|---|
| Project conventions, commands, gotchas, review rules | AGENTS.md (nested files for subfolders) | Yes | Everyone on the repository |
| Shared defaults (model, approvals, sandbox, MCP servers) | .codex/config.toml in the repo | Yes | Everyone who trusts the project |
| Command rules (what may run outside the sandbox) | .codex/rules/*.rules | Yes | Everyone who trusts the project |
| Shared workflows and know-how | Skills (Part 6) | Yes | Everyone |
| 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:
- AGENTS.md is layered. Codex reads your global file in
~/.codexfirst, then walks from the project root down to your current folder, one file per directory. Files closer to where you work come later, so they win. Combined size stops atproject_doc_max_bytes(32 KiB by default). - Project config only loads for trusted projects. If a project is untrusted, Codex skips its
.codex/layers, including config, hooks and rules. Your user and system config still load. - Rules need care. A
prefix_ruledecides whether a command may run outside the sandbox:allow,promptorforbidden, and when several rules match the most restrictive one wins. Rules are marked experimental in the docs. Test them withcodex execpolicy checkbefore relying on them.
Habits that work, mostly from the docs and Parts 2 and 3:
- Treat these files like code. Review changes in pull requests, because a bad rule or default affects every future session.
- Turn mistakes into lines. When Codex gets something wrong that a teammate would also get wrong, add one line to
AGENTS.md. The same goes for a point reviewers keep repeating, which can become a code review rule. - Allow safe commands with rules, and use
forbiddenwith a justification that names an alternative for risky ones. - Pick a default sandbox and approval setting and write down when a read-only run is enough and when to review manually.
- Standardise through the repository. The admin guide suggests checking configuration, rules and skills into
.codexor.agentsso everyone gets the same defaults. It also says repository configuration can supply defaults but cannot grant workspace, model, API or connected-system access.
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:
| Piece | What it is |
|---|---|
| Requirements | Admin-enforced constraints, in a requirements.toml file. Users cannot override them. |
| Configuration defaults | System or cloud-managed config.toml settings that users can still change. |
| Legacy managed defaults | managed_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):
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:
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:
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:
- System
requirements.toml:/etc/codex/requirements.tomlon Linux and macOS, or%ProgramData%\OpenAI\Codex\requirements.tomlon Windows. - Requirements delivered in the cloud, from Agent Security in the Admin Console, when a user signs in with ChatGPT on a supported plan.
- Legacy
managed_config.tomlfields that the client reinterprets as requirements. - 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 token | Service account | |
|---|---|---|
| Represents | The workspace member who created it | A non-human workspace identity, for example release-automation |
| Created | In the admin console under Access tokens | Under Service accounts; a token is then created from the account's detail page |
| Good for | codex exec jobs, local scripts and trusted app-server automation | CI 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:
- Choose a finite expiry (for example 7, 30, 60 or 90 days) and copy the token immediately, because you cannot view it again. Store it in a secret manager or CI secret store.
- Rotate by creating a new token, updating the secret, running a smoke test, then revoking the old one.
- Use access tokens only on trusted runners. Public CI, forked pull requests and shared machines can expose them.
- Create tokens per workflow owner, not one shared person's token for unrelated teams.
- Service-account tokens need Codex CLI 0.142.0 or later. Workspace owners and admins create service accounts and can share them with people or groups as User, Configure or Manager.
- If a Platform API key works for your automation, the docs say to keep using API key auth.
Seeing usage and cost
Where to look depends on how your team pays:
| Question | Where the docs point |
|---|---|
| Interactive usage and Codex analytics | Workspace analytics in the admin console |
| Programmatic, aggregated reporting | The Analytics API |
| Audit and investigation records | The Compliance API |
| Spend on eligible Codex activity under a workspace plan | ChatGPT usage limits and spend controls (user guardrails, workspace-level spend controls, notifications, depending on plan) |
| Spend on the OpenAI API Platform | Platform 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.
- Least privilege. Read-only by default,
workspace-writewhen it must edit, full access only in an isolated runner or container. Give the workflow token only the permissions the job needs (for examplecontents: 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.jsonand 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-usersandallow-botsdeliberately. - 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.tomlso 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:
- Pilot with a few people and a small project, and measure cost and time saved before widening.
- 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. - Choose an identity for automation: API key, access token or a service account, and keep it in a secret store with a rotation date.
- 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.tomland test on one machine. - Set up cost visibility before launch: analytics, spend controls and the right billing view for your plan.
- Automate carefully: start with a read-only review job before any job that writes, and keep humans in the merge step.
- Review and prune monthly:
AGENTS.md, rules, skills, plugins and tokens all drift.
12. Wrap-up and glossary
codex execturns Codex into a command-line tool with text or JSON output, read-only by default.- Unattended runs need explicit, narrow sandbox settings and keys kept away from repository code.
- The GitHub Action and
@codex reviewbring Codex to pull requests, with humans reviewing the result. - Teams share conventions in committed files and enforce policy with
requirements.toml. - 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.
| Term | In plain words |
|---|---|
codex exec | Run Codex once without a conversation and print the final answer. |
| JSONL | JSON Lines: one JSON object per line, used for the --json event stream. |
| Sandbox | The technical limit on what commands Codex can touch. |
| Approval policy | The rule for when Codex must stop and ask you. |
| Runner | The machine (for example a GitHub-hosted one) that executes a CI job. |
| Workflow | A GitHub Actions file describing when and how a job runs. |
| Prompt injection | Hidden instructions in text that Codex reads, trying to steer it. |
requirements.toml | An admin-enforced policy file that users cannot override. |
| Access token | A workspace credential scoped to Codex, for scripts and CI. |
| Service account | A non-human workspace identity for automation. |
| MDM | Mobile device management: tools that push policy to company computers. |
| SDK | A 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.
- Non-interactive mode (codex exec), including the CI auto-fix example
- CLI command reference
- Codex GitHub Action and the openai/codex-action repository, with its security guidance
- Maintain Codex account auth in CI/CD (advanced)
- Scheduled tasks
- Review GitHub pull requests with Codex, Slack and Linear
- Codex SDK and App Server
- Custom instructions with AGENTS.md, Config basics and Rules
- Agent approvals and security
- Admin rollout guide, Managed configuration, Access tokens, Service accounts, Usage limits and spend controls and Governance