Skip to content

Team collaboration and shared configuration in Codex

A shared Codex team setup is four committed artifacts: AGENTS.md for conventions, .codex/config.toml for defaults such as sandbox, approval policy and MCP servers, .codex/rules/*.rules for commands allowed outside the sandbox, and .agents/skills/ for repeatable procedures. Codex loads the project layer only in a trusted directory, and a CI job proves the files still work.

This page is for the tech lead who has to make Codex behave the same for eight people, and for the developer asked to set it up. The symptom is familiar: one teammate runs with --dangerously-bypass-approvals-and-sandbox, another approves every ls by hand, a third has five MCP servers nobody else uses. A shared prompt then gives three different results, and nobody can say whether the prompt or the setup was at fault. Commands and keys below were checked against Codex CLI 0.157.1 on 2026-09-26.

  • A committed project layer that overrides personal defaults, and a clear line between what the team shares and what stays personal
  • Command rules that carry their own tests (match and not_match examples) and a way to check them without starting a session
  • Skills that turn a proven prompt into a $pr-ready anyone on the team can run
  • A one-session onboarding that ends with evidence, not a feeling that “it seems to work”
  • A CI job that fails when the shared config drifts, so nobody has to inspect laptops

Organization-wide limits that nobody may override belong in requirements.toml, covered in Codex enterprise governance. The order of the whole rollout is on the Codex for teams hub.

Which Codex files does a team commit, and which stay personal?

Section titled “Which Codex files does a team commit, and which stay personal?”
ArtifactPathCommitted?Holds
ConventionsAGENTS.md (root and per package)YesBuild and test commands, code rules, review rules
Project config.codex/config.tomlYesapproval_policy, sandbox_mode (or the beta default_permissions, never both), web_search, [mcp_servers.*]
Command rules.codex/rules/*.rulesYesprefix_rule() decisions: allow, prompt, forbidden
Skills.agents/skills/<name>/SKILL.mdYesProcedures invoked as $<name>
OwnershipCODEOWNERS entries for the four paths aboveYesWho approves a change to the team’s agent setup
Personal config$CODEX_HOME/config.toml (default ~/.codex/)NoPersonal preferences, credential helpers, notify
Profiles$CODEX_HOME/<name>.config.toml, selected with --profile <name>NoOpt-in variants, such as a cheaper model for quick work
Enforced limits/etc/codex/requirements.toml, MDM or a managed cloud bundleAdmin-ownedConstraints no layer below can loosen

The split is not only a convention. In 0.157.1 Codex refuses a handful of keys from the project layer because the repository’s contents should not decide where credentials go or which local commands run: model_provider, model_providers, notify, profile, profiles, otel, openai_base_url and chatgpt_base_url, among others (Codex source, PROJECT_LOCAL_CONFIG_DENYLIST). A profile therefore cannot be shipped in the repository; each developer creates it in $CODEX_HOME.

  1. Write the project config. Keep it small. Every key you set here overrides every developer’s personal choice.

    # .codex/config.toml -- shared team defaults
    approval_policy = "on-request"
    sandbox_mode = "workspace-write"
    # "disabled" suits repositories with sensitive code
    web_search = "disabled"
    [mcp_servers.linear]
    url = "https://mcp.linear.app/mcp"

    sandbox_mode is the legacy sandbox system. OpenAI prefers permission profiles (beta, CLI 0.138.0 or later), selected with default_permissions = ":workspace"; pick one system per layer, because OpenAI says the two “do not compose”. This page keeps sandbox_mode because profiles are still in beta, and Codex enterprise governance covers enforcing either one from requirements.toml.

    Leave model unset. The team then runs on Codex’s own default, GPT-6 Astra as of 2026-09-26 (bundled default since CLI 0.153.4), and moves with it when OpenAI changes the default, instead of staying pinned to an older model. Current models and prices live on the models hub.

  2. Add command rules with tests. Rules are Starlark files. A list inside pattern means “any of these at this position”, and the match and not_match examples are checked when the file loads, so a rule that does not do what its author thinks fails immediately.

    .codex/rules/team.rules
    prefix_rule(
    pattern = [["npm", "pnpm"]],
    decision = "allow",
    match = ["pnpm test", "npm run lint"],
    )
    prefix_rule(
    pattern = ["git", ["push", "reset"]],
    decision = "prompt",
    justification = "Pushes and resets change shared history. Confirm first.",
    match = ["git push origin main", "git reset --hard HEAD~1"],
    not_match = ["git status", "git diff"],
    )
    prefix_rule(
    pattern = ["rm", "-rf"],
    decision = "forbidden",
    justification = "Use git clean -n to preview deletions instead.",
    match = ["rm -rf dist"],
    )

    When several rules match one command, the most restrictive decision wins. Check a command against the file without starting a session:

    Terminal window
    codex execpolicy check --rules .codex/rules/team.rules git push origin main
    # {"matchedRules":[...],"decision":"prompt"}

    codex execpolicy does not appear in codex --help in 0.157.1, but it runs there and exits non-zero when a match example fails. Restart Codex after you edit a rules file.

  3. Split AGENTS.md by scope. The root file carries what is true everywhere; a package file carries only what differs there. Codex concatenates the chain from the repository root down to the working directory and stops at 32 KiB by default (project_doc_max_bytes), so anything repeated from the root spends the budget twice.

    AGENTS.md
    ## Commands
    - Install: pnpm install --frozen-lockfile
    - Verify: pnpm lint && pnpm typecheck && pnpm test
    ## Rules
    - New endpoints need an integration test in tests/integration/
    - Schema changes need a migration in migrations/; never edit an applied one
    ## Done means
    - The Verify command passes and the PR description lists what was not tested

    How to prune and measure the chain is covered in optimizing AGENTS.md and skills for Codex.

  4. Turn proven prompts into skills. A skill is a directory with a SKILL.md. Codex scans .agents/skills/ in every directory from the working directory up to the repository root, plus ~/.agents/skills/ for personal skills and admin-deployed skills (see Codex enterprise governance). Skills load even in an untrusted checkout, unlike the project config.

    ---
    name: pr-ready
    description: Prepare the current branch for a pull request. Use when the user
    asks to finish, wrap up, or open a PR.
    ---
    1. Run the Verify command from AGENTS.md. Fix failures in source, never by
    editing or skipping tests.
    2. Run `git diff --stat origin/main...HEAD` and list every file you changed.
    3. Write the PR description: what changed, why, how it was tested, and
    what was NOT tested.
    4. Stop and report if Verify still fails after two attempts.

    The file lives at .agents/skills/pr-ready/SKILL.md, and the name must match the directory. Anyone who clones the repository runs it as $pr-ready; /skills lists what loaded. When a skill needs to reach other repositories too, package it as a plugin in a private team marketplace.

  5. Protect the setup with CODEOWNERS. A change to .codex/, .agents/skills/ or any AGENTS.md changes how every teammate’s agent behaves, so it needs the same named reviewer as a CI change.

    # .github/CODEOWNERS
    /.github/ @acme/dev-platform
    /.codex/ @acme/dev-platform
    /.agents/skills/ @acme/dev-platform
    AGENTS.md @acme/dev-platform

From lowest to highest precedence in 0.157.1: built-in defaults, /etc/codex/config.toml, a managed cloud bundle, $CODEX_HOME/config.toml, the selected profile file, then the project layers (.codex/config.toml in the working directory, its parents and the repository root), and finally runtime overrides such as -c key=value, --sandbox or the model picker. requirements.toml sits outside that stack: it constrains what any layer may choose.

Two consequences matter for a team. The committed project file beats a personal profile, so --profile cannot quietly loosen the team’s sandbox. And the project layers load only when the directory is trusted: in an untrusted checkout Codex skips .codex/config.toml, disables the project’s rules (.codex/rules/) and hooks, and since 0.150.0 also ignores the project’s AGENTS.md. Skills from .agents/skills/ still load.

Onboard a new developer to the team’s Codex setup in one session

Section titled “Onboard a new developer to the team’s Codex setup in one session”
  1. Install the CLI with npm install -g @openai/codex (or brew install --cask codex); the other surfaces are in installing Codex.
  2. Run codex login, choose the team’s ChatGPT workspace, then confirm with codex login status.
  3. Clone the repository and start codex in it. Accept the trust prompt: if you decline it, the committed .codex/config.toml, .codex/rules/ and project hooks stay disabled and AGENTS.md does not load. Skills load either way, so a visible $pr-ready does not prove trust.
  4. Authenticate the shared MCP servers that need OAuth, for example codex mcp login linear.
  5. Run codex doctor for installation, auth and reachability. In the TUI, run /debug-config to see each config layer and where every requirement came from, then /status.
  6. Confirm what the model actually receives, without calling it. codex debug prompt-input | grep -c "pr-ready" returns a non-zero count when the team skill loaded, trusted or not; codex debug prompt-input | grep -c "Verify: pnpm lint" returns 0 when the project is marked untrusted (you declined the trust prompt), because that line comes from AGENTS.md; after you accept the prompt it returns a non-zero count.
  7. Paste the “check a new teammate’s Codex setup” prompt above, then run $onboard if the team ships an orientation skill.

The exit criterion is the table from step 7 with no mismatches. That is evidence the tech lead can accept in a pull request comment, which “I installed it” is not.

How do you prove the shared Codex setup holds without watching every session?

Section titled “How do you prove the shared Codex setup holds without watching every session?”

Treat the shared layer like code: a CI job checks it on every pull request, and the agent’s own output goes through the same gates as a human’s.

.github/workflows/codex-config.yml
name: codex-config
on:
pull_request:
paths: ['.codex/**', '.agents/skills/**', '**/AGENTS.md']
permissions:
contents: read
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
persist-credentials: false
- uses: actions/setup-node@v7
with:
node-version: '22'
- run: npm install -g @openai/codex@0.157.1
- name: Rules load and still decide what we expect
run: |
args=()
for f in .codex/rules/*.rules; do args+=(--rules "$f"); done
codex execpolicy check "${args[@]}" rm -rf / | grep -q '"decision":"forbidden"'
codex execpolicy check "${args[@]}" git push origin main | grep -q '"decision":"prompt"'
- name: AGENTS.md chain fits the 32 KiB default
run: |
bytes=$(find . -name AGENTS.md -not -path '*/node_modules/*' -exec cat {} + | wc -c)
echo "AGENTS.md total: $bytes bytes"
test "$bytes" -le 32768
- name: Every skill's name matches its directory
run: |
for dir in .agents/skills/*/; do
name=$(basename "$dir")
grep -qx "name: $name" "${dir}SKILL.md" || { echo "${dir}: name must be $name"; exit 1; }
grep -q '^description: ' "${dir}SKILL.md" || { echo "${dir}: missing description"; exit 1; }
done

