Securing ChatGPT and Codex with AiriaNewEnterprise

Route the ChatGPT app's Codex and Work surfaces and the Codex CLI through the Airia AI Gateway for DLP, guardrails, budgets, and audit, and govern the surfaces that can't be routed.

OpenAI ships more than one desktop app, and they do not behave the same way. The current ChatGPT app has three surfaces: Chat, Work, and Codex. Its Codex and Work surfaces can be pointed at your Airia AI Gateway, along with the Codex CLI and IDE extension, and once they are, agent turns, tool calls, and computer use all travel through Airia. Chat inside the app talks to chatgpt.com directly and has no endpoint setting, so you govern it the same way as chatgpt.com in a browser.

This guide covers which surface is which, how to route the ones that can be routed, what governance you get once they are, and how to cover the rest.

Start here: which app and surface

The app name doesn't tell you whether it routes. The bundle ID and the surface do.

App or surfaceBundle IDRoutes through Airia?
ChatGPT app, Codex and Work surfacescom.openai.codexYes. Agent turns, tool calls, computer use.
ChatGPT app, Chat surfacecom.openai.codexNo. Talks to chatgpt.com directly.
ChatGPT Classiccom.openai.chatNo. No endpoint setting at any version.
ChatGPT Atlascom.openai.atlasNo. Browser surface.
Codex CLI and IDE extensionnot applicableYes. Same configuration file as the app.
chatgpt.com in a browsernot applicableNo. Web session, no endpoint to repoint.

The app labeled simply ChatGPT is the Codex app that absorbed ChatGPT, which is why its bundle ID is com.openai.codex and why its Codex and Work surfaces read Codex's configuration file.

Users may have two or three of these icons in the Dock. Confirm which app a user actually opened before you treat their ChatGPT as covered. On macOS the bundle ID is visible in the app's Info.plist, and your MDM inventory reports it for every managed device, which is the practical way to see the split across a fleet.

1 · Route Codex through the AI Gateway

The ChatGPT app's Codex and Work surfaces, the Codex CLI, and the Codex IDE extension all read the same configuration file and honor a custom model provider. Point that provider at your Airia AI Gateway and every model call from those surfaces travels through Airia.

ChatGPT app (Codex · Work) · Codex CLI · IDE  →  Airia AI Gateway  →  OpenAI
                                                ↓  DLP · Guardrails · Agent constraints · Budgets · Audit

A · Build the gateway

Go to Secure → Gateway → AI Gateway and add a configuration. Name it for the audience, for example OpenAI_Dev_Tools.

Choose where OpenAI models come from. This choice decides who pays for tokens:

Model access choiceWho pays for tokensWhat the client sends
Airia Model Library (shared Airia key)Airia handles billing, charged to your Airia accountThe user's gateway key
Bring Your Own Keys → OpenAI → Use Customer's KeyYour organization's OpenAI accountThe user's gateway key
Bring Your Own Keys → OpenAI → OAuth PassthroughEach user's own ChatGPT plan; your Airia balance is not chargedThe user's ChatGPT sign-in, plus the gateway key in an x-airia-key header

Choose OAuth Passthrough when your developers already sign in to Codex with their own ChatGPT plan and you want Airia governance on that traffic without a second API bill.

Under Allowed Models, list the models users may select. Leaving it empty allows all of them. The app also calls smaller models for background tasks such as naming threads, so include the current model family, not only the chat model.
On the Access & Keys tab, add the users and groups who may use this gateway, then create a per-user gateway key. Per-user keys are what make the User column in Gateway Monitoring attribute traffic to a real person.
Attach the guardrails, agent constraints, and budget you want enforced. Everything routed through this gateway inherits them.

Full configuration reference: AI Gateway.

Two credentials, two jobs. The gateway key lives on the developer's machine and authenticates the user to Airia. The upstream credential (Airia's key, your organization's OpenAI key, or the user's own ChatGPT sign-in with OAuth Passthrough) authenticates the request to OpenAI, and that is what gets billed.

B · Point Codex at the gateway

Codex has no settings screen for this. The configuration file is the interface, and every Codex surface reads the same one:

OSPath
macOS and Linux~/.codex/config.toml
Windows%USERPROFILE%\.codex\config.toml

Set the CODEX_HOME environment variable to use a different directory.

Find your base URL. In Secure → Gateway → AI Gateway, click Gateway URL to copy your tenant's gateway endpoint, then append /openai/v1.

Let Airia write the file. On the gateway configuration, choose Integrate, then Automate Codex Setup to download a setup script for the user's operating system. The script adds the Airia provider to the user's existing config.toml and supplies the key for the model access choice you made. To write the file by hand instead, use the tab that matches that choice:

For Airia Model Library and Use Customer's Key. Codex reads the gateway key from an environment variable, so the secret stays out of config.toml:

model_provider = "airia"

[model_providers.airia]
name = "Airia Gateway"
base_url = "https://<your-gateway-url>/openai/v1"
wire_api = "responses"
env_key = "AIRIA_GATEWAY_KEY"

Then set the variable to the user's gateway key. For the desktop app, add it to ~/.codex/.env as a plain-text file (named exactly .env, not .env.txt):

AIRIA_GATEWAY_KEY=agk-your-gateway-key

For terminal and IDE use, also export it from the shell profile. Store only the key value; do not prepend Bearer.

A few details decide whether this works:

  • model_provider is a top-level key. Keep it above every [table] in the file, and keep exactly one. A second or misplaced model_provider makes the whole file invalid, and Codex silently ignores it.
  • Add to the file, don't replace it. It likely already holds marketplace, plugin, MCP, and project sections that the app wrote. The setup script merges for you.
  • wire_api = "responses" is required. Codex speaks the OpenAI Responses API, not Chat Completions.
  • Environment variables alone don't route. Codex does not redirect traffic based on OPENAI_BASE_URL. The config.toml provider is the routing path; the environment variable carries only the key.

The app reads this file at launch. After any edit, quit the app completely (⌘Q on macOS; closing the window is not enough), reopen it, and start a new Codex session. An app left running keeps sending to the old endpoint, which looks exactly like the configuration not working.

C · Confirm it is actually routing

Send one turn from each surface you care about, then open Gateway → Analytics → Gateway Monitoring. Every routed call appears with the user, the model, the token count, and a userAgent that tells you which surface produced it.

What produced the calluserAgent
ChatGPT app, Codex and Work surfacesCodex Desktop/<version>
ChatGPT app, computer usecodex-computer-use/<version>
Codex CLI in a terminalcodex-tui/<version>
Codex CLI in an editor or scriptcodex_exec/<version>

Read the userAgent, not the app's version number. These apps update their internal runtime independently of the outer app, so the version the feed reports and the version the App Store shows will not always agree. The feed is the one that describes what actually made the call.

SymptomLikely causeFix
Missing environment variable AIRIA_GATEWAY_KEY.env is missing, misnamed (.env.txt), saved as rich text, or not loaded yetCheck that ~/.codex/.env exists and holds AIRIA_GATEWAY_KEY=…, then quit and reopen the app
401 UnauthorizedThe gateway key is wrong or prefixed with BearerCreate a new key on the gateway's Access & Keys tab and store the bare value
404 on every requestThe base URL is wrongUse your Gateway URL with /openai/v1 appended
Some requests fail while chat turns workA background model isn't in Allowed ModelsAdd the app's current model family to the allowlist
Changes appear ignoredThe app wasn't fully restarted, or model_provider is duplicated or below a tableQuit and reopen the app; check that model_provider appears once, at the top
Every turn fails with a policy violationA guardrail on the gateway is blocking the requestMatch the correlation ID the client prints to the feed row to confirm

To roll back, remove the model_provider = "airia" line from config.toml (the [model_providers.airia] table can stay) and restart the app.

D · Push it to the fleet

A configuration file each developer edits by hand is a pilot, not a rollout. Two ways to make it stick:

Deploy config.toml through Jamf, Intune, or Kandji, using a placeholder for the gateway key and your MDM's per-user secret substitution so no long-lived credential is embedded in the profile. Deploy the file owned by the user, with restrictive permissions.

This is the floor, not the ceiling. A user with write access to their own home directory can edit the file back. Pair it with Codex's admin-enforced requirements.toml (see section 2), which users cannot override, and pin the Airia provider there so it stays selected.

2 · What you get once it's routed

Everything attached to that gateway configuration now applies to every routed Codex and Work session:

ControlWhat it does to routed traffic
DLP policiesInspect prompts and completions for PII, PCI, secrets, and your own detectors before the call leaves.
GuardrailsBlock prompt injection, jailbreaks, and off-policy content inline.
Agent constraintsBlock or audit specific tool calls the model tries to make.
BudgetsCap spend per gateway and cut off runaway usage.
Model allowlistRestrict which models can be selected, regardless of what the client offers.
AuditEvery request, user, model, and token count in one feed alongside your other AI traffic.

Scope agent constraints to the Gateway. A constraint scoped to All Agents covers Airia pipeline traffic only. Codex traffic is gateway traffic, so the constraint has to be scoped to Gateway to see them.

A blocked call looks like a client error. When a guardrail stops a turn, the client reports a policy violation and the feed shows the request with zero tokens. The correlation ID the client prints matches the execution ID on the feed row, so you can tie the two together and confirm the block was yours before anyone starts debugging the client.

