Skip to main content
Codex is OpenAI’s coding agent, available through a terminal CLI, an IDE extension, and the ChatGPT desktop app. It can read repositories, run shell commands, apply patches, and call external tools on the developer’s machine. TrustGuard lifecycle hooks evaluate local prompts and actions.

NeuralTrust controls

Install TrustGuard from the trustguard-codex-plugin repository, either from a checkout or through MDM. Configure TrustGate separately in Codex’s config.toml. Codex does not support importing plugins from GitHub through a marketplace.

Deployment options

Use separate credentials for TrustGuard and TrustGate. The hooks use a tgk_… collector key in codex.json. MCP authenticates as a consumer with OAuth or an ag_… API key. A tgk_… key does not authenticate MCP, and codex.json does not accept MCP settings.
The plugin uses Codex lifecycle hooks, not Codex External guardrails. External guardrails are a separate extension point and are not configured here.

Before you start

Create the policy in Observe mode. Observe records decisions in Activity without enforcing them. Review the results, then switch the policy to Enforce. See Policies.
Developers do not need NeuralTrust accounts for the hooks path.

Set up prompt and tool screening (TrustGuard)

Install from a checkout (pilot)

make install-local:
  • Builds trustguard-codex and installs it under ~/.trustguard/bin
  • Copies the plugin to ~/.codex/plugins/trustguard
  • Writes ~/.codex/hooks.json with absolute paths to the bootstrap scripts. Codex runs hooks from the session cwd, so relative paths are unreliable
Then write the key config to ~/.trustguard/codex.json and chmod 600 it:
In Codex run /hooks, trust the TrustGuard definitions, and send a test prompt.

Deploy under MDM (enterprise)

An MDM deployment consists of four components: Managed key config.
Codex policy. requirements.toml keeps the hooks on and pins them to the managed directory:
With allow_managed_hooks_only = true, developers cannot switch managed hooks off from /hooks. The full file is docs/enterprise-requirements.toml in the plugin repo; exact keys vary by Codex version, so confirm against Codex hooks docs.

Set up governed tool access (TrustGate)

Codex treats TrustGate as a streamable HTTP MCP server: one url per MCP consumer, and the agent sees the merged toolkit that consumer is routed to. Copy the endpoint from the consumer’s Connect tab:
The Codex CLI, ChatGPT desktop app, and IDE extension share the same config.toml for a given Codex host. Each server is an [mcp_servers.<name>] table; see Configuration for the two scopes and the transport rules. For OAuth, only url is required:
Then log in once:
Codex opens the browser, registers a client (CIMD or dynamic registration) against the discovery documents TrustGate publishes, and stores the tokens. Codex logs in against TrustGate, not against your IdP directly, so nothing has to be registered per developer. Override the callback only when the machine needs a fixed port or a non-loopback base, for example on a remote development host:
Codex appends a server-specific callback id to that base.

API-key consumers

Keep the key out of the file with env_http_headers, which reads the value from the environment at connect time:
If environment variables are unavailable on a shared machine, configure a static value:
bearer_token_env_var also works:
Private (Hybrid) data plane. Add the gateway slug unless the MCP host already scopes the gateway:
Combine it with env_http_headers for the API key when the consumer is not OAuth.

Add it from the GUI

Both write the same config.toml, so a server added in one client shows up in the others.

Verify

Hooks.
  1. In Codex, run /hooks and confirm the TrustGuard hooks are listed. Under an enterprise policy, also confirm they are marked managed.
  2. Send a test prompt.
  3. Confirm the event in TrustGuard Activity. consumer_id is typically codex:<user>, or codex:<email> when the payload includes email.
Smoke-test the binary (optional):
MCP.
  1. Run codex mcp list, or /mcp in the CLI TUI, and confirm TrustGate is active.
  2. Ask the agent to use a tool from a toolkit bound to that consumer.
  3. Confirm the call in TrustGate telemetry. See Metrics.

Reference

Coverage

TrustGuard can evaluate Codex prompts, commands, and tool calls from a local checkout during a pilot or from an MDM deployment. Ask. Codex does not display an Ask permission dialog. The result of an ask verdict depends on the event: Use a Block gate wherever you need a stop. The one exception is an ask derived from a transform (DLP) status under the default transform_action: "ask". That verdict reaches PostToolUse as decision: "block"; its reason includes the sensitive-data message and untrusted-content guidance. Limits. The hooks require the bootstrap scripts on disk; the configuration file alone is not sufficient. This collector does not support redaction. Set transform_action: "deny" so a masking policy blocks rather than warns. A PostToolUse block cannot undo a tool call that already ran. The plugin returns decision: "block" with a reason, mirrors that reason in additionalContext, and does not provide replacement content. Codex controls whether the original tool output is suppressed. The hooks do not evaluate model responses or tool declarations. Use TrustGate to control which tools are available. Full comparison: Coverage.

What is evaluated

Every hook calls POST /v1/evaluate with the collector tgk_… key, and the policy’s detectors decide the verdict. MCP tool calls pass through the hooks like any other tool call. For an MCP hook name such as mcp__<server>__<tool>, tool.name is the final <tool> segment. It does not include the server name. Gate on the short tool name.

Configuration

codex.json (TrustGuard hooks only). Keys: data_url, api_key, fail_mode, plus the optional settings below. It never holds MCP values. When the managed file includes api_key:
  • Locked: api_key, data_url, fail_mode. A user file and environment variables cannot replace them.
  • User-overridable settings may still be loaded from ~/.trustguard/codex.json: timeout_ms, transform_action, events, consumer_id.
Without a managed file, all configuration is loaded from ~/.trustguard/codex.json (chmod 600). config.toml (TrustGate only). Two scopes: The table key is snake_case: mcp_servers, not mcpServers. Codex infers the transport from the keys: url selects HTTP and command selects stdio. It rejects a table that mixes keys from both. TrustGate always uses url. Auth headers. TrustGate accepts X-AG-API-Key, x-api-key, or Authorization: Bearer ag_…. For OAuth it advertises discovery at /.well-known/oauth-authorization-server and /.well-known/oauth-protected-resource and exposes a registration endpoint. The Codex configuration does not require a client ID or secret. TrustGate accepts https callbacks, http loopback callbacks, and private-use schemes, and rejects anything else with invalid_redirect_uri. The consumer configuration determines which IdP handles the login. See Okta or Entra ID.
Use OAuth for consumers that resolve tools per user. The identity used to log in selects the roles, and therefore the registries and tools, on Identity-based consumers.
Authenticating to TrustGate is not the same as authenticating to the upstream servers. When a registry uses OAuth (forwarded), the first call for a user without a stored credential returns a connect link; the user authorizes once and TrustGate stores and refreshes the credential. Deployment ownership.

Tools and approvals

TrustGate defines the consumer’s tool set. Codex applies additional settings on the local machine:
Codex tool filters, approval modes, and server settings apply only to the local client. Configure restrictions that must apply to every client on the consumer or role. To limit MCP tool calls, attach the Per-Tool Rate Limiter policy.

Attributes

  • attributes.collector.type = "ide"
  • attributes.source.application = "codex-plugin"
  • attributes.codex.event, cwd, model, and turn
  • consumer_id prefixed codex:, using the email from the payload when present, otherwise the configured value or an OS fallback
Every decision appears in Activity under that consumer_id, providing per-developer attribution when the identifier is available. Gate on source.application and/or tool.name / tool.command.

Troubleshooting