The job needs no secret and runs no model: it parses the rules (which executes their match examples), asserts two decisions that must never change, and checks the context budget and skill metadata. The size check adds up every AGENTS.md in the repository, which is stricter than the chain Codex loads for one directory. Adjust the two asserted commands to your own rules.

On the pull_request trigger GitHub runs this workflow from the pull request’s own merge ref, so a pull request that edits .codex/ can also edit the job that checks it. The check only binds when /.github/ is under CODEOWNERS too (as in step 5) and branch protection or a ruleset requires that review.

CheckEvidenceWho signs off
The shared layer is validcodex-config job green on the pull requestCODEOWNERS for .codex/
Everyone runs the same setupTwo developers’ /status in the same repository shows the same sandbox, approval policy and modelTech lead
New teammates are set upThe onboarding table with no mismatches, pasted in the onboarding issueTech lead
Agent work meets the barThe same CI, tests and required review as human pull requests, plus codex review --base main before opening oneRepository owner

How to scale the review side without it becoming the bottleneck is in reviewing Codex work and, for the team process, running the review queue.

Keep team usage predictable with shared defaults

Section titled “Keep team usage predictable with shared defaults”
  • Leave the model to Codex’s default; cheaper models go in personal profiles. A developer who wants a lighter model for exploration creates $CODEX_HOME/quick.config.toml with model = "gpt-6-luna" (or gpt-6-sol) and runs codex --profile quick. The project layer still wins on sandbox and approvals.
  • Tune effort before switching model. Codex runs GPT-6 Astra at low reasoning effort by default. When results fall short, raise effort for one session in /model, or set model_reasoning_effort = "medium" in a personal profile file, before you reach for a different model.
  • Pay context once, not per session. Every AGENTS.md byte costs context on every session, and each MCP server adds tool metadata (tool search defers the full definitions). Remove servers the team does not use, and add enabled_tools = [...] to a server entry when only a few of its tools matter.
  • Check real usage, not estimates. /usage shows account usage and limit resets, and /status shows the current session. Credits, plans and dashboards are covered in Codex cost management.