Lock down local behavior

The gateway sees model traffic. Codex's local actions (file edits, shell commands, sandbox mode) are governed by OpenAI's own admin enforcement: a requirements.toml file that users cannot override. Deploy it with your MDM, or manage the same settings from the Codex Policies page if you have ChatGPT Business or Enterprise.

OSPath
macOS and Linux/etc/codex/requirements.toml
WindowsC:\ProgramData\OpenAI\Codex\requirements.toml

A typical enterprise baseline:

  • Pin the Airia provider. Set model_provider = "airia" and the same [model_providers.airia] table you use in config.toml. The admin file takes precedence, so every Codex surface stays routed through the gateway.
  • Block the unsandboxed mode (danger-full-access) so Codex always runs sandboxed.
  • Disallow the "never ask" approval policy so destructive actions always require review.
  • Allowlist MCP servers to your Airia MCP Gateway entry so unsanctioned local tools can't be added.
  • Deny known-dangerous commands, for example unencrypted curl http:// calls.

When a user's own configuration conflicts with the admin file, the most restrictive setting wins and Codex tells the user. See OpenAI's Codex documentation for the full requirements.toml reference.

3 · Govern the tool side with the MCP Gateway

Routing inference does not govern the tools the model calls. Point Codex at the Airia MCP Gateway and every downstream credential is managed centrally, behind one authenticated URL, instead of scattered across local configurations in plaintext.

On your MCP gateway, open Client Setup → ChatGPT & Codex for the steps for each client: the desktop app, the IDE extension, the Codex CLI (codex mcp add), or config.toml directly. All of them write the same Codex MCP configuration on the device, so connecting once covers every Codex surface. Users authenticate through OAuth on first connect.

Setup and credential management: MCP Gateway.

4 · Cover the surfaces that don't route

Four surfaces sit outside the gateway's reach. Cover each one with a different control.

SurfaceWhy it can't be routedWhat to do instead
Chat in the ChatGPT appTalks to chatgpt.com directly and reads no local configuration.Network policy or a SASE path, and steer users to the Codex and Work surfaces for sensitive work.
chatgpt.com in a browserA web session, not an API call. There is no base URL to change.Browser extension policy, or a SASE path.
ChatGPT Classic and AtlasNo base-URL setting at any version.Browser extension for Atlas, network policy for both, or remove them from managed devices.
ChatGPT on iOS and AndroidNo base-URL setting, and no interception hook short of network inspection.Mobile device policy and network controls.

The browser and shadow-AI answer

The Airia Browser Extension is the control point for chatgpt.com. It is domain-scoped, offering Block, Warn, Monitor, or Redirect at the AI-service domain, with optional request-body capture so your DLP detectors can run against what was actually typed. Redirect is the useful one here: send chatgpt.com to your sanctioned Airia deployment instead, so people keep working on a governed surface.

Configure under Secure → Runtime Security → Browser Extension Policies, and force-install it through your MDM so users can't remove it. Deployment steps: Browser Extension MDM Deployment.

For traffic you can see on the network but not on the endpoint, chain your secure web gateway into an Airia AI Gateway rather than blocking it outright. The user keeps working and the call picks up your policies. See SASE Integration.

Close the direct path

The gateway enforces on the traffic it receives, so close the direct paths from managed devices at the firewall or SASE layer. Codex uses a different OpenAI endpoint depending on how the user signs in:

Sign-inDirect endpoint to block
OpenAI API keyapi.openai.com
ChatGPT accountchatgpt.com/backend-api/codex (a path rule, so apply it on a SASE path with TLS inspection)

Block both. A block on api.openai.com alone covers API-key use only. The gateway calls OpenAI from Airia's side, not from the device, so gateway-routed traffic, including OAuth Passthrough, keeps working with both blocks in place.

  1. One AI Gateway configuration for OpenAI, with your DLP policies, guardrails, agent constraints, and a budget attached.
  2. Per-user gateway keys, so the audit trail names people.
  3. config.toml pushed by MDM with requirements.toml alongside it, then the endpoint agent in enforce mode to make it stick.
  4. Agent constraints scoped to Gateway.
  5. The MCP Gateway for the tool side, replacing local server entries.
  6. Browser extension policy on chatgpt.com, force-installed.
  7. Egress blocks on api.openai.com and chatgpt.com/backend-api/codex.
  8. A weekly look at the gateway feed. An active developer with no gateway traffic for a week is worth a follow-up to confirm their client still routes through the gateway.

For the Anthropic equivalent of this build, see Securing Claude with Airia.

Was this page helpful?

On this page