Codex
Codex connector wires versioned lifecycle hooks, native OTel logs/metrics/traces, and the notify bridge without inserting a model proxy.
The Codex connector wires DefenseClaw into Codex's documented hooks, native OpenTelemetry exporter, and the notify bridge for agent-turn-complete events.
The Codex connector is hook-only. There is no LLM-proxy data path — Codex talks directly to its native upstream (api.openai.com or the ChatGPT backend) and DefenseClaw observes via hooks + native OTel.
mode=action is supported on Codex's declared blocking hook events. For
example, PreToolUse can return permissionDecision: "deny" before the tool.
Observation-only events and agent activity outside the registered hook contract
are not proxy-intercepted.
Platform support
| Platform | Status | Connector path |
|---|---|---|
| macOS and Linux | Supported | Portable command hooks, native OTel, and the notify bridge. |
| Native Windows x64 | Supported | Event- and contract-bound PowerShell -EncodedCommand bridge to the protected defenseclaw-hook.exe, plus native OTel and notify configuration. Validation version, date, and run metadata remain empty and live=false. |
Setup
defenseclaw setup codex # observe (default) — record only
defenseclaw setup codex --mode action # block on policy hits via PreToolUse denyDefenseClaw installs the portable Codex hook and configures native OTel plus the agent-turn-complete notify bridge.
defenseclaw setup codex # observe (default) — record only
defenseclaw setup codex --mode action # block on policy hits via PreToolUse denyDefenseClaw writes each selected Codex event and hook contract into
%CODEX_HOME%\managed_config.toml. The registered command invokes system
Windows PowerShell with -EncodedCommand, synchronously starts the protected
defenseclaw-hook.exe with inherited standard handles, and passes the bound
--event and --hook-contract values. This bridge is native Windows plumbing;
it does not use a POSIX hook shell or WSL.
setup codex is the dedicated Codex setup alias. It uses the same setup
backend as setup guardrail, adds or reconfigures Codex, wires hooks + OTel +
the notify bridge, and can join an existing hook-connector roster when you
choose Add. No proxy listener binds in either mode.
Native logs, metrics, and traces use the standard loopback
/v1/{logs,metrics,traces} endpoints with
X-DefenseClaw-Source: codex and an Authorization bearer managed in Codex's
exporter configuration. The credential is separate from both the gateway
master token and the Codex hook credential, is accepted only for matching Codex
OTLP over loopback, and cannot call management or another connector.
Do not print or copy the managed exporter header or its protected sidecar.
Setup also pins Codex's documented otel.environment field to DefenseClaw's
configured environment (Codex otherwise defaults it to dev). Doctor compares
that on-disk value with authenticated live runtime metadata and telemetry
health so a stale gateway or configuration drift is visible.
Redaction is configured through the v8 bucket/profile policy: edit
observability.destinations[].routes[].selector.buckets and
observability.redaction_profiles, then follow
Redaction → Verify policy.
The alias defaults to observe mode and accepts the common hook-connector
options, including --mode, --workspace, --rule-pack,
--human-approval, --hilt-min-severity, --fail-mode, --block-message,
--replace, --with-local-stack, and restart controls. Use the
quick-alias reference for that surface. Use
the full guardrail setup when you also need scanner,
detection-strategy, or judge-provider configuration. Defaults are documented
once on the Defaults page.
Files DefenseClaw will modify
%CODEX_HOME%\managed_config.toml carries the managed hook matrix.
%CODEX_HOME%\config.toml carries DefenseClaw-marked OTLP and notify fields.
Generated runtime and protected connector credentials live below
%USERPROFILE%\.defenseclaw\hooks. Use setup/teardown commands; do not edit or
copy those entries manually. See the
Windows path reference.
Everything outside DefenseClaw-marked fields is preserved. Teardown restores a pristine backup when its identity still matches; otherwise it removes only owned entries.
Hook capabilities
Block events
- SessionStart
- UserPromptSubmit
- PreToolUse
- PermissionRequest
- PostToolUse
- SubagentStop
- PreCompact
- PostCompact
- Stop
Native ask events
None — confirm verdicts are downgraded with the raw action preserved.
Action-mode responses follow each event's official control or feedback contract; the events do not all have the same effect:
Each native hook request must exactly match the registered event and its stdin
hook_event_name. Before policy evaluation, the gateway also compares that
event and its contract ID with the protected contract lock; mismatches or
tampering are rejected.
The lifecycle-control rows marked v3/v4 below are contract-supported only
for Codex >=0.133: v3 covers 0.133 through 0.144, and v4 covers
>=0.145. This version boundary is not release certification; native Windows
support does not populate authentic official-client validation metadata.
DefenseClaw does not infer or backfill these matcher/control semantics onto the
smaller v1/v2 contracts.
| Event | DefenseClaw-owned action response |
|---|---|
SessionStart (v3/v4, >=0.133) | continue: false ends the turn before another model request. Its matcher includes all official sources: startup, resume, clear, and compact. |
PostToolUse | decision: "block" cannot undo the completed tool. In interactive use, the reason replaces the tool result fed to the next loop; in code mode, the corresponding tool promise rejects. |
SubagentStop (v3/v4, >=0.133) | decision: "block" continues the subagent flow; it does not terminate the subagent. |
PreCompact (v3/v4, >=0.133) | continue: false stops before compaction. |
PostCompact (v3/v4, >=0.133) | continue: false stops after compaction has already completed. |
Stop | decision: "block" prevents stopping and continues with the reason as a new continuation prompt. |
SessionEnd (0.145+) | Advisory observation only. Output cannot steer Codex or keep the thread open, and the hook has a three-second host maximum. |
Codex has no native ask surface here. Confirm verdicts become an alert/system message with raw_action preserved so operators can review the original action in audit or the TUI. That review cannot resume the hook call.
Inventory surfaces
DefenseClaw follows the current Codex layouts rather than Claude Code's
.mcp.json convention:
- Skills:
.agents/skillsat every directory from the active working directory to the detected repository root, then$HOME/.agents/skills, plus$CODEX_HOME/skills;/etc/codex/skillsis also included on Unix.CODEX_HOMEdoes not redirect personal.agents/skills. Operator-installed children of$CODEX_HOME/skillsare scanned normally. The exact$CODEX_HOME/skills/.systemchildren are vendor-bundled: DefenseClaw lists them in inventory but never scans, blocks, disables, or quarantines them. A directory merely named.systemanywhere else is not exempt. Linked or reparse-point roots, children, and markers (including Windows junctions) are rejected; copy a linked skill into a real contained directory before relying on inventory coverage. - MCP:
[mcp_servers.*]in candidate project.codex/config.tomllayers, closest layer first, followed by$CODEX_HOME/config.toml. The exact URL-onlyopenaiDeveloperDocs = https://developers.openai.com/mcpentry in the canonical user config is vendor-bundled: it remains visible withbundled: true, but DefenseClaw never scans or enforces it. A same-named project entry, or a user entry with any command, auth, header, query, transport, or other added field, is not exempt. Codex's generatednode_replcurrently has no stable published provenance/schema contract, so it intentionally remains scan-eligible even when the observed local runtime binary is OpenAI-signed. MCP manifests shipped inside Amp skills are also user/workspace assets and remain scan-eligible. - Custom agents: standalone
.tomlfiles in candidate project.codex/agents/layers and$CODEX_HOME/agents/. Inventory validates the requiredname,description, anddeveloper_instructionsfields without copying instruction text into the AIBOM. - Rules:
*.rulesbelowrules/beside each candidate active config layer, including project.codex/rules/and$CODEX_HOME/rules/. - Memories: generated local-memory state under
$CODEX_HOME/memories/.$CODEX_HOME/history.jsonlis a separate transcript-history file and is not reported as a memory store. - Plugins: exact local
source.pathentries from repository and personal.agents/plugins/marketplace.json, the repository's lower-precedence legacy-compatible.claude-plugin/marketplace.json, plus bounded inventory of installed copies in the implementation-observed$CODEX_HOME/plugins/cache/hierarchy. Personal marketplace entries follow both repository sources. DefenseClaw does not invent a fixed project plugin directory. The marketplace paths, localsource.pathresolution, and.codex-plugin/plugin.jsonmanifest are official. Codex CLI reports aninstalledPath, but its public CLI contract does not promise that the cache hierarchy will remain stable. DefenseClaw therefore does not claim that Git/URL/npm sources must land there; bounded inventory reports only installed copies actually observed under that hierarchy.
Codex activates project .codex/ config, MCP, agent, and rule layers only for
trusted projects. Filesystem inventory reports project entries as
trust_required; it does not infer the client's private trust decision from
the presence of a file.
Telemetry channels at boot
In an OpenShell sandbox
defenseclaw sandbox run codex runs Codex in an NVIDIA OpenShell sandbox on
Linux, or on a Mac with Apple silicon in a MicroVM of its own that works on a
copy of your folder (macOS): the agent sees only
your project folder, and DefenseClaw hooks gate every tool call. The sandbox guide covers setup,
the session and every flag. The files below exist only in the sandbox image;
your own Codex configuration does not change.
- Managed tier. The hooks are in root-owned
/etc/codex/requirements.toml, which pinsallow_managed_hooks_onlyandfeatures.hookson, so user and project config cannot add hooks or switch DefenseClaw's off. Root-owned/etc/codex/managed_config.tomlturns off the update check, analytics and the features that reach remote services, sends Codex's OTel to DefenseClaw, and pinsBASH_ENV,ENVand the dynamic-loader variables to empty for every command Codex runs. The hooks fail closed and authenticate with a per-sandbox token, which never goes on a command line: the launcher hands it to Codex's OTel exporters in their header variables (blanked for the commands Codex runs), and the hooks and the notify bridge give it to curl as configuration on a file descriptor. The notify bridge only sends telemetry, so it never blocks Codex. - Startup tip download. The Codex TUI fetches its startup tip from
raw.githubusercontent.comat every start, around the egress proxy. OpenShell refuses it and DefenseClaw's triage rejects the drafted rule (harness_background_fetch) instead of opening a direct one; the refusal is not counted as a blocked site, and Codex shows a built-in tip. - Skip-permissions. On by default (the
openandbalancedpacks): Codex starts with--dangerously-bypass-approvals-and-sandbox. Codex's own sandbox cannot run inside OpenShell, so--safe(or thestrictpack) keeps its approval prompts withsandbox_mode="danger-full-access"andapproval_policy="untrusted": Codex asks before every command outside its read-only set and before every edit. A headless--saferun (--prompt,codex exec) cannot ask, so it refuses those commands. The sandbox'srequirements.tomlthen refuses theneverapproval policy (falling back tountrusted), and--dangerously-bypass-approvals-and-sandbox,--yolo,--full-auto,--ask-for-approval neverand-c approval_policy="never"are dropped from the arguments you pass. - Model sign-in.
--llm auto(the default) sharesOPENAI_API_KEY(orCODEX_API_KEY) from your shell, or else the API key thatcodex login --with-api-keystored in~/.codex/auth.json. A ChatGPT sign-in is not shared. OpenShell holds the secret, and the sandbox gets a placeholder that works only atapi.openai.com.--llm bedrock, andautowhen neither is set, shares a short-term Amazon Bedrock API key fromAWS_BEARER_TOKEN_BEDROCKfor a Codex custom provider on the Bedrock Mantle endpoint in--bedrock-region(default$AWS_REGION, then$AWS_DEFAULT_REGION, thenus-east-1), with Codex's multi-agent and web search tools off. Mantle does not serve Codex's own default model, so a Bedrock run usesopenai.gpt-oss-20bunless you pick another with-- -m MODEL(a-c model=override does not change it); the banner's Model line names the model either way.openshell.llmsets the choice for runs without--llm, such as thecodexshell wrapper's. - Bedrock follow-up turns. Bedrock Mantle rejects every turn after the
first of a Codex conversation, which Codex shows as
stream disconnected before completion; no provider setting avoids it. Start each task with/newin the TUI, or run one--promptper task. The banner of an interactive Codex session on Bedrock says so. - Per-sandbox settings. Codex reads one
managed_config.tomland onerequirements.toml, so each sandbox gets both again, read-only, with its own settings.managed_config.tomlpins the model provider the run chose, so aconfig.tomlthe agent writes cannot redirect Codex, and defines the MCP servers DefenseClaw brought along from your Codex setup. Unless the sandbox pack setsmcp.project_servers: allow,requirements.tomlallows exactly those servers, which disables every other one, a repository's included.--no-mcpleaves your servers behind. - MCP gap. Codex matches an allowed server by its command only, and merges
a repository's
[mcp_servers.<name>]table into yours key by key, so a repository could add environment variables to an imported server of the same name. DefenseClaw leaves such a server behind and names it when the run starts. - Image and verification. The image installs Codex 0.146.0 by default,
replacing the base image's older Codex, and refuses a version without a
reviewed Linux hook contract. Verified end to end: against a mock model
every required hook fired and a blocked tool call did not run, also with
hostile user and project config (
features.hooks = false, hooks, a notify program and OTel exporters of their own, a plantedBASH_ENV, fake tools onPATHand a forged sandbox token), and a live sandbox run fired the hooks and honoured a deny with a Bedrock Mantle model.
Disable
defenseclaw guardrail disable --connector codex --yesClaude Code
Claude Code connector wires the documented lifecycle hook set plus native OTel. Thirteen current events can return block decisions, and PreToolUse supports native HITL ask.
OpenClaw
The reference proxy connector. DefenseClaw ships a TypeScript plugin that wires OpenClaw's fetch interceptor and before_tool_call hook directly into the gateway.