When the shared Codex setup breaks, and how to recover

Section titled “When the shared Codex setup breaks, and how to recover”
  • One developer gets different results from everyone else. Check trust first: an untrusted checkout drops .codex/config.toml, the project rules and hooks, and the project AGENTS.md, while skills still load and make the setup look complete. Then look for -c overrides in a shell alias, the selected --profile, and /debug-config for the layer that set the odd value.
  • A key in .codex/config.toml has no effect. It may be one of the keys Codex refuses from the project layer, such as profile, model_provider or notify. Move it to personal config or, if it must hold for everyone, to requirements.toml.
  • A rules file stops Codex from starting a command it used to allow. Several rules matched and the most restrictive won. Run codex execpolicy check with every rules file the developer has, including ~/.codex/rules/, to find the rule that decided.
  • Instructions at the bottom of AGENTS.md are ignored. The chain passed 32 KiB and was cut. Move procedures into skills, delete what the root already says, and only then consider raising project_doc_max_bytes.
  • A new skill does not appear. Check that the directory sits under .agents/skills/ between the working directory and the repository root, that name matches the directory, and that the change is pushed; then restart Codex and check /skills.
  • A teammate cannot reach a shared MCP server. The entry is shared but the login is personal: run codex mcp login <name>, and keep tokens in environment variables (bearer_token_env_var), never in the committed file.
  • Someone wants to loosen the sandbox “just for this repo”. The project layer can do it, which is why CODEOWNERS guards it. If it must never happen, enforce it with allowed_sandbox_modes in requirements.toml instead.

Where to go next with Codex team workflows

Section titled “Where to go next with Codex team workflows”