Opinionated defaults, documentation, and workflows for Codex CLI at Trail of Bits. Covers sandboxing, permissions, exec policy rules, hooks, skills, MCP servers, and usage patterns we've found effective for security audits, development, and research.
Also see: claude-code-config · skills · skills-curated · claude-code-devcontainer · dropkit · nono-config
First-time setup:
git clone git@github.com:trailofbits/codex-config.git
cd codex-config
codexThen inside the session, run $install-codex-config. It walks you through installing each component, detects what you already have, and self-installs the skill so future runs work from any directory. Run it again after updates.
- Read These First
- Initial Checklist
- Operating Loop
- Prerequisites
- Shell Setup
- Settings
- Global AGENTS.md
- Per-invocation overrides
- Token tracking
- Operational playbook
- Untrusted-repo posture
- Containerized runs
Before configuring anything, read these to understand why this setup works the way it does:
- Codex CLI docs -- the official primer; config schema, sandbox model, exec policy, hooks, skills, and CLI flags
- GPT-5.6 model guidance: model tiers, migration guidance, reasoning effort, and prompt design
- Build skills: skill discovery, implicit invocation, and progressive disclosure
- Codex for Knowledge Work -- Every's guide to using Codex as a workspace for knowledge work, not just code
- Codex-maxxing -- Jason Liu on durable threads, memory, steering, browser/computer use, goals, and review surfaces
- AI-assisted coding for teams that can't get away with vibes -- Nilenso's playbook for teams integrating AI tools with high standards
- My AI Skeptic Friends Are All Nuts -- Thomas Ptacek on why dismissing LLMs for coding is a mistake
- Harness engineering: leveraging Codex in an agent-first world -- Ryan Lopopolo on how OpenAI's team shipped a million-line product with zero human-written code, and what that implies for how you structure repos, AGENTS.md files, and review loops
Use this checklist after the first install and when starting in a new codebase:
- Run
codex doctor --summary; fix install, auth, MCP, or sandbox issues before long runs. - Add or customize the project's
AGENTS.md. - Configure Context7 and Exa if the work needs current docs, web search, or code search.
- Install the Trail of Bits skills you expect to use.
- Confirm the sandbox and approval policy with
codex doctororcodex sandbox. - Decide whether the run needs the default model or a separate API-key/cyber identity.
- Start with one bounded, verifiable task; use
/goalif it should survive multiple turns. - Run the project's normal tests/scanners once and record baseline failures before patching.
The Trail of Bits Codex loop is:
- Connect the tools and source material the task actually needs.
- Contextualize with
AGENTS.md, project docs, known findings, and explicit constraints. - Delegate or collaborate based on risk: delegate repeatable, objective, checkable work; collaborate on ambiguous, judgment-heavy, or exploratory work.
- Review where the artifact will live: inspect diffs in Git, PRs in GitHub, documents in their editor, and metrics against the source of truth.
- Compound the useful parts into skills, workflows, scripts, checklists, or project instructions so the next run starts with more context.
Install Codex with Homebrew:
brew install codex
codex --version
codex doctor --summaryDo not install Codex with npm. Trail of Bits enforces a 7-day cooldown on npm packages, so npm install -g @openai/codex will be behind upstream. If your install looks stale or which -a codex shows an npm install ahead of Homebrew, remove the npm copy first:
which -a codex
npm uninstall -g @openai/codex
brew install codex
codex updateThe Homebrew package tracks stable releases directly. codex update is still useful after a stale install cleanup because it verifies the running CLI path.
Use Ghostty. It uses native Metal GPU rendering, so it handles the high-volume text output from long Codex sessions without lag or memory bloat. Cmd+D / Cmd+Shift+D give you split panes for running Codex alongside a dev server, and it doesn't crash during extended autonomous runs.
brew install --cask ghosttymacOS only. On Linux, see the Ghostty install docs. No Windows support yet -- use WezTerm there.
Install core tools via Homebrew:
brew install jq ripgrep fd ast-grep shellcheck shfmt \
actionlint zizmor macos-trash node@24 pnpm uvPython tools (via uv):
uv tool install ruff
uv tool install ty
uv tool install pip-auditRust toolchain:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
cargo install prek worktrunk cargo-deny cargo-carefulNode tools (also subject to the 7-day cooldown):
npm install -g oxlint agent-browserAdd to ~/.zshrc:
alias codex-cyber='codex -m gpt-5.6-cyber --config model_reasoning_effort="xhigh"'gpt-5.6-cyber is for explicitly authorized security research. It requires separate Trusted Access
for Cyber approval and provisioning for the identity, organization or workspace, project, model,
and product surface in use. Model selection does not expand the systems or actions authorized for a
task.
Official docs: config reference.
Copy config.toml to ~/.codex/config.toml (or merge entries into your existing file). If you already have a config, keep your authentication, project trust, and any local model overrides.
mkdir -p ~/.codex
cp config.toml ~/.codex/config.tomlThe template sets:
model = "gpt-5.6-sol": the shipped default uses the explicit flagship GPT-5.6 slug.review_modelremains unset, so/reviewfollows the active session or profile model.model_reasoning_effort = "xhigh"withplan_mode_reasoning_effort = "xhigh": normal and Plan work use extra-high effort.model_verbosityremains unset so the model preset controls response length.personality = "pragmatic"andmodel_reasoning_summary = "auto": use the pragmatic communication preset and automatic reasoning summaries.approval_policy = "on-request"-- Codex asks before stepping outside the sandbox; see Sandboxing for the other valuesapprovals_reviewer = "auto_review"-- routes eligible approval prompts through Codex's automatic reviewerdefault_permissions = "tob-workspace"-- selects the custom Trail of Bits sandbox profile: broad local reads, workspace/temp writes, no command network, deny-read rules for credentials and crypto walletsweb_search = "cached"-- Codex's built-in web search caches responses to reduce token spend on repeated queriesproject_doc_fallback_filenames = ["CLAUDE.md"]-- migration aid for repos that haven't renamedCLAUDE.mdtoAGENTS.md; lets Codex still read the filecli_auth_credentials_store = "keyring"+mcp_oauth_credentials_store = "keyring"-- macOS Keychain (Linux: secret-service)[features] goals = true-- enables the /goal loop[tui]-- colored footer showing model, reasoning, context remaining, current directory, Git branch, and fast mode- Hooks wired to the three shipped scripts -- see Hooks
Official docs: custom instructions with AGENTS.md.
The global AGENTS.md at ~/.codex/AGENTS.md sets default instructions for every Codex session. In this repository, the installable template is global-agents.md; the root AGENTS.md is only for contributors working on this config repo.
The global template contains only rules that apply across tasks: instruction precedence, current sources, untrusted input, scope and approvals, preservation of existing behavior, direct communication, and relevant validation. Development, durable writing, and security-research detail live in implicitly invoked skills so unrelated sessions do not pay for those instructions.
Copy the template into place:
cp global-agents.md ~/.codex/AGENTS.mdCodex builds the AGENTS chain once when a run starts. It reads the global file, then walks from the
project root down to the directory where Codex was launched; files closer to that launch directory
take precedence. A nested AGENTS.md is not a dynamic per-file router for files elsewhere in the
tree. Launch Codex from the relevant subtree when its nested instructions should apply. Run
/status to inspect the loaded chain and any configured CLAUDE.md fallback.
For an example of a project-level AGENTS.md, see crytic/slither/CLAUDE.md -- the same content works under either name since project_doc_fallback_filenames is set.
Official docs: permissions, agent approvals & security, rules.
Codex sandboxing has two controls you need to understand:
default_permissionsselects what local commands can read, write, and access over the network.approval_policycontrols when Codex may ask to do more than the sandbox allows.
The Trail of Bits default is:
default_permissions = "tob-workspace"
approval_policy = "on-request"
approvals_reviewer = "auto_review"That profile gives Codex broad local reads, workspace/temp writes, no command network, and deny-read rules for common credential stores, wallets, .env, *.pem, and *.key. The practical effect: Codex can inspect ordinary local files and edit the repo without prompting, while secrets, network use, and writes outside the workspace require approval or a different profile.
Do not set sandbox_mode in this config. If it appears in any active config layer, Codex uses that setting instead of default_permissions.
Use :danger-full-access or approval_policy = "never" only inside an external sandbox such as a devcontainer or disposable VPS. The shared default should stay interactive and sandboxed.
Rules and hooks are the command layer around the sandbox. rules/default.rules classifies unsandboxed command requests; hooks catch footguns even when a command stays inside the sandbox. The defaults block recursive force deletion, disk-formatting commands, force-push/reset mistakes, direct pushes to main/master, wrong package managers, and selected audit-log-worthy mutations.
Install:
mkdir -p ~/.codex/rules
cp rules/default.rules ~/.codex/rules/default.rulesWARNING: Only enable YOLO mode in a sandbox such as a virtual machine or disposable cloud machine. Understand the risks of Codex running arbitrary commands.
--yolo lets Codex run any command without approval or sandboxing. It is a hidden alias for --dangerously-bypass-approvals-and-sandbox (approval policy never, no sandbox), so codex --help shows the long form rather than --yolo.
YOLO mode drops sandboxing and approvals, but it still evaluates installed rules and hooks. With this configuration installed, command requests are checked against rules/default.rules first, so a forbidden rule still rejects the command and PreToolUse/PostToolUse hooks still run. One sharp edge: never approvals leave a prompt rule with nothing to approve it, so it becomes a hard rejection -- sudo, for instance, is blocked outright rather than prompted. For unrestricted execution, do not install this repository's rules or hooks.
Use codex sandbox to test profile changes after installing the config:
codex sandbox macos --permissions-profile tob-workspace -C . -- cat ~/.ssh/id_rsa
codex sandbox macos --permissions-profile tob-workspace -C . -- git statusFor full read+write isolation:
- trailofbits/claude-code-devcontainer -- devcontainer with no host filesystem access (works for Codex with minor adjustments)
- trailofbits/dropkit -- disposable DigitalOcean droplets via Tailscale; create, ssh in, run Codex, destroy
Official docs: hooks.
Hooks are deterministic checkpoints around Codex tool calls. They are more reliable than instructions for repetitive guardrails because the check runs at the moment of action: a PreToolUse hook can block rm -rf, and a PostToolUse hook can log a mutation after it happens.
Hooks are not a security boundary. Use them for workflow pressure: block known-bad patterns, enforce project conventions, add audit logs, or inject context at decision points. Keep sandboxing on.
The three hooks in hooks/ are the ToB defaults:
block-dangerous-command.sh--PreToolUseregex blocker forrm -rf, force-push tomain/master, and a few other footguns. Belt-and-braces withrules/default.rules.enforce-package-manager.sh-- blocksnpmwhen the project haspnpm-lock.yaml; tells Codex to usepnpminstead. Generalizes to any "use X not Y" convention.log-gam.sh--PostToolUseaudit log for Google Apps Manager (gam) mutations. Pattern generalizes to any CLI where you want to log writes.
Install:
mkdir -p ~/.codex/hooks
cp hooks/*.sh ~/.codex/hooks/
chmod +x ~/.codex/hooks/*.shThe hooks block in config.toml wires them up. Each hook has a timeout (seconds, default 600) and an optional statusMessage shown in the TUI while it runs.
Official docs: build skills.
Codex skills use progressive disclosure. The initial prompt contains each skill's name and concise
description. Codex loads the complete SKILL.md only when the request matches or the user invokes
the skill. Keep guidance used by a typical invocation in that entrypoint. Use references/ only
when a meaningful branch lets the invocation skip the file, such as a language, PR type, or
authorized mutation path. A skill can also bundle agents/openai.yaml for interface metadata and
invocation policy.
Repository skills are discovered from .agents/skills/ along the launch-directory path to the
repository root. User skills can be installed under ~/.agents/skills/. Skill descriptions should
be narrow enough for reliable implicit selection.
Seven skills ship in this repo under .agents/skills/:
| Skill | What it does |
|---|---|
$install-codex-config |
Installs or updates this Codex configuration from the local repo. Self-installs into ~/.agents/skills/ so it works from any directory after the first run. |
$development-standards |
Routes code standards by language and file type. |
$technical-writing |
Guides durable technical prose. |
$security-research-hygiene |
Validates and records authorized findings. |
$fix-github-issue |
Takes a GitHub issue from triage through PR creation -- research, plan, implement, verify, self-review, push, comment back. |
$merge-dependabot-prs |
Evaluates and merges Dependabot PRs with dependency-aware batching, transitive analysis, build/test verification, and sequential merges. |
$review-and-fix-pr |
Reviews a PR, merges findings from codex review and other reviewers, fixes P1-P3 findings, and posts a summary comment. |
For additional maintained workflows and domain expertise, use trailofbits/skills. Use trailofbits/skills-curated for reviewed third-party skills instead of duplicating a fast-moving recommendation catalog here.
Keep .agents/skills/ at the repo root for project-local use, or copy globally:
mkdir -p ~/.agents/skills
cp -R .agents/skills/* ~/.agents/skills/Official docs: MCP.
Everyone at Trail of Bits should set up at least Context7 and Exa as global MCP servers.
| Server | What it does | Requirements |
|---|---|---|
| Context7 | Up-to-date library documentation lookup | None (no API key) |
| Exa | Web and code search via real-browser fetch | EXA_API_KEY (Trail of Bits employees: shared key in 1Password; external users: get one here) |
Codex configures MCP in TOML, not in .mcp.json. Servers live under [mcp_servers.NAME] in ~/.codex/config.toml (global) or .codex/config.toml (project-local, only loaded for trusted projects). Stdio servers use command + args; HTTP/SSE/WebSocket servers use url + optional bearer_token_env_var.
Append the template:
cat mcp-template.toml >> ~/.codex/config.tomlThen replace EXA_API_KEY placeholder with your actual key (or remove the exa entry if you don't have one).
Or use the CLI to add servers (writes to ~/.codex/config.toml):
codex mcp add context7 -- npx -y @upstash/context7-mcp
codex mcp add exa --env EXA_API_KEY="$EXA_API_KEY" -- npx -y exa-mcp-serverOAuth tokens for MCP servers are stored in the OS keychain via mcp_oauth_credentials_store = "keyring". On platforms where the keyring backend is unreliable, switch to "auto".
Beyond the baseline, these are worth adding for specific workflows:
| Server | What it does | Requirements |
|---|---|---|
| Granola | Meeting notes and transcripts | Granola app with paid plan |
| slither-mcp | Slither static analysis for Solidity -- vulnerability detection, call graphs, inheritance mapping, function metadata | Python 3.11+, Foundry/Hardhat |
| pyghidra-mcp | Headless Ghidra reverse engineering -- binary analysis, decompilation, cross-references, semantic search | Ghidra (GHIDRA_INSTALL_DIR env var) |
| Serena | Symbol-level code navigation and editing across 30+ languages via LSP | uv, language LSP servers |
Official docs: Follow a goal, goal-mode prompting, CLI slash commands.
/goal is Codex's durable loop for one objective. It gives the session a standing contract and lets Codex continue across turns until the objective is complete, blocked, paused, or cleared.
Use /goal when the work is larger than one turn, has a clear stopping condition, and can be validated by commands or artifacts. A simple test: if you would repeat the same standing instruction three turns in a row, put it in the goal. Good fits are code migrations, issue implementation, large refactors, deployment retry loops, eval or prompt optimization, prototypes, games, and bounded audit checklists. Do not use it for a loose backlog, subjective cleanup, open-ended bug hunting, or work that needs frequent human decisions. For long efforts, chain smaller goals with review between checkpoints instead of creating one giant goal.
A goal is the objective for this stretch of work. A skill is reusable expertise for a recurring class of work. Use skills to teach Codex how to do something repeatably; use /goal to define what done means for the current run. A goal can invoke skills, but it should still name the scope, constraints, validation, and stop condition.
Requirements:
[features] goals = truein~/.codex/config.tomlfor the CLI- Interactive Codex session.
codex execis non-interactive and does not expose slash commands. - Objective length at most 4,000 characters; put longer specs in
PLAN.mdorGOAL.md.
Controls:
/goal <objective>-- set the active goal/goal-- view the current goal/goal pause,/goal resume,/goal clear-- control the run
If the goal is hard to define, start with /plan, refine the contract, then set /goal. Write goals as a work order:
Objective: one-sentence outcome
Scope: files, directories, issue, logs, or plan Codex must read first
Constraints: what must not change
Validation: exact commands or artifacts that prove progress
Stop: explicit done condition or reason to pause
Checkpoints: smaller milestones with their own validation
Evidence: output, diff, report, screenshot, or other proof to show at the end
For security research, harden the goal against reward hacking. A flood of wrong or impact-inflated findings is not harmless -- to a maintainer it reads as a denial-of-service on their time, so treat false-positive reduction as part of the work, not cleanup.
- Ask Codex to convert a casual objective into a precise
/goalprompt before starting the run. - Use neutral wording such as "trigger and validate the issue" instead of "prove this is exploitable."
- Require Codex to check open issues, open PRs, and known-findings files before treating a bug as new.
- Keep a short progress log or findings file in the repo so compaction and resumed sessions have durable state.
- Stop after each meaningful finding for human review instead of letting one goal produce a pile of untriaged reports.
- Don't accept assumed access. Codex's most common false positive assumes the attacker already controls something -- a malicious upstream, an internal caller, or pre-existing code execution. Require the goal to demonstrate that precondition rather than assert it; if the access can't be shown in scope, the finding isn't one.
- Scope a threat model and reference it in the goal. State what is in and out of scope and what the attacker can and cannot do. This alone removes most invalid "assume the attacker has X" findings.
- Supply concrete threat scenarios and a baseline severity. Realistic scenarios and a starting severity curb inflation; define what high-severity means for this project before asking Codex to find high-severity bugs.
- Validate each candidate with a second pass, never the finder alone. Have a different model or a fresh agent re-check the finding against a short plan-note before treating it as real. The config's
approvals_reviewer = "auto_review"setting is for command approvals; finding validation should be a separate review pass. - Measure what the agent actually read. After an audit pass, run trailofbits/aicov to get HTML/gcov/lcov coverage of the files Codex (or Claude) opened, then set a follow-up goal to reach full audited coverage of the in-scope code.
Field notes on what surfaces real bugs fastest. These are goal patterns, not guarantees -- pick the ones that fit the target.
- Differential testing across implementations. When several projects implement the same spec or algorithm (TLS stacks, crypto primitives, JOSE/JWT, protocol parsers), point them at each other and look for disagreements. Cross-implementation divergence is high-signal and tends to produce few false positives, because a real spec violation shows up as one implementation behaving differently from the rest.
- Break invariants instead of scanning for "vulns." Ask Codex to state a function or module's core invariants, then set a goal to find inputs that break them. Treat RFC keywords (MUST, SHALL, SHOULD) as invariants to prove or violate. For stateful systems, have Codex generate many configurations and exercise them until an invariant no longer holds. Pairs well with the
contrarianskill. - Variant analysis from past bugs. Scrape the project's historical high-severity issues and advisories, then goal Codex to find other instances of the same root cause in the tree. Generated Semgrep or CodeQL rules scale this: require each rule to fire on the known-vulnerable revision and stay silent on the fixed one, so it finds variants rather than re-reporting the original.
- Fuzzing without prior fuzzing experience. Ask Codex which parts of the codebase are the best fuzz targets, then run several agents on separate worktrees, each with a concrete security goal ("find an input that crashes the parser"). Payoff concentrates where untrusted bytes meet a hand-written parser: protocol and header parsing, length and size fields, credential and token decoding, and compression layers.
- Also worth trying. Have Codex build an attack taxonomy for the system class first -- from the relevant RFCs, prior literature, and classic attacks -- and review each feature against it. For code that is hard to read, ask Codex to re-express it in another language to expose edge cases hidden by unfamiliar constructs. Pair
/goalwith a formal-verification tool such as Verus when correctness is provable.
These options are useful for one-off runs that should not edit the global config:
codex --config model_reasoning_effort="high"lowers the normalxhighdefault for a measured low-risk workload."medium"or"low"can reduce latency further.codex -c "service_tier=flex"requests flex service for a latency-tolerant run when the active model and provider offer it.service_tier=fastrequests fast mode. Verify effective status.codex exec --ignore-user-configskips$CODEX_HOME/config.tomlfor that non-interactive run; authentication still usesCODEX_HOME. It does not disableAGENTS.mddiscovery.codex exec --ignore-rulesskips user and project exec-policy.rulesfiles. It does not disable hooks, AGENTS instructions, or the sandbox. Use it only for a controlled rules-exclusion test, never as a routine token-saving flag.
Use an isolated eval home for clean comparisons instead of weakening a normal working configuration.
Use /status inside Codex for the current thread, context, and rate-limit picture. Use npx @ccusage/codex for daily, monthly, and session-level token usage with per-model breakdown. For authoritative billed spend, see platform.openai.com/usage.
These are field-tested fixes for specific machines and runs. Keep them out of the default config unless the machine's trust boundary matches the advice.
If the local network is slow or restrictive, run Codex on a disposable VPS, a dropkit droplet, or a devcontainer instead of fighting the laptop network. Keep the repo, credentials, and teardown story simple. To drive that remote host from your laptop's Codex instead of SSHing in, see remote connections.
On macOS, keep the machine awake while a long session runs:
caffeinate -i codexIf Codex hangs during startup because Git is waiting for an SSH-key passphrase before the TUI can accept keyboard input, bypass the global Git config for that launch:
GIT_CONFIG_GLOBAL=/dev/null codexChanging API keys requires a fresh login flow; exporting OPENAI_API_KEY does not rewrite an active Codex session.
codex logout
codexFor side-by-side identities (for example, a ChatGPT-plan login and an API-key login), use a profile. A profile is a separate file at ~/.codex/<name>.config.toml that overrides the model, provider, and auth while reusing your global AGENTS.md, skills, rules, and hooks. Copy the template, drop your key next to it, and select it with --profile:
cp profile-template.toml ~/.codex/api.config.toml
echo "sk-..." > ~/.codex/api-key.txt # never commit API keys
codex --profile apiThe profile name is the file stem (api above). The template defines a custom provider whose auth.command prints a bearer token to stdout; see profile-template.toml for the worked example. Run /status after launching to confirm the API-key provider is active and that your global AGENTS.md and skills still loaded.
The profile template includes an optional commented gpt-5.6-cyber pin. Uncomment it only for an
API identity and project that have separate approval and provisioning for authorized security
research.
For full isolation -- a wholly separate config home with its own AGENTS.md, skills, and history rather than a shared one -- point CODEX_HOME at a second directory instead:
mkdir -p "$HOME/.codex-isolated"
alias codex-isolated='CODEX_HOME=$HOME/.codex-isolated codex'On Linux VPS images without a working secret-service backend, switch both credential stores to "auto":
cli_auth_credentials_store = "auto"
mcp_oauth_credentials_store = "auto"If "auto" still fails on a single-purpose disposable host, "file" works, but it stores credentials on disk in plaintext. Do not use it on a shared workstation.
Relax approvals and sandboxing only inside an external sandbox such as a disposable VPS or devcontainer:
codex -a never -s danger-full-accessDo not put that in the shared default config.
When /plugin fails without a useful TUI error, use the CLI so the real error is printed:
codex plugin marketplace list
codex plugin add plugin@marketplaceIf hardware-backed SSH auth or local Git state gets in the way, add a local marketplace checkout instead of debugging the interactive flow:
codex plugin marketplace add ./path/to/marketplaceCodex can keep serving a cached copy of a plugin after you update it. If your edits to a skill or marketplace are not taking effect, toggle the plugin off and back on in /plugins to force a reload. For a scripted refresh, send the plugin/list RPC to a running Codex app server -- see this refresh script.
/status-- inspect thread, context, and rate-limit status./side-- ask a side question or get a status recap without steering the main thread./logout-- clear stored auth before switching between plan/OAuth and API-key identities.
For more mid-run visibility, use detailed reasoning summaries per session:
codex --config model_reasoning_summary='"detailed"'If summaries do not appear for the model you are using, uncomment model_supports_reasoning_summaries = true in config.toml.
For throughput, use multiple isolated worktrees and Codex sessions when the task divides cleanly and
the user authorizes parallel work. When long-running unattended sessions can tolerate variable
latency, evaluate service_tier=flex against the default tier for the actual workload.
The shipped normal default, Plan mode, and the public cyber alias use xhigh. Lower a run to
high, medium, or low only when representative evaluation shows no quality loss for that
workload. Choose effort from task risk, available validation, latency, and measured results.
Any repo can plant instructions in agent-readable files (AGENTS.md, CONTRIBUTING.md, SKILL.md) and rely on Codex picking them up. Treat these files in third-party repos as untrusted input, especially during security research on code you do not own.
For headless or Dockerized Codex runs, copy ~/.codex/auth.json into the container so the CLI has credentials. The [features] table in config.toml still applies. Use codex exec for non-interactive jobs; slash commands require an interactive codex TUI with a TTY. To embed Codex in a service or pipeline rather than shelling out to codex exec, use the Codex SDK.