SpyBara
Go Premium

Documentation 2026-10-18 23:00 UTC to 2026-10-19 23:02 UTC

6 files changed +1,331 −742. View all changes and history on the product overview
2026
Fri 30 23:59 Thu 29 23:59 Wed 28 23:00 Tue 27 23:58 Mon 26 23:58 Fri 23 23:59 Thu 22 23:57 Tue 20 23:02 Mon 19 23:02 Sat 17 23:00 Fri 16 23:02 Thu 15 23:00 Wed 14 23:59 Tue 13 23:01 Mon 12 23:01 Fri 9 23:02 Thu 8 23:01 Wed 7 23:57 Tue 6 23:02 Mon 5 23:57 Fri 2 23:58 Thu 1 22:59
Details

4 4 

5Managed configuration lets enterprise admins set supported requirements and defaults for ChatGPT Work and Codex. Requirements constrain what users and tasks can do. Defaults provide starting values. Support depends on the product, client version, and execution environment.5Managed configuration lets enterprise admins set supported requirements and defaults for ChatGPT Work and Codex. Requirements constrain what users and tasks can do. Defaults provide starting values. Support depends on the product, client version, and execution environment.

6 6 

7For Work with local access and dots, supported Global policy governs the shared cloud orchestrator when managed policy is enabled; applicable local execution requirements govern the connected computer. Work cloud containers retain existing Work Cloud policies, and supported device controls still apply to local execution. Codex keeps its existing configuration behavior. Managed configuration does not grant a workspace seat or feature access. Use [Roles and workspace permissions](https://learn.chatgpt.com/docs/enterprise/roles-and-workspace-permissions) for those controls.7Start in **Agent security** in the Admin Console for supported cloud-managed

8settings. Use the settings controls for common tasks, or select **Edit as TOML**

9to inspect, copy, or edit the configuration text. Both views edit the same policy;

10TOML also exposes supported fields without a dedicated control. You don't need to

11distribute a local file to use cloud-managed settings. Authentication restrictions and

12device-managed deployments have separate [local setup](#manage-authentication-locally).

8 13 

9Enterprise admins can control supported local client behavior with:14Enterprise admins can control supported local client behavior with:

10 15 


16 21 

17See [Agent Security](https://learn.chatgpt.com/docs/enterprise/agent-security) for the Global baseline, environment overrides, and orchestrator and executor field lists.22See [Agent Security](https://learn.chatgpt.com/docs/enterprise/agent-security) for the Global baseline, environment overrides, and orchestrator and executor field lists.

18 23 

19<a id="agent-security-and-work-sync"></a>24## Configure a policy in Agent security

25 

26Where Agent security is enabled, workspace owners, workspace admins, and members

27with Codex admin permissions can manage policies. Access to the policy editor

28doesn't grant members access to the features that a policy controls.

29 

30Use **Workspace default** for the workspace baseline. Use **Overrides** when

31specific users, groups, or roles need different settings. An audience override

32selects who receives a policy; an environment setting selects where supported

33execution controls apply.

34 

351. Open **Admin Console** > **Agent security** and select **Workspace default** or

36 the policy you want to edit under **Overrides**.

371. Open **Requirements** to set enforced limits, or **Defaults** to set starting

38 values that members can change within those limits.

391. Keep approval, web search, and other agent-wide settings in **Global**. Where

40 available, use **Add environment settings** in the relevant card to add

41 **Local Environments** or **Codex Cloud Environments** for supported execution

42 settings. An empty environment document inherits settings from Global; it doesn't copy or

43 pin the current baseline.

441. Use the controls described in this guide. For advanced fields, select

45 **Edit as TOML** and edit the appropriate scope's `requirements.toml` or

46 `config.toml`. Select **Use settings controls** to return to the visual editor.

471. Review validation messages, then select **Save changes**. Applying a rule in

48 a rule editor updates the draft; it doesn't save the policy by itself.

491. Check policy selection and the supported client behavior as described in

50 [Confirm the admin and employee experience](#confirm-the-admin-and-employee-experience).

51 

52Environment editors and supported fields depend on the workspace and policy.

53See [Where settings apply](https://learn.chatgpt.com/docs/enterprise/agent-security#where-settings-apply)

54before moving a Global setting into an environment. A setting in Global doesn't

55necessarily apply to every product or execution path.

56 

57### Copy or reuse a configuration

58 

59The visual editor doesn't replace TOML. Select **Edit as TOML** to copy a

60configuration, keep a reference copy, or reuse settings in another policy.

61Select **Use settings controls** to switch back to the visual editor.

62 

631. Open the source policy and select **Edit as TOML**.

641. Choose the scope you want to copy: **Global** or an available environment tab.

65 Copy the text from **Requirements** (`requirements.toml`), **Defaults**

66 (`config.toml`), or both, depending on what you want to reuse.

671. Open the destination policy, select **Edit as TOML**, and choose the matching

68 scope. Paste requirements into `requirements.toml` and defaults into

69 `config.toml`. Review existing destination settings before replacing text;

70 keep unrelated settings that should still apply.

711. Review validation messages and the destination policy's targets and priority,

72 then select **Save changes**. Confirm the resulting client behavior before

73 relying on the copied policy.

74 

75The copied text contains the authored settings for that policy and scope. It doesn't include assignments, policy order, other environment documents, or the

76effective configuration combined from other policies and device settings.

77Copy environment settings separately when needed. Switching views or copying

78text doesn't save a policy change.

79 

80Try the example below: change a setting, then select **Edit as TOML** to see its

81configuration. Switch back with **Use settings controls** to keep experimenting.

82 

83 

84 

85> Illustration: Interactive example of Agent security settings and their TOML representation. The initial requirements allow on-request approvals, read-only sandboxing, and disabled web search. Change a sample setting and select Edit as TOML to see the corresponding field; Use settings controls returns to the same sample choices. This example does not change workspace policies.

86 

87 

88 

89### Choose the right control

90 

91| Task | Where to configure it | What it changes |

92| ------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |

93| [Restrict browser and native-app access](#control-browser-and-computer-use) | **Requirements** > **Desktop feature availability**, **Site rules**, and **App rules** | Controls which supported desktop capabilities are available and which sites or apps they can access. |

94| [Limit approval, sandbox, or web search choices](#set-approval-sandbox-and-web-search-guardrails) | **Requirements** > **Policy guardrails** | Restricts the choices available to supported clients. |

95| [Set starting approval, permission, search, or tool behavior](#set-configuration-defaults) | **Defaults** | Sets values members can change within enforced requirements. |

96| [Restrict command network destinations](#configure-network-access) | **Requirements** > **Network use controls** | Applies managed networking rules to supported command traffic. It isn't a workspace-wide internet switch. |

97| [Configure plugins and managed hooks](#configure-plugins-and-managed-hooks) | **Edit as TOML** | Lets you configure supported policy fields that have no dedicated visual control. |

98| [Restrict login methods or workspaces before sign-in](#manage-authentication-locally) | Local system requirements or macOS MDM | Applies authentication restrictions before cloud policy is loaded. |

99 

100## Control browser and Computer Use

101 

102Use **Agent security** in the Admin Console to manage browser and native-app access

103for supported desktop clients. Start with the UI controls. The TOML examples below

104provide a configuration reference for file-based policy delivery and settings that

105need the TOML editor.

106 

107Browser Use controls agent-driven activity in a browser. Computer Use controls

108agent-driven activity in native desktop apps. Settings for the built-in browser

109pane are separate from Browser Use. See [browser sessions and existing

110sign-ins](https://learn.chatgpt.com/docs/enterprise/chatgpt-work-local-security#browser-sessions-and-existing-sign-ins)

111for the differences between browser paths.

112 

113### Before you begin

114 

115Use an account with permission to manage Agent Security policies. Confirm which

116people receive the policy and which client versions and operating systems you need

117to support. Review [Agent Security](https://learn.chatgpt.com/docs/enterprise/agent-security) for policy

118assignments, Global settings, and supported environment overrides.

119 

120Use **Requirements** for limits users can't override. **Defaults** set starting

121values within those limits. Allowing a site or app doesn't install a plugin, grant

122operating-system permissions, sign a user in, or approve an action that still

123requires review.

124 

125Under **Desktop feature availability**, review **Browser use**, **External browser

126use**, and **Computer use**. **Force off** disables the corresponding feature; an

127allow rule for a site or app doesn't override it. Review **Full CDP access**

128separately; **Block user opt-in** prevents users from enabling it.

129 

130These desktop controls don't configure the hosted Work Cloud browser. Manage

131**Cloud browser use** and **Cloud network access** separately under

132**Admin Console > Permissions & roles > Workspace capabilities > Cloud computer capabilities**.

133See [how Agent Security applies to Work Cloud](https://learn.chatgpt.com/docs/enterprise/agent-security#how-agent-security-applies-to-work-cloud).

134 

135### Configure browser access

136 

137{/* Preserve the console label "Auto-approve requests". */}

138{/* vale Microsoft.Auto = NO */}

139 

1401. Open **Admin Console > Agent security**. Use **Workspace default** for the

141 workspace baseline, or open the relevant policy under **Overrides**. In

142 **Requirements**, go to **Desktop browser controls**.

1431. In **Site rules**, open the **Default** row's actions and choose **Edit Default**.

144 For access limited to approved sites, set **Site access** to **Block**, then

145 choose **Apply rule**. The **Default** row supplies values that a matching site

146 rule leaves at **Use default rule**.

1471. Choose **Add site rule**. In **Site or pattern**, enter an origin: a scheme,

148 hostname, and optional port. For example, `https://example.com` is valid;

149 `https://example.com/files` isn't. Don't include a path, query, or fragment.

150 HTTP and HTTPS are different origins. Specify the port when it differs from

151 the scheme's default.

1521. Set **Site access** and review **Downloads**, **Uploads**, and **Debug/CDP**.

153 Choose **Allow** or **Block** as appropriate, or leave a setting at **Use default

154 rule**. **Debug/CDP** controls full Chrome DevTools Protocol access for browser

155 debugging. **Allow** lets normal policy and approval checks continue.

1561. Review **Auto-review**, **Always allow**, and **Approval duration** for the site.

157 **Approval duration** offers **This turn** and **This thread**. Review **Browser

158 history**, **Save site approvals**, and **Auto-approve requests** in **Desktop

159 browser controls** as well.

1601. Choose **Add rule**, review validation messages, and select **Save changes**.

161 Test an allowed site and a blocked site on a supported client that receives the policy. Test

162 uploads, downloads, and other restricted actions separately.

20 163 

21<span164{/* vale Microsoft.Auto = YES */}

22 id="agent-security-and-local-computer-access"

23 data-localization-body-anchor

24/>

25 165 

26## Agent Security and Local computer access with Work Cloud

27 166 

28Use Agent Security in the Admin Console to manage policies and configuration. It replaces Policies & Configuration. Agent Security will be available to everyone, independently of Local computer access with Work Cloud. Existing policies, assignments, and ordering are preserved. Review your existing policies in Agent Security. Local computer access with Work Cloud is a separate opt-in. See [Agent Security](https://learn.chatgpt.com/docs/enterprise/agent-security) for migration guidance.

29 167 

30Before moving policy automation to **Agent Security**:168> Illustration: Agent Security site-rule editor with site access, transfers, debugging, and approval controls.

31 169 

321. Identify affected integrations. Inventory Terraform configurations and scripts that update policies, and record which policies they manage.

33 170 

341. Use the policy API to manage Global settings. To manage Local or Codex Cloud settings, use the Agent Security UI. Existing Global API workflows remain available after migration. Test your scripts and Terraform integrations, and confirm that policy assignments and ordering are unchanged.

35 171 

361. Make any required changes and test the automation. Verify that an intended update reaches the correct Agent Security policy and that the resulting controls are enforced.172Disabling automatic review for browser actions sends those actions to the user for

173approval instead. It doesn't disable model safety monitoring.

37 174 

38Policy migration does not grant local computer access for Work or dots. Reviewing or creating policies is recommended before rollout, but the confirmation flow does not require policy creation to enable access. Before enabling **Allow local computer access**, review the migrated baseline or create a cloud baseline if your policies are currently delivered only through MDM. If `enforce_residency` is enabled in any cloud policy, **Allow local computer access** is disabled for both Work and dots. This safeguard does not configure workspace residency or, by itself, disable Work Cloud or dots.175When several origin patterns match, the most restrictive value wins for each

176setting. Local configuration can't relax a managed denial. Managed network denies

177and exclusive allowlists also apply to browser tools. See the [browser policy

178fields](https://learn.chatgpt.com/docs/config-file/config-reference#requirementstoml) for origin patterns

179and approval behavior.

39 180 

40Environment overrides vary supported settings within a policy. Within a given policy, the order from highest to lowest is OS-specific environment override → all-OS environment override → Global. A higher-priority policy still wins over a lower-priority policy, even when the lower-priority policy is more specific. Some requirements have field-specific merge rules. Confirm which override editors and fields are available for your workspace.181Computer Use can also operate a browser as a native app. Browser Use site and

182capability rules don't apply to that path. Review native-app access separately;

183see the [browser security

184boundaries](https://learn.chatgpt.com/docs/enterprise/chatgpt-work-local-security#browser-sessions-and-existing-sign-ins).

41 185 

42When managed policy and remote hooks are enabled, Work Cloud with local access and dots use admin-managed remote MCP hooks on the cloud orchestrator. Configure `mcp_tool` handlers in Global `requirements.toml`. Work Cloud without local access and personal accounts do not use these enterprise hooks. Command/shell, prompt, and agent handlers; hooks from local configuration, plugins, or local directories; environment-scoped hooks; and `SessionEnd` MCP hooks are not supported with cloud orchestration, even when tools execute locally. When both orchestration and execution are local, existing supported hooks continue to work in local-only Work and Codex threads. Admins can still configure supported managed hooks in Agent Security for those workflows. Before relying on these hooks, test callback connectivity, required events, and failure behavior. An explicit supported denial can block an action, but a `PreToolUse` callback error, timeout, or malformed response can fail the hook without blocking the tool. MCP hooks do not provide a complete Compliance API audit trail. See the [Configuration Reference](https://learn.chatgpt.com/docs/config-file/config-reference).186### Configure native-app access

43 187 

44## Configure plugin marketplaces and defaults1881. In **Requirements**, go to **Desktop app controls > App rules**.

1891. Use the **Default** row's actions to configure access for apps without a matching

190 rule. To limit Computer Use to approved apps, block access by default and add

191 allow rules for those apps.

1921. Choose **Add app rule**. In the **Edit rule** dialog, select **macOS bundle ID**,

193 **Windows AUMID**, or **Windows executable** from **App**. Enter the exact **App

194 identifier** for a bundle ID or Application User Model ID (AUMID). For **Windows

195 executable**, enter **Publisher name** and **Product name**; **Binary name** is

196 optional. Use verified app identity information, not a display name or file path.

1971. Set **App access** for the rule, then choose **Add rule**. Review **Save app

198 approvals** under **Desktop app controls**, review validation messages, and

199 select **Save changes**. Disabling saved approvals still permits approvals for the current

200 session; allowing saved approvals doesn't approve an app.

2011. Test an allowed app and a blocked app on each supported operating system in

202 your deployment. Confirm that operating-system permissions still apply and that users must still provide required approvals.

45 203 

46Define local or Git marketplaces and plugin defaults in system `config.toml`

47or the supported configuration defaults in **Agent Security**.

48These settings are defaults, not enforced policy.

49 204 

50See [Configuration Reference](https://learn.chatgpt.com/docs/config-file/config-reference) for configuration keys,

51[Configuration precedence](https://learn.chatgpt.com/docs/config-file/config-basic#configuration-precedence)

52for overrides, and [repo plugin settings](https://developers.openai.com/plugins/build/plugins#enable-or-disable-a-plugin-for-a-repo)

53for project-level configuration. [Workspace GitHub import and

54sync](https://learn.chatgpt.com/docs/enterprise/plugin-management) is separate.

55 205 

56## Admin-enforced requirements (requirements.toml)206> Illustration: Agent Security native-app rule editor showing macOS bundle ID, app identifier, and app access.

57 207 

58Requirements constrain security-sensitive settings (approval policy, approvals reviewer, automatic review policy, sandbox mode, permission profiles, web search mode, managed hooks, which MCP servers users can enable, and which plugin marketplace sources they can use). When resolving configuration (for example from `config.toml`, [profile files](https://learn.chatgpt.com/docs/config-file/config-advanced#profiles), or CLI config overrides), if a value conflicts with an enforced rule, the local client falls back to a compatible value and notifies the user. If you configure an `mcp_servers` allowlist, the client enables an MCP server only when both its name and identity match an approved entry; otherwise, the client disables it.

59 208 

60Requirements can also constrain [feature flags](https://learn.chatgpt.com/docs/config-file/config-basic#feature-flags) via the `[features]` table in `requirements.toml`. Note that features aren't always security-sensitive, but enterprises can pin values if desired. Omitted keys remain unconstrained.

61 209 

62For Codex 0.138.0 or later, prefer [permission profiles](https://learn.chatgpt.com/docs/permissions)210See the [Computer Use policy

63with `allowed_permission_profiles` and managed `default_permissions`. Use211fields](https://learn.chatgpt.com/docs/config-file/config-reference#requirementstoml) for Windows identity

64`allowed_sandbox_modes` only for legacy deployments that still configure212requirements and [locked-use restrictions](#restrict-locked-computer-use) for

65`sandbox_mode`.213managed Macs.

66 214 

67For the exact key list, see the [`requirements.toml` section in Configuration Reference](https://learn.chatgpt.com/docs/config-file/config-reference#requirementstoml).215### Check the effective policy

68 216 

69### Migrate the retired `untrusted` approval policy217If an allowed site or app is still blocked, check other matching rules, policy

70 218assignments and priority, device requirements, and user configuration. An allow

71Codex and ChatGPT Work no longer support `approval_policy = "untrusted"`.219rule in one source doesn't bypass another applicable denial. See [requirements

72Remove it from managed defaults, legacy `managed_config.toml`, and any user,220locations and precedence](#locations-and-precedence).

73project, profile, or startup configuration that sets it.

74 221 

75For interactive, read-only use, select `approval_policy = "on-request"` with a222If a setting has no effect, verify that the client, operating system, and policy

76read-only sandbox or permission profile allowed by your managed requirements.223delivery path support it. Pay particular attention to Work Cloud with local

77Commands allowed by that sandbox can run without approval.224computer access: some fields have partial support or require validation. See

225[Work compatibility in the Configuration Reference](https://learn.chatgpt.com/docs/config-file/config-reference).

78 226 

79To keep stricter command approvals, omit an explicit `approval_policy`, set227Check [workspace permissions](https://learn.chatgpt.com/docs/enterprise/roles-and-workspace-permissions)

80`trust_level = "untrusted"` in the project's entry in user-level228and [plugin controls](https://learn.chatgpt.com/docs/enterprise/apps-and-connectors) separately when a user

81`~/.codex/config.toml`, and keep `untrusted` in `allowed_approval_policies`.229can't access the feature or required plugin.

82This also disables project-local configuration. Setting `on-request` explicitly

83overrides that policy. See

84[Migrate from the retired `untrusted` approval policy](https://learn.chatgpt.com/docs/agent-approvals-security#migrate-from-the-retired-untrusted-approval-policy)

85for examples and security tradeoffs.

86 230 

87### Locations and precedence231### TOML configuration reference

88 232 

89For local execution, requirements are applied from lower to higher priority as follows. This ordering also applies to local steps in Local computer access with Work Cloud:233The following examples describe the same policy intent for `requirements.toml`.

234Use them when managing policy through files or the TOML editor. You don't need to

235edit a local file to use the controls available in Agent Security.

90 236 

911. System `requirements.toml` (`/etc/codex/requirements.toml` on Unix systems,237This browser example denies access by default, allows `https://example.com`, blocks

92 including Linux and macOS, or `%ProgramData%\OpenAI\Codex\requirements.toml`238uploads and full CDP access there, and limits site-access approval to the current

93 on Windows).239turn:

942. Agent Security requirements delivered in the cloud config bundle.

953. Legacy `managed_config.toml` fields that the local client reinterprets as requirements.

964. macOS managed preferences (MDM) delivered through

97 `com.openai.codex:requirements_toml_base64`.

98 

99Higher-precedence layers override ordinary scalar and list values from lower

100layers. Tables merge by key, while requirements such as rules, hooks, and

101filesystem restrictions have field-specific composition behavior. Use the

102[`requirements.toml` reference](https://learn.chatgpt.com/docs/config-file/config-reference#requirementstoml)

103for the current schema instead of assuming that every field merges the same

104way.

105 

106For backward compatibility, supported local clients reinterpret the legacy

107`approval_policy`, `approvals_reviewer`, and `sandbox_mode` fields as

108requirements. This conversion adds compatibility choices where necessary; use

109`requirements.toml` for explicit allowlists.

110 240 

241```toml

242[browser_use]

243allow_history_access = false

244allow_global_persistent_approval = false

111 245 

246[browser_use.default_origin_policy]

247access = "deny"

112 248 

249[browser_use.origins."https://example.com"]

250access = "allow"

251uploads = "deny"

252downloads = "allow"

253full_cdp_access = "deny"

254persistent_approval = false

255access_approval_lifetime = "turn"

256```

113 257 

114### Precedence for Local computer access with Work Cloud258To disable automatic review for browser actions, set

259`browser_use.disable_auto_review = true`, or set `auto_review = "deny"` on an

260origin policy to restrict it for that origin.

115 261 

116For Work with local access and dots, distinguish Global orchestrator policy from execution policy. Applicable local requirements govern the connected computer. Work cloud containers and dots cloud computers use their own execution configuration and requirements, rather than the managed environment bundle used by other executors.262To enable [Site tools](https://learn.chatgpt.com/docs/webmcp) for an eligible Enterprise workspace,

263set `browser_use.allow_webmcp = true`. This managed opt-in applies to the

264desktop app's built-in browser. Setting it to `false` or omitting it leaves

265normal feature availability checks in place; `false` does not enforce a block.

266User preferences and site permissions still apply.

117 267 

118For local execution, MDM and legacy managed-device requirements rank above Agent Security. The device's system requirements file ranks below Agent Security. Within each policy, resolve OS-specific environment overrides before all-OS environment overrides, then Global. Policy priority wins over specificity across policies.268This native-app example allows Calculator on macOS, denies other apps by default,

269and prevents app approvals from persisting across sessions:

119 270 

120| Control | Local Work without sync and local Codex | Local computer access with Work Cloud |271```toml

121| ----------------------------- | ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |272[computer_use]

122| Enterprise requirements | Follow the local requirements order above. | Apply to local executors. Work cloud containers retain existing Work Cloud policies. |273default_app_access = "deny"

123| Device execution restrictions | Enforced by supported local controls. | Follow the local requirements order above, including MDM and legacy requirements above Agent Security. |274allow_persistent_approval = false

124| Environment overrides | Use the configuration model for the relevant product. | Within one policy: OS-specific environment override, then all-OS environment override, then Global. A lower-priority policy cannot win through specificity. |

125 275 

126Requirements impose constraints, while configuration defaults supply starting values. For Work with local access and dots, supported Global policy applies through the shared cloud orchestrator when managed policy is enabled. Applicable local `requirements.toml` requirements govern execution on a connected computer. Work cloud containers and dots cloud computers use their own execution configuration and requirements, rather than the managed environment bundle used by other executor types. Local execution restrictions do not automatically apply to these cloud computers. Review cloud capability permissions and test local and cloud execution separately.276[computer_use.macos.bundle_ids]

277"com.apple.calculator" = "allow"

278```

127 279 

128Keep orchestrator controls, including approvals and web search, in Global. Use the dedicated Allowed approval policies and Allowed web search modes controls where available, and TOML for other supported fields. See the [Configuration Reference](https://learn.chatgpt.com/docs/config-file/config-reference) for the field list and execution scope.280Windows policies can identify packaged apps with `computer_use.windows.aumids` or

281executables with `computer_use.windows.exes`. Executable rules require

282`publisher_name`, `product_name`, and `access`; `binary_name` is optional.

129 283 

130### Network policy precedence and runtime limits284For all supported fields and values, use the

285[`requirements.toml` reference](https://learn.chatgpt.com/docs/config-file/config-reference#requirementstoml).

286To disable a capability rather than restrict individual sites or apps, see

287[Pin feature flags](#pin-feature-flags).

131 288 

132Within a given policy, the order from highest to lowest is OS-specific environment override → all-OS environment override → Global. A higher-priority policy still wins over a lower-priority policy, even when the lower-priority policy is more specific. Some requirements have field-specific merge rules. The runtime then enforces the resolved requirements. Consider the field-specific network cases below separately from policy priority.289### Other desktop controls

133 290 

134These examples compare environment and Global settings within the same policy, with managed networking already configured and no higher-priority policy changing the values. They describe field-specific merge and runtime behavior.291The following desktop controls cover feature availability, Locked Use, Appshots, and device remote control. Use dedicated settings for feature availability and Locked Use; configure Appshots and device remote control with **Edit as TOML**. For destination restrictions on desktop-app traffic, see [Control desktop app network destinations](#control-desktop-app-network-destinations).

135 292 

136#### Set different domain access by environment293#### Pin feature flags

137 294 

138For the same domain rule within a policy, an admin environment override can allow a domain denied in Global or deny a domain allowed in Global. Without an environment override, the Global rule is inherited. Other effective Deny rules or access controls can still block a request.295For desktop features exposed in Agent security, open **Global** > **Requirements** > **Desktop feature availability**. Set **In-app browser**, **Browser use**,

296**External browser use**, or **Computer use** to **Force off** to disable that

297capability, then select **Save changes**. For **Full CDP access**, choose

298**Block user opt-in** to prevent users from enabling it. Allowing a feature doesn't override its product, platform, or rollout availability.

139 299 

140**How domain rules combine**300For other supported [feature flags](https://learn.chatgpt.com/docs/config-file/config-basic#feature-flags),

301use **Edit as TOML** and the Global `requirements.toml` document, or a supported

302local requirements source. The following examples include both runtime and

303desktop-specific feature pins:

141 304 

142| Global rule | Environment rule | Domain-policy result |305```toml

143| ------------- | ---------------- | --------------------------------------------------------------------- |306[features]

144| Deny | Allow | Allowed by the environment override, subject to the conditions below. |307hooks = true

145| Allow | Deny | Blocked in that environment. |308unified_exec = false

146| Allow | Allow | Allowed by these domain rules. |

147| Deny | Deny | Blocked by these domain rules. |

148| Allow or Deny | No override | Inherits the Global rule. |

149 309 

150These outcomes compare the same domain key within one policy, with no higher-priority policy changing the result. A higher-priority value replaces the same key. Other inherited keys remain. An Allow does not bypass a different matching Deny, such as an inherited wildcard. An empty environment map does not clear inherited rules.310# Disable surface-specific features when needed.

311browser_use = false

312browser_use_full_cdp_access = false

313browser_use_external = false

314in_app_browser = false

315in_app_updates = false

316computer_use = false

317```

151 318 

152**Example:** Deny `packages.example.com` in Global and allow it in Development. Development can permit it under the conditions above. Production inherits the Global Deny unless overridden.319Use the canonical feature keys from `config.toml`'s `[features]` table for

320runtime features. The local runtime normalizes recognized features to meet these

321pins and rejects conflicting writes to `config.toml` or profile file feature

322settings.

153 323 

154Confirm the deployed executor supports these merge rules. Coverage for regular managed executors still needs validation.324A managed `unified_exec = false` keeps command execution available, but disables

325resumable processes and the `write_stdin` tool. User configuration can't disable

326this feature.

155 327 

156Orchestrator limits. Managed HTTP/SOCKS listener ports and non-loopback proxy listeners are unsupported by the cloud runtime; socket-rule support depends on the execution path. A local-execution setting in the table below is not a supported Orchestrator configuration.328<a id="disable-codex-feature-surfaces"></a>

157 329 

158#### Other network runtime limits330- `in_app_browser = false` disables the built-in browser pane.

331- `in_app_updates = false` disables the ChatGPT desktop app's own updater on

332 restart, where supported. It doesn't affect external package deployment or

333 extend support for older app versions. For setup and rollout guidance, see

334 [Manage app updates](https://learn.chatgpt.com/docs/enterprise/manage-app-updates).

335- `browser_use = false` disables supported Browser Use capabilities. External

336 Browser Use and native-app Computer Use have separate controls.

337- `browser_use_full_cdp_access = false` disables full CDP access in the local

338 runtime, including Browser Developer mode, and prevents the ChatGPT desktop

339 app from enabling the corresponding setting.

340- `browser_use_external = false` disables agent-driven Browser Use through

341 supported browser extensions.

342- `computer_use = false` disables native-app Computer Use, including operating

343 a browser as a native app, along with Record & Replay and related install or

344 setup flows.

345 

346**Disabling Browser Use alone does not block every browser path.** Native-app

347Computer Use can still operate a browser when that capability and app access are

348allowed; Browser Use site and capability rules do not apply to that path. To

349block it, set **Computer use** to **Force off** (`computer_use = false`), or

350[deny the browser app in App rules](#configure-native-app-access) if other native

351apps should remain available. Review **External browser use** and **In-app

352browser** separately. See [browser sessions and existing

353sign-ins](https://learn.chatgpt.com/docs/enterprise/chatgpt-work-local-security#browser-sessions-and-existing-sign-ins)

354for the controls that apply to each path.

159 355 

160All field names below are under `experimental_network` in `requirements.toml`. The arrows show a Global value followed by an environment value within the same policy. These local-execution cases do not establish Orchestrator support for the same settings.356If you omit these keys, policy allows the features, subject to normal client,

357platform, and rollout availability.

161 358 

162| **Setting and attempted override** | **Runtime behavior** | **Admin action** |359#### Restrict locked computer use

163| -------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |

164| domains: deny → allow | The environment Allow replaces the same Global domain key on supported paths. Other matching Deny rules still apply. | Test both allowed and blocked requests on the deployed executor. |

165| `managed_allowed_domains_only`: true → false | Do not infer exclusivity behavior from domain-key composition. With effective `enabled = true` and `managed_allowed_domains_only = true`, ordinary commands need effective Allow entries. | Review effective settings and inherited Allow entries. A deny-only policy does not allow the rest of the internet. |

166| `allow_local_binding`: false → true | On the supported Codex Cloud proxy path, an explicit false can prevent upstream-proxy access. A supported higher-priority Cloud override can change it. | Check the source of the effective value and executor support. Do not apply the Cloud default to Local. |

167 360 

168Proxy activation, exclusivity, upstream-proxy behavior, and Unix-socket rules have executor-specific behavior. Do not generalize domain-key composition to these settings. Verify the effective values and test the deployed runtime. For Codex Cloud local/private connectivity, see [Configure network access requirements](#configure-network-access-requirements).361To prevent users from enabling [Locked Use](https://learn.chatgpt.com/docs/computer-use#locked-use)

362on a managed Mac, open **Global** > **Requirements** > **Desktop app controls**,

363set **Allow use while locked** to **Disabled**, and select **Save changes**.

364This setting doesn't turn off Locked Use on a Mac where it's already enabled.

169 365 

170#### Verify behavior before rollout366The equivalent requirement for the TOML editor or device-managed delivery is:

171 367 

172Test the actual destinations, local listeners, proxy behavior, and socket paths your workflows use. Check an action that should succeed and one that should be blocked in each affected environment. Check that the deployed runtime version supports each setting you use.368```toml

369[computer_use]

370allow_locked_computer_use = false

371```

173 372 

174### Cloud-managed requirements373This requirement removes the controls for enabling Locked Use. It doesn't

374turn off Locked Use if it's already enabled. If you omit it, normal product

375availability and the user's local setting still apply.

175 376 

176When a user signs in with ChatGPT on a supported plan, supported local clients377#### Disable Appshots

177can receive admin-enforced requirements associated with the workspace. This is

178a delivery channel for `requirements.toml`-compatible policy. It doesn't grant

179workspace access or replace workspace RBAC. Authentication requirements must be

180[managed locally](#manage-authentication-locally).

181 378 

182Open **Agent Security** in the Admin Console to review and manage cloud379Appshots let supported clients include application snapshots. To disable them

183requirements. Use the migrated global baseline for existing policies. For380for cloud-managed users, open **Edit as TOML** in Agent security and set the

184example, this policy limits381top-level `allow_appshots` field in Global `requirements.toml`. For device-managed

185approval and sandbox choices and prompts before a supported shell entry point382deployments, use the applicable local requirements source:

186runs:

187 383 

188```toml384```toml

189allowed_approval_policies = ["on-request"]385allow_appshots = false

190allowed_sandbox_modes = ["read-only", "workspace-write"]

191 

192[rules]

193prefix_rules = [

194 { pattern = [{ any_of = ["bash", "sh", "zsh"] }], decision = "prompt", justification = "Require explicit approval for shell entry points" },

195]

196```386```

197 387 

198Check that every managed client version supports the keys you select. Assign the policy to the intended users or groups and verify that it takes effect on their supported clients. Use388Where Appshots are available, `allow_appshots = false` disables them. If you

199the configuration reference for the current schema and the administration389omit the key, requirements don't constrain Appshots, and normal product

200surface for current assignment behavior.390availability checks apply. App-server clients that read effective requirements

391through `configRequirements/read` receive the same restriction as

392`allowAppshots`; an omitted or `null` `allowAppshots` value doesn't disable

393Appshots.

201 394 

202The service selects the enterprise-managed requirement layers that apply to the395#### Disable device remote control

203signed-in identity. The local client evaluates those layers with the other

204requirements sources described in [Locations and precedence](#locations-and-precedence).

205Use the current administration surface for workspace-side creation and

206assignment. Don't rely on a copied group-matching algorithm; the administration

207service owns that behavior and can change it independently of the local

208requirements format.

209 396 

210For supported keys and examples, see397To disable [device remote control](https://learn.chatgpt.com/docs/remote-connections#pick-up-work-from-another-device)

211[Example requirements.toml](#example-requirementstoml) and the398for cloud-managed users, use **Edit as TOML** in Agent security and set the

212[`requirements.toml` reference](https://learn.chatgpt.com/docs/config-file/config-reference#requirementstoml).399top-level `allow_remote_control` field in Global `requirements.toml`. You can

400also set `allow_remote_control` in a supported local requirements source:

213 401 

214#### How local clients apply cloud-managed requirements402```toml

403allow_remote_control = false

404```

215 405 

216The local loading and cache behavior below describes supported local clients. It does not establish when a changed cloud policy takes effect in an already-running task using Local computer access with Work Cloud. Verify the effective policy before relying on a changed restriction.406Where device remote control is supported, `allow_remote_control = false`

407disables it. If you omit the key, requirements don't constrain device remote

408control, and normal product availability checks apply. This requirement doesn't

409disable SSH remote connections.

217 410 

218When a user starts a supported local client and signs in with ChatGPT on a411## Set approvals and execution permissions

219supported plan, the client first checks for a valid, identity-matched cache

220entry. If no valid entry is available, the client fetches the applicable bundle

221with retries and writes a signed cache entry on success. If the request fails or

222times out and no valid cache is available, the cloud config bundle load returns

223an error rather than silently starting without the cloud-managed requirements

224layer.

225 412 

226After cache resolution, the client composes the cloud requirements with the413Use this section to set approval behavior, permission boundaries, and starting defaults. Begin with [Policy guardrails](#set-approval-sandbox-and-web-search-guardrails) and [Defaults](#set-configuration-defaults). The later tasks explain TOML requirements for reviewer enforcement, custom permission profiles, filesystem restrictions, host overrides, and command rules.

227other requirements layers described above. A background refresh can update the

228cache for a later start; it doesn't replace the requirements already loaded

229into the current process.

230 414 

231### Confirm the admin and employee experience415### Admin-enforced requirements (requirements.toml)

232 416 

233Assign a person to own each managed policy, record which users or groups should417Requirements constrain security-sensitive settings (approval policy, approvals reviewer, automatic review policy, sandbox mode, permission profiles, web search mode, managed hooks, which MCP servers users can enable, and which plugin marketplace sources they can use). When resolving configuration (for example from `config.toml`, [profile files](https://learn.chatgpt.com/docs/config-file/config-advanced#profiles), or CLI config overrides), if a value conflicts with an enforced rule, the local client falls back to a compatible value and notifies the user. If you configure an `mcp_servers` allowlist, the client enables an MCP server only when both its name and identity match an approved entry; otherwise, the client disables it.

234receive it, and document the business reason for any filesystem, network,

235approval, or permission-profile restriction.

236 418 

237Test an allowed workflow and a blocked workflow with a user who has the intended permissions. Check the effective settings in the supported client. A workspace role or group alone does not enforce a local runtime restriction.419Requirements can also constrain [feature flags](https://learn.chatgpt.com/docs/config-file/config-basic#feature-flags) via the `[features]` table in `requirements.toml`. Note that features aren't always security-sensitive, but enterprises can pin values if desired. Omitted keys remain unconstrained.

238 420 

239### Manage authentication locally421For Codex 0.138.0 or later, prefer [permission profiles](https://learn.chatgpt.com/docs/permissions)

422with `allowed_permission_profiles` and managed `default_permissions`. Use

423`allowed_sandbox_modes` only for legacy deployments that still configure

424`sandbox_mode`.

240 425 

241Set `allowed_login_methods`, `allowed_chatgpt_workspaces`,426For the exact key list, see the [`requirements.toml` section in Configuration Reference](https://learn.chatgpt.com/docs/config-file/config-reference#requirementstoml).

242`cli_auth_credentials_store`, and `chatgpt_base_url` in the local system

243`requirements.toml` or macOS MDM requirements. Codex ignores these four fields

244in cloud-managed requirements. Local authentication requirements apply before

245credentials load and before Codex retrieves cloud policy.

246 427 

247To require ChatGPT login to an approved workspace and store credentials in the428### Set approval, sandbox, and web search guardrails

248OS credential store, use:429 

430Use **Requirements** > **Policy guardrails** to limit supported client choices.

431These controls constrain configuration; they don't select the starting value.

432Set the starting value separately under **Defaults**.

433 

4341. In **Global**, open **Approval policies** and select the allowed approval

435 styles. For example, **Ask when needed** allows the agent to request approval

436 for actions such as sandbox escalation. **Never ask** prevents approval

437 requests; it doesn't grant unrestricted execution.

4381. Open **Sandbox modes** to limit legacy sandbox choices. **Read-only** restricts

439 writes, **Workspace write** permits writes within the workspace and configured

440 writable roots, and **Full access** removes filesystem sandboxing. Use

441 [permission-profile requirements](#control-available-permission-profiles) for

442 deployments that use permission profiles instead of `sandbox_mode`.

4431. In **Global**, open **Web search modes** to limit web search. Choose **Cached**

444 to permit cached search without live search, or **Disabled** to turn off web

445 search. Web search restrictions are separate from command network rules.

4461. Review the allowed choices and corresponding defaults, then select

447 **Save changes**.

448 

449Leaving a requirement unset imposes no limit under that policy. Other

450applicable policies still apply. The **Ask for untrusted commands** option

451corresponds to `untrusted` in the requirements allowlist; it doesn't restore the

452retired explicit `approval_policy = "untrusted"` setting. Follow the migration

453guidance below for that case.

454 

455To constrain web search, use **Global** > **Requirements** > **Policy guardrails** > **Web search modes**. The equivalent TOML is:

249 456 

250```toml457```toml

251allowed_login_methods = ["chatgpt"]458allowed_web_search_modes = ["cached"] # "disabled" remains implicitly allowed

252allowed_chatgpt_workspaces = ["00000000-0000-0000-0000-000000000000"]

253cli_auth_credentials_store = "keyring"

254```459```

255 460 

256`allowed_login_methods` accepts `chatgpt`, `api`, or both. If omitted, this setting461`allowed_web_search_modes = []` allows only `"disabled"`.

257doesn't restrict login methods. If set, the list must contain at least one method.462For example, `allowed_web_search_modes = ["cached"]` prevents live web search even in `danger-full-access` sessions.

258`api` permits API authentication, including Amazon Bedrock.

259The workspace restriction also applies to

260[Codex access tokens](https://learn.chatgpt.com/docs/enterprise/access-tokens).

261 463 

262User-configured `forced_login_method` and `forced_chatgpt_workspace_id` must464### Set configuration defaults

263follow the requirements. When a user selects a workspace, it must also appear

264in the managed workspace allowlist. If no workspaces match, ChatGPT login is

265unavailable. API authentication remains available when permitted. If no login method

266is available, Codex refuses to start.

267 465 

268See the [requirements reference](https://learn.chatgpt.com/docs/config-file/config-reference#requirementstoml)466Defaults give members a starting configuration. They don't enforce a

269for credential storage modes and service URL configuration.467restriction or grant access to a workspace capability.

468 

4691. Open the policy's **Defaults** card. Keep agent-wide defaults in **Global**;

470 use an available environment tab for supported execution defaults.

4711. Under **Command execution**, choose the starting **Approval policy** and

472 **Approval reviewer**, and the applicable **Sandbox mode** or **Default

473 permissions**. The reviewer determines who reviews approval requests by

474 default; the approval policy determines when requests can occur.

4751. Under **Web search**, choose the starting **Web search** mode and **Web search

476 context**. Under **Apps and tools**, review **Apps/connectors**, **Open-world

477 tools**, and **Destructive tools** for supported app tools.

4781. Confirm the defaults meet your **Requirements**, then select **Save changes**.

479 

480Use **Edit as TOML** for supported defaults without visual controls, such as

481plugin marketplace configuration. These cloud defaults use [normal configuration

482precedence](https://learn.chatgpt.com/docs/config-file/config-basic#configuration-precedence). They differ

483from the [legacy `managed_config.toml` precedence](#precedence-and-layering),

484which places managed defaults above local configuration at startup.

270 485 

271### Example requirements.toml486### Example requirements.toml

272 487 


281`trust_level = "untrusted"`; it does not make `approval_policy = "untrusted"` a496`trust_level = "untrusted"`; it does not make `approval_policy = "untrusted"` a

282supported explicit setting.497supported explicit setting.

283 498 

284### Disable Appshots499### Migrate the retired `untrusted` approval policy

285 500 

286To disable Appshots for managed users, set the top-level `allow_appshots` requirement:501Codex and ChatGPT Work no longer support `approval_policy = "untrusted"`.

502Remove it from managed defaults, legacy `managed_config.toml`, and any user,

503project, profile, or startup configuration that sets it.

287 504 

288```toml505For interactive, read-only use, select `approval_policy = "on-request"` with a

289allow_appshots = false506read-only sandbox or permission profile allowed by your managed requirements.

290```507Commands allowed by that sandbox can run without approval.

291 508 

292Where Appshots are available, `allow_appshots = false` disables them. If you509To keep stricter command approvals, omit an explicit `approval_policy`, set

293omit the key, requirements don't constrain Appshots, and normal product510`trust_level = "untrusted"` in the project's entry in user-level

294availability checks apply. App-server clients that read effective requirements511`~/.codex/config.toml`, and keep `untrusted` in `allowed_approval_policies`.

295through `configRequirements/read` receive the same restriction as512This also disables project-local configuration. Setting `on-request` explicitly

296`allowAppshots`; an omitted or `null` `allowAppshots` value doesn't disable513overrides that policy. See

297Appshots.514[Migrate from the retired `untrusted` approval policy](https://learn.chatgpt.com/docs/agent-approvals-security#migrate-from-the-retired-untrusted-approval-policy)

515for examples and security tradeoffs.

298 516 

299### Disable device remote control517### Configure automatic review policy

300 518 

301To disable [device remote control](https://learn.chatgpt.com/docs/remote-connections#pick-up-work-from-another-device)519To make automatic review the default, use **Global** > **Defaults** > **Command execution** > **Approval reviewer**. A default lets users choose

302for managed users, set the top-level `allow_remote_control` requirement:520another permitted reviewer. To require automatic review or supply your

521organization's review instructions, use **Edit as TOML** and edit Global

522`requirements.toml` instead. These requirements are separate from the browser's

523automatic-review controls.

524 

525Use `allowed_approvals_reviewers` to require or allow automatic review. Set it

526to `["auto_review"]` to require automatic review, or include `"user"` when users

527can choose manual approval.

528 

529Set `guardian_policy_config` to replace the tenant-specific section of the

530automatic review policy. The local runtime still uses the built-in reviewer

531template and output contract. Managed `guardian_policy_config` takes precedence

532over local `[auto_review].policy`.

303 533 

304```toml534```toml

305allow_remote_control = false535allowed_approval_policies = ["on-request"]

306```536allowed_approvals_reviewers = ["auto_review"]

307 537 

308Where device remote control is supported, `allow_remote_control = false`538guardian_policy_config = """

309disables it. If you omit the key, requirements don't constrain device remote539## Environment Profile

310control, and normal product availability checks apply. This requirement doesn't540- Trusted internal destinations include github.com/my-org, artifacts.example.com,

311disable SSH remote connections.541 and internal CI systems.

542 

543## Tenant Risk Taxonomy and Allow/Deny Rules

544- Treat uploads to unapproved third-party file-sharing services as high risk.

545- Deny actions that expose credentials or private source code to untrusted

546 destinations.

547"""

548```

312 549 

313### Control available permission profiles550### Control available permission profiles

314 551 

552Use **Defaults** > **Command execution** > **Default permissions** to choose the built-in profile users start with. To enforce which profiles users can select or to define

553custom profiles, use **Edit as TOML** and configure `requirements.toml` for the

554applicable Global or supported execution environment scope. Choosing a default

555alone doesn't restrict the available profiles.

556 

315Use `allowed_permission_profiles` to control which built-in and custom557Use `allowed_permission_profiles` to control which built-in and custom

316[permission profiles](https://learn.chatgpt.com/docs/permissions) users can select. This is the558[permission profiles](https://learn.chatgpt.com/docs/permissions) users can select. This is the

317permission-profile counterpart to `allowed_sandbox_modes`; use the allowlist that559permission-profile counterpart to `allowed_sandbox_modes`; use the allowlist that


425a loaded config or requirements source. Define custom profiles in managed667a loaded config or requirements source. Define custom profiles in managed

426requirements to control their behavior centrally.668requirements to control their behavior centrally.

427 669 

670### Enforce deny-read requirements

671 

672Use **Edit as TOML** to add filesystem restrictions to the applicable Global or

673supported execution environment `requirements.toml`. These restrictions block

674reads of sensitive paths; a read-only default by itself doesn't hide files.

675 

676Admins can deny reads for exact paths or glob patterns with

677`[permissions.filesystem]`. Users can't weaken these requirements with local

678configuration.

679 

680```toml

681[permissions.filesystem]

682deny_read = [

683 # values can be absolute paths...

684 "/**/*.env",

685 # ...or relative to $HOME/%USERPROFILE% using `~`.

686 "~/.ssh",

687 # But relative paths starting with `./` are not allowed.

688]

689```

690 

691When deny-read requirements are present, the local runtime rejects full-access

692permissions and keeps local execution in a read-only or workspace sandbox so it

693can enforce them. On native Windows, managed `deny_read` applies to direct file

694tools; shell subprocess reads don't use this sandbox rule.

695 

428### Override sandbox requirements by host696### Override sandbox requirements by host

429 697 

698Use **Edit as TOML** in Agent security to author host-specific requirements.

699Environment controls select an execution environment; host patterns select

700matching machines within the supported runtime.

701 

430Use `[[remote_sandbox_config]]` when one managed policy should apply different702Use `[[remote_sandbox_config]]` when one managed policy should apply different

431sandbox requirements on different hosts. For example, you can keep a stricter703sandbox requirements on different hosts. For example, you can keep a stricter

432default for laptops while allowing workspace writes on matching dev boxes or CI704default for laptops while allowing workspace writes on matching dev boxes or CI


450`allowed_sandbox_modes`. Host name matching is for policy selection only; don't722`allowed_sandbox_modes`. Host name matching is for policy selection only; don't

451treat it as authenticated device proof.723treat it as authenticated device proof.

452 724 

453You can also constrain web search mode:725### Enforce command rules from requirements

726 

727Use **Edit as TOML** in Agent security to add command rules and MCP server

728restrictions to Global `requirements.toml`. Command rules specify approval or denial

729decisions for matching commands; MCP restrictions limit which server identities

730the client can enable. The **Approval policies** control doesn't author either

731of these rule sets.

732 

733Admins can also enforce restrictive command rules from `requirements.toml`

734using a `[rules]` table. These rules merge with regular `.rules` files, and the

735most restrictive decision still wins.

736 

737Unlike `.rules`, requirements rules must specify `decision`, and that decision

738must be `"prompt"` or `"forbidden"` (not `"allow"`).

454 739 

455```toml740```toml

456allowed_web_search_modes = ["cached"] # "disabled" remains implicitly allowed741[rules]

742prefix_rules = [

743 { pattern = [{ token = "rm" }], decision = "forbidden", justification = "Use git clean -fd instead." },

744 { pattern = [{ token = "git" }, { any_of = ["push", "commit"] }], decision = "prompt", justification = "Require review before mutating history." },

745]

457```746```

458 747 

459`allowed_web_search_modes = []` allows only `"disabled"`.748To restrict which MCP servers a local client can enable, add an `mcp_servers`

460For example, `allowed_web_search_modes = ["cached"]` prevents live web search even in `danger-full-access` sessions.749approved list. For stdio servers, match on `command`; for streamable HTTP

750servers, match on `url`:

751 

752```toml

753[mcp_servers.docs]

754identity = { command = "codex-mcp" }

755 

756[mcp_servers.remote]

757identity = { url = "https://example.com/mcp" }

758```

759 

760The string form of `identity.command` matches only the configured `command`. It

761doesn't inspect `args`, `cwd`, `env`, or `env_vars`.

762 

763To constrain a complete stdio invocation, match the executable and each

764positional argument:

765 

766```toml

767[mcp_servers.internal.identity]

768command = { executable = "/usr/local/bin/codex-mcp", args = [

769 { match = "exact", value = "serve" },

770 { match = "prefix", value = "--workspace=" },

771] }

772```

773 

774The executable, argument count, and argument order must match. Argument and URL

775rules support `exact`, `prefix`, and full-value `regex` matching. Structured

776command rules still don't inspect `cwd`, `env`, or `env_vars`. Plugin-bundled

777MCP servers use the same identity shapes under

778`plugins.<plugin>.mcp_servers.<server>`.

779 

780If `mcp_servers` is present but empty, the local client disables all MCP servers.

781 

782## Configure network access

783 

784Command networking and desktop-app networking use different controls. Start with **Network use controls** for supported command traffic, review the environment and runtime limits, then use the separate desktop-app requirements if needed. Browser site rules remain in [Control browser and Computer Use](#control-browser-and-computer-use).

461 785 

462### Configure network access requirements786### Configure network access requirements

463 787 


469 you have tested it in your environment.793 you have tested it in your environment.

470</WarningTip>794</WarningTip>

471 795 

796Use **Requirements** > **Network use controls** to manage supported command

797networking in Agent security. Configure a shared baseline in **Global**, or an

798available **Local Environments** or **Codex Cloud Environments** tab for

799environment-specific execution settings.

800 

8011. Set **Managed networking** to **On** to apply domain rules to managed command

802 traffic. Adding domain rules alone doesn't activate the managed proxy.

8031. Under **Network rules**, select **Add network rule**. Enter a **Domain** such

804 as `api.openai.com` or `**.example.com`, without a URL scheme or path. Choose

805 **Allow** or **Deny** under **Access**, then select **Save rule** to update the

806 draft. Repeat for other destinations.

8071. Set **Only allow domains added by admins** to **On** if user settings and

808 per-domain approvals must not expand the managed allowlist. Include the

809 required Allow entries; a deny-only list doesn't allow other destinations.

8101. Review **Allow local network access** for workflows that need local listeners

811 or private destinations. Direct local connections may bypass the proxy's

812 domain rules. Review the Codex Cloud connectivity limits below before changing

813 this setting.

8141. Review inherited rules and validation messages, then select **Save changes**.

815 Test a request that should succeed and one that should be blocked in every

816 affected execution environment.

817 

818Setting **Managed networking** to **Off** clears that scope's authored network

819rules and stores an explicit off value; it doesn't disable internet access.

820**Not set** removes that scope's authored network settings so applicable policy

821or runtime defaults can apply. Removing environment settings can reveal inherited

822Global rules. Use **Edit as TOML** for advanced network fields or existing legacy

823domain lists that the visual editor can't represent.

824 

472Use `[experimental_network]` in `requirements.toml` when administrators should825Use `[experimental_network]` in `requirements.toml` when administrators should

473define network access requirements centrally. These requirements are separate826define network access requirements centrally. These requirements are separate

474from the user `features.network_proxy` toggle: they can configure sandbox827from the user `features.network_proxy` toggle: they can configure sandbox


525 878 

526A managed command allowlist applies to commands using the managed proxy. Where policy permits full sandbox escalation and it is approved, that execution can bypass the command proxy. A narrow network grant is different from full sandbox escalation. Configure enforced approval and sandbox requirements for the intended boundary, and test both ordinary and escalated commands.879A managed command allowlist applies to commands using the managed proxy. Where policy permits full sandbox escalation and it is approved, that execution can bypass the command proxy. A narrow network grant is different from full sandbox escalation. Configure enforced approval and sandbox requirements for the intended boundary, and test both ordinary and escalated commands.

527 880 

528> **No effective allowed destinations:** When **Manage Networking** and **Only allow domains added by admins** are On, ordinary managed commands need effective allowed destinations. If no Allow entries are configured or inherited, those commands have no allowed destinations. A deny-only policy does not implicitly allow the rest of the internet. Add required Allow entries and check inherited rules before saving. This restriction applies to the managed command proxy, not every tool or approved full sandbox escalation.881> **No effective allowed destinations:** When **Managed networking** and **Only allow domains added by admins** are On, ordinary managed commands need effective allowed destinations. If no Allow entries are configured or inherited, those commands have no allowed destinations. A deny-only policy does not implicitly allow the rest of the internet. Add required Allow entries and check inherited rules before saving. This restriction applies to the managed command proxy, not every tool or approved full sandbox escalation.

529 882 

530> **Codex Cloud local/private connectivity:** An explicit Off value for local/private connectivity can prevent Codex Cloud from reaching its upstream proxy, even when the destination domain is allowed. Check the final `allow_local_binding` value and identify which policy or setting supplies it. On the supported Cloud proxy path, this defaults to true only when no applicable requirement, selected network profile, or proxy feature setting supplies a value. An inherited false still counts as an explicit setting. Where supported, set a higher-priority Cloud override to change this value for Codex Cloud without changing the Global value used by Local. This does not add domain Allow entries. Verify executor support before relying on the override. Do not apply this Cloud default to Local.883> **Codex Cloud local/private connectivity:** An explicit Off value for local/private connectivity can prevent Codex Cloud from reaching its upstream proxy, even when the destination domain is allowed. Check the final `allow_local_binding` value and identify which policy or setting supplies it. On the supported Cloud proxy path, this defaults to true only when no applicable requirement, selected network profile, or proxy feature setting supplies a value. An inherited false still counts as an explicit setting. Where supported, set a higher-priority Cloud override to change this value for Codex Cloud without changing the Global value used by Local. This does not add domain Allow entries. Verify executor support before relying on the override. Do not apply this Cloud default to Local.

531 884 

532Empty environment requirements inherit Global. Manage Networking Off is not the Cloud environment Internet access Off switch. See [Configure networking in the UI](https://learn.chatgpt.com/docs/enterprise/agent-security#configure-networking-in-the-ui).885When environment requirements are empty, Global requirements apply. **Managed networking** set to

886**Off** is separate from the Cloud environment's Internet access setting. See

887[Agent Security execution controls](https://learn.chatgpt.com/docs/enterprise/agent-security#execution-controls-executor)

888for details about execution scope.

889 

890### Network policy precedence and runtime limits

891 

892Within a given policy, the order from highest to lowest is OS-specific environment override → all-OS environment override → Global. A higher-priority policy still wins over a lower-priority policy, even when the lower-priority policy is more specific. Some requirements have field-specific merge rules. The runtime then enforces the resolved requirements. Consider the field-specific network cases below separately from policy priority.

893 

894These examples compare environment and Global settings within the same policy, with managed networking already configured and no higher-priority policy changing the values. They describe field-specific merge and runtime behavior.

895 

896#### Set different domain access by environment

897 

898For the same domain rule within a policy, an admin environment override can allow a domain denied in Global or deny a domain allowed in Global. Without an environment override, the Global rule is inherited. Other effective Deny rules or access controls can still block a request.

899 

900**How domain rules combine**

901 

902| Global rule | Environment rule | Domain-policy result |

903| ------------- | ---------------- | --------------------------------------------------------------------- |

904| Deny | Allow | Allowed by the environment override, subject to the conditions below. |

905| Allow | Deny | Blocked in that environment. |

906| Allow | Allow | Allowed by these domain rules. |

907| Deny | Deny | Blocked by these domain rules. |

908| Allow or Deny | No override | Inherits the Global rule. |

909 

910These outcomes compare the same domain key within one policy, with no higher-priority policy changing the result. A higher-priority value replaces the same key. Other inherited keys remain. An Allow does not bypass a different matching Deny, such as an inherited wildcard. An empty environment map does not clear inherited rules.

911 

912**Example:** Deny `packages.example.com` in Global and allow it in Development. Development can permit it under the conditions above. Production inherits the Global Deny unless overridden.

913 

914Confirm the deployed executor supports these merge rules. Coverage for regular managed executors still needs validation.

915 

916Orchestrator limits. Managed HTTP/SOCKS listener ports and non-loopback proxy listeners are unsupported by the cloud runtime; socket-rule support depends on the execution path. A local-execution setting in the table below is not a supported Orchestrator configuration.

917 

918#### Other network runtime limits

919 

920All field names below are under `experimental_network` in `requirements.toml`. The arrows show a Global value followed by an environment value within the same policy. These local-execution cases do not establish Orchestrator support for the same settings.

921 

922| **Setting and attempted override** | **Runtime behavior** | **Admin action** |

923| -------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |

924| domains: deny → allow | The environment Allow replaces the same Global domain key on supported paths. Other matching Deny rules still apply. | Test both allowed and blocked requests on the deployed executor. |

925| `managed_allowed_domains_only`: true → false | Do not infer exclusivity behavior from domain-key composition. With effective `enabled = true` and `managed_allowed_domains_only = true`, ordinary commands need effective Allow entries. | Review effective settings and inherited Allow entries. A deny-only policy does not allow the rest of the internet. |

926| `allow_local_binding`: false → true | On the supported Codex Cloud proxy path, an explicit false can prevent upstream-proxy access. A supported higher-priority Cloud override can change it. | Check the source of the effective value and executor support. Do not apply the Cloud default to Local. |

927 

928Proxy activation, exclusivity, upstream-proxy behavior, and Unix-socket rules have executor-specific behavior. Do not generalize domain-key composition to these settings. Verify the effective values and test the deployed runtime. For Codex Cloud local/private connectivity, see [Configure network access requirements](#configure-network-access-requirements).

929 

930#### Verify behavior before rollout

931 

932Test the actual destinations, local listeners, proxy behavior, and socket paths your workflows use. Check an action that should succeed and one that should be blocked in each affected environment. Check that the deployed runtime version supports each setting you use.

533 933 

534### Control desktop app network destinations934### Control desktop app network destinations

535 935 

936Use **Edit as TOML** in Agent security to configure these desktop-specific

937requirements in Global. The **Network use controls** UI manages command

938networking, which is a separate policy.

939 

536Use `[application.network]` in `requirements.toml` to restrict the desktop940Use `[application.network]` in `requirements.toml` to restrict the desktop

537app's network destinations. With `enabled = true`, external requests must use941app's network destinations. With `enabled = true`, external requests must use

538HTTPS or WSS and match an exact domain with an `"allow"` value in942HTTPS or WSS and match an exact domain with an `"allow"` value in


544doesn't impose destination restrictions on native modules or spawned processes,948doesn't impose destination restrictions on native modules or spawned processes,

545and it doesn't govern Work Cloud execution.949and it doesn't govern Work Cloud execution.

546 950 

547### Control browser and Computer Use951## Configure plugins and managed hooks

548 952 

549Use the `[browser_use]` and `[computer_use]` tables in `requirements.toml` to953For these tasks, use **Edit as TOML** in Agent security or a supported local configuration source. Marketplace defaults, enforced plugin restrictions, and managed hooks have different purposes; choose the task that matches the policy you need.

550restrict supported desktop clients. Validate the policy on the client versions

551and operating systems in your deployment. A configured allow rule doesn't

552install a plugin, grant an operating-system permission, or approve an action

553that still requires review.

554 954 

555For browser access, configure an origin policy. An origin includes the scheme,955### Configure plugin marketplaces and defaults

556host, and optional port, such as `https://example.com` or

557`https://*.example.com:8443`. Don't include a path, query, or fragment. Unlike

558command-network domain rules, browser origin rules distinguish HTTP from HTTPS

559and match the port.

560 956 

561This example restricts browser access to an approved site and prevents uploads957Use **Agent security** > **Edit as TOML** to define local or Git marketplaces and

562and full Chrome DevTools Protocol (CDP) access there:958plugin defaults in the Global `config.toml` document. You can also distribute

959these settings in system `config.toml`. They provide starting marketplace and

960plugin configuration, not enforced policy. To limit which sources members can

961use, configure [marketplace source requirements](#restrict-plugin-marketplace-sources).

563 962 

564```toml963See [Configuration Reference](https://learn.chatgpt.com/docs/config-file/config-reference) for configuration keys,

565[browser_use]964[Configuration precedence](https://learn.chatgpt.com/docs/config-file/config-basic#configuration-precedence)

566allow_history_access = false965for overrides, and [repo plugin settings](https://developers.openai.com/plugins/build/plugins#enable-or-disable-a-plugin-for-a-repo)

567allow_global_persistent_approval = false966for project-level configuration. [Workspace GitHub import and

967sync](https://learn.chatgpt.com/docs/enterprise/plugin-management) is separate.

568 968 

569[browser_use.default_origin_policy]969### Control plugin availability

570access = "deny"

571 970 

572[browser_use.origins."https://example.com"]971Use **Edit as TOML** in Agent security for enforced plugin feature settings in

573access = "allow"972Global `requirements.toml`, or distribute them through local requirements for

574uploads = "deny"973device-managed clients. **Defaults** > **Apps and tools** > **Apps/connectors**

575downloads = "allow"974sets app-tool defaults; it isn't the enforced `features.plugins` switch. For

576full_cdp_access = "deny"975workspace plugin permissions, see [Apps and connectors](https://learn.chatgpt.com/docs/enterprise/apps-and-connectors).

577persistent_approval = false976 

578access_approval_lifetime = "turn"977To turn off plugins in supported local clients, set `features.plugins` to

978`false` in `requirements.toml`:

979 

980```toml

981features.plugins = false

579```982```

580 983 

581Matching origin rules are resolved per field. A matching deny wins. Otherwise,984This setting also applies when users sign in to Codex with an API key. See the

582the default origin policy supplies fields that matching rules don't specify.985[`features.plugins`

583Local configuration can add restrictions but can't relax a managed deny.986reference](https://learn.chatgpt.com/docs/config-file/config-reference#requirementstoml) for the

584Network denies and exclusive managed network allowlists still apply.987supported configuration.

585 988 

586Set `browser_use.disable_auto_review = true` to disable automatic approval989### Restrict plugin marketplace sources

587review for browser actions, or set `auto_review = "deny"` on an origin policy

588to restrict it for that origin. This controls approval handling; it doesn't

589disable model safety monitoring.

590 990 

591To enable [Site tools](https://learn.chatgpt.com/docs/webmcp) for an eligible Enterprise workspace,991Use **Edit as TOML** to configure marketplace source requirements in Global

592set `browser_use.allow_webmcp = true`. This managed opt-in applies to the992`requirements.toml`, or deliver them through local requirements. These rules

593desktop app's built-in browser. Setting it to `false` or omitting it leaves993limit which local or Git sources users can add and use. They are separate from

594normal feature availability checks in place; `false` does not enforce a block.994the [marketplace defaults](#configure-plugin-marketplaces-and-defaults).

595User preferences and site permissions still apply.

596 995 

597For native apps, set a default access policy and identify permitted apps. For996To restrict plugin marketplace sources, set

598example, this macOS policy allows Calculator and prevents saved approvals:997`restrict_to_allowed_sources = true` and define one or more source rules:

599 998 

600```toml999```toml

601[computer_use]1000[marketplaces]

602default_app_access = "deny"1001restrict_to_allowed_sources = true

603allow_persistent_approval = false

604 1002 

605[computer_use.macos.bundle_ids]1003[marketplaces.allowed_sources.company_plugins]

606"com.apple.calculator" = "allow"1004source = "git"

1005url = "https://github.com/example/company-plugins.git"

1006ref = "main"

1007 

1008[marketplaces.allowed_sources.internal_git]

1009source = "host_pattern"

1010host_pattern = '^git\.example\.com$'

1011 

1012[marketplaces.allowed_sources.local_plugins]

1013source = "local"

1014path = "/opt/company/codex-plugins"

1015```

1016 

1017Git rules match the normalized repository URL and, when present, an exact

1018`ref`. Host patterns are regular expressions matched against the lowercase Git

1019host; use `^` and `$` for a whole-host match. Local rules require an absolute,

1020normalized path. See the [`requirements.toml` reference](https://learn.chatgpt.com/docs/config-file/config-reference#requirementstoml)

1021for the full schema and merge behavior.

1022 

1023These requirements reject unmatched marketplace add, plugin install, and

1024configured Git marketplace refresh operations. They also filter configured

1025marketplaces and their plugins at runtime.

1026 

1027The OpenAI-curated Git marketplaces, including the API-key catalog, must also

1028match the source allowlist. To allow them, include the following Git source

1029without a `ref` constraint:

1030 

1031```toml

1032[marketplaces.allowed_sources.openai_curated]

1033source = "git"

1034url = "https://github.com/openai/plugins.git"

607```1035```

608 1036 

609Windows policies can identify packaged apps with1037To exclude the curated catalogs, omit that source and ensure no broader host

610`computer_use.windows.aumids` or executables with1038rule allows it. Bundled plugins and remotely installed workspace plugins are

611`computer_use.windows.exes`. Executable rules require `publisher_name`,1039separate from this curated Git source policy.

612`product_name`, and `access`; `binary_name` is optional. Use the app's verified1040 

613identity rather than its display name alone.1041These source restrictions apply only where a local client supports plugin

1042marketplace operations: ChatGPT and Codex in the desktop app, and Codex CLI.

1043They don't control plugin use in ChatGPT on the web or mobile, and they don't

1044add plugins to the IDE extension.

1045 

1046### Enforce managed hooks from requirements

1047 

1048Managed hooks run administrator-defined actions at supported task or tool

1049events. Use **Edit as TOML** in Agent security to configure them in Global

1050`requirements.toml`; the settings controls don't include a dedicated hook editor. The execution paths below determine which hook types can run.

614 1051 

615See the [configuration reference](https://learn.chatgpt.com/docs/config-file/config-reference#requirementstoml)1052When managed policy and remote hooks are enabled, Work Cloud with local access and dots use admin-managed remote MCP hooks on the cloud orchestrator. Configure `mcp_tool` handlers in Global `requirements.toml`. Work Cloud without local access and personal accounts do not use these enterprise hooks. Command/shell, prompt, and agent handlers; hooks from local configuration, plugins, or local directories; environment-scoped hooks; and `SessionEnd` MCP hooks are not supported with cloud orchestration, even when tools execute locally. When both orchestration and execution are local, existing supported hooks continue to work in local-only Work and Codex threads. Admins can still configure supported managed hooks in Agent Security for those workflows.

616for the complete fields and [locked-use restrictions](#restrict-locked-computer-use)1053 

617for managed macOS devices.1054Before relying on these hooks, test callback connectivity, required events, and failure behavior. An explicit supported denial can block an action, but a `PreToolUse` callback error, timeout, or malformed response can fail the hook without blocking the tool. MCP hooks do not provide a complete Compliance API audit trail. The following script and directory examples retain their Codex scope.

618 1055 

619### Pin feature flags1056Admins can also define managed lifecycle hooks directly in `requirements.toml`.

1057Use `[hooks]` for the hook configuration itself, and point `managed_dir` at the

1058directory where your MDM or endpoint-management tooling installs the referenced

1059scripts.

620 1060 

621You can also pin [feature flags](https://learn.chatgpt.com/docs/config-file/config-basic#feature-flags) for users1061To enforce managed hooks even for users who turned hooks off locally, pin

622receiving a managed `requirements.toml`:1062`[features].hooks = true` alongside `[hooks]`. To skip user, project, session,

1063and plugin hooks while still allowing managed hooks, set

1064`allow_managed_hooks_only = true`.

623 1065 

624```toml1066```toml

1067allow_managed_hooks_only = true

1068 

625[features]1069[features]

626hooks = true1070hooks = true

627unified_exec = false

628 1071 

629# Disable surface-specific features when needed.1072[hooks]

630browser_use = false1073managed_dir = "/enterprise/hooks"

631browser_use_full_cdp_access = false1074windows_managed_dir = 'C:\enterprise\hooks'

632browser_use_external = false

633in_app_browser = false

634in_app_updates = false

635computer_use = false

636```

637 1075 

638Use the canonical feature keys from `config.toml`'s `[features]` table for1076[[hooks.PreToolUse]]

639runtime features. The local runtime normalizes recognized features to meet these1077matcher = "^Bash$"

640pins and rejects conflicting writes to `config.toml` or profile file feature

641settings.

642 1078 

643A managed `unified_exec = false` keeps command execution available, but disables1079[[hooks.PreToolUse.hooks]]

644resumable processes and the `write_stdin` tool. User configuration can't disable1080type = "command"

645this feature.1081command = "python3 /enterprise/hooks/pre_tool_use_policy.py"

1082command_windows = 'py -3 C:\enterprise\hooks\pre_tool_use_policy.py'

1083timeout = 30

1084statusMessage = "Checking managed Bash command"

1085```

646 1086 

647<a id="disable-codex-feature-surfaces"></a>1087Notes:

648 1088 

649- `in_app_browser = false` disables the built-in browser pane.1089- The local runtime enforces the hook configuration from `requirements.toml`,

650- `in_app_updates = false` disables the ChatGPT desktop app's own updater on1090 but it doesn't distribute the scripts in `managed_dir`.

651 restart, where supported. It doesn't affect external package deployment or1091- Deliver those scripts with your MDM or device-management solution.

652 extend support for older app versions. For setup and rollout guidance, see1092- Managed hook commands should reference absolute script paths under the

653 [Manage app updates](https://learn.chatgpt.com/docs/enterprise/manage-app-updates).1093 configured managed directory.

654- `browser_use = false` disables Computer Use in browsers and Browser Agent availability.1094- `allow_managed_hooks_only = true` skips hooks from user, project, session, and

655- `browser_use_full_cdp_access = false` disables full CDP access in the local1095 plugin sources, but still loads hooks from `requirements.toml` and other

656 runtime, including Browser Developer mode, and prevents the ChatGPT desktop1096 managed config layers.

657 app from enabling the corresponding setting.

658- `browser_use_external = false` disables external Browser Use.

659- `computer_use = false` disables Computer Use, Record & Replay, and related

660 install or setup flows.

661 1097 

662If you omit these keys, policy allows the features, subject to normal client,1098## Understand policy scope and precedence

663platform, and rollout availability.

664 1099 

665### Restrict locked computer use1100Use this section to check where a policy applies, how requirements combine, how clients receive cloud-managed settings, and how to verify the result.

666 1101 

667To prevent users from enabling [Locked Use](https://learn.chatgpt.com/docs/computer-use#locked-use)1102For Work with local access and dots, supported Global policy governs the shared cloud orchestrator when managed policy is enabled; applicable local execution requirements govern the connected computer. Work cloud containers retain existing Work Cloud policies, and supported device controls still apply to local execution. Codex keeps its existing configuration behavior. Managed configuration does not grant a workspace seat or feature access. Use [Roles and workspace permissions](https://learn.chatgpt.com/docs/enterprise/roles-and-workspace-permissions) for those controls.

668on a managed Mac, add this requirement:

669 1103 

670```toml1104<a id="agent-security-and-work-sync"></a>

671[computer_use]

672allow_locked_computer_use = false

673```

674 1105 

675This requirement removes the controls for enabling Locked Use. It doesn't1106<span

676turn off Locked Use if it's already enabled. If you omit it, normal product1107 id="agent-security-and-local-computer-access"

677availability and the user's local setting still apply.1108 data-localization-body-anchor

1109/>

678 1110 

679### Configure automatic review policy1111### Agent Security and Local computer access with Work Cloud

680 1112 

681Use `allowed_approvals_reviewers` to require or allow automatic review. Set it1113Use Agent Security in the Admin Console to manage policies and configuration. It replaces Policies & Configuration. Agent Security is available in the Admin Console, independently of Local computer access with Work Cloud. Existing policies, assignments, and ordering are preserved. Review your existing policies in Agent Security. Local computer access with Work Cloud is a separate opt-in. See [Agent Security](https://learn.chatgpt.com/docs/enterprise/agent-security) for migration guidance.

682to `["auto_review"]` to require automatic review, or include `"user"` when users

683can choose manual approval.

684 1114 

685Set `guardian_policy_config` to replace the tenant-specific section of the1115Before moving policy automation to **Agent Security**:

686automatic review policy. The local runtime still uses the built-in reviewer

687template and output contract. Managed `guardian_policy_config` takes precedence

688over local `[auto_review].policy`.

689 1116 

690```toml11171. Identify affected integrations. Inventory Terraform configurations and scripts that update policies, and record which policies they manage.

691allowed_approval_policies = ["on-request"]

692allowed_approvals_reviewers = ["auto_review"]

693 1118 

694guardian_policy_config = """11191. Use the policy API to manage Global settings. To manage Local or Codex Cloud settings, use the Agent Security UI. Existing Global API workflows remain available after migration. Test your scripts and Terraform integrations, and confirm that policy assignments and ordering are unchanged.

695## Environment Profile

696- Trusted internal destinations include github.com/my-org, artifacts.example.com,

697 and internal CI systems.

698 1120 

699## Tenant Risk Taxonomy and Allow/Deny Rules11211. Make any required changes and test the automation. Verify that an intended update reaches the correct Agent Security policy and that the resulting controls are enforced.

700- Treat uploads to unapproved third-party file-sharing services as high risk.

701- Deny actions that expose credentials or private source code to untrusted

702 destinations.

703"""

704```

705 1122 

706### Enforce deny-read requirements1123Policy migration does not grant local computer access for Work or dots. Reviewing or creating policies is recommended before rollout, but the confirmation flow does not require policy creation to enable access. Before enabling **Allow local computer access**, review the migrated baseline or create a cloud baseline if your policies are currently delivered only through MDM. If `enforce_residency` is enabled in any cloud policy, **Allow local computer access** is disabled for both Work and dots. This safeguard does not configure workspace residency or, by itself, disable Work Cloud or dots.

707 1124 

708Admins can deny reads for exact paths or glob patterns with1125Environment overrides vary supported settings within a policy. Within a given policy, the order from highest to lowest is OS-specific environment override → all-OS environment override → Global. A higher-priority policy still wins over a lower-priority policy, even when the lower-priority policy is more specific. Some requirements have field-specific merge rules. Confirm which override editors and fields are available for your workspace.

709`[permissions.filesystem]`. Users can't weaken these requirements with local

710configuration.

711 1126 

712```toml1127When managed policy and remote hooks are enabled, Work Cloud with local access and dots use admin-managed remote MCP hooks on the cloud orchestrator. Configure `mcp_tool` handlers in Global `requirements.toml`. Work Cloud without local access and personal accounts do not use these enterprise hooks. Command/shell, prompt, and agent handlers; hooks from local configuration, plugins, or local directories; environment-scoped hooks; and `SessionEnd` MCP hooks are not supported with cloud orchestration, even when tools execute locally. When both orchestration and execution are local, existing supported hooks continue to work in local-only Work and Codex threads. Admins can still configure supported managed hooks in Agent Security for those workflows. Before relying on these hooks, test callback connectivity, required events, and failure behavior. An explicit supported denial can block an action, but a `PreToolUse` callback error, timeout, or malformed response can fail the hook without blocking the tool. MCP hooks do not provide a complete Compliance API audit trail. See the [Configuration Reference](https://learn.chatgpt.com/docs/config-file/config-reference).

713[permissions.filesystem]

714deny_read = [

715 # values can be absolute paths...

716 "/**/*.env",

717 # ...or relative to $HOME/%USERPROFILE% using `~`.

718 "~/.ssh",

719 # But relative paths starting with `./` are not allowed.

720]

721```

722 1128 

723When deny-read requirements are present, the local runtime rejects full-access1129### Locations and precedence

724permissions and keeps local execution in a read-only or workspace sandbox so it1130 

725can enforce them. On native Windows, managed `deny_read` applies to direct file1131For local execution, requirements are applied from lower to higher priority as follows. This ordering also applies to local steps in Local computer access with Work Cloud:

726tools; shell subprocess reads don't use this sandbox rule.

727 1132 

728### Enforce managed hooks from requirements11331. System `requirements.toml` (`/etc/codex/requirements.toml` on Unix systems,

1134 including Linux and macOS, or `%ProgramData%\OpenAI\Codex\requirements.toml`

1135 on Windows).

11362. Agent Security requirements delivered in the cloud config bundle.

11373. Legacy `managed_config.toml` fields that the local client reinterprets as requirements.

11384. macOS managed preferences (MDM) delivered through

1139 `com.openai.codex:requirements_toml_base64`.

729 1140 

730When managed policy and remote hooks are enabled, Work Cloud with local access and dots use admin-managed remote MCP hooks on the cloud orchestrator. Configure `mcp_tool` handlers in Global `requirements.toml`. Work Cloud without local access and personal accounts do not use these enterprise hooks. Command/shell, prompt, and agent handlers; hooks from local configuration, plugins, or local directories; environment-scoped hooks; and `SessionEnd` MCP hooks are not supported with cloud orchestration, even when tools execute locally. When both orchestration and execution are local, existing supported hooks continue to work in local-only Work and Codex threads. Admins can still configure supported managed hooks in Agent Security for those workflows.1141Higher-precedence layers override ordinary scalar and list values from lower

1142layers. Tables merge by key, while requirements such as rules, hooks, and

1143filesystem restrictions have field-specific composition behavior. Use the

1144[`requirements.toml` reference](https://learn.chatgpt.com/docs/config-file/config-reference#requirementstoml)

1145for the current schema instead of assuming that every field merges the same

1146way.

731 1147 

732Before relying on these hooks, test callback connectivity, required events, and failure behavior. An explicit supported denial can block an action, but a `PreToolUse` callback error, timeout, or malformed response can fail the hook without blocking the tool. MCP hooks do not provide a complete Compliance API audit trail. The following script and directory examples retain their Codex scope.1148For backward compatibility, supported local clients reinterpret the legacy

1149`approval_policy`, `approvals_reviewer`, and `sandbox_mode` fields as

1150requirements. This conversion adds compatibility choices where necessary; use

1151`requirements.toml` for explicit allowlists.

733 1152 

734Admins can also define managed lifecycle hooks directly in `requirements.toml`.

735Use `[hooks]` for the hook configuration itself, and point `managed_dir` at the

736directory where your MDM or endpoint-management tooling installs the referenced

737scripts.

738 1153 

739To enforce managed hooks even for users who turned hooks off locally, pin

740`[features].hooks = true` alongside `[hooks]`. To skip user, project, session,

741and plugin hooks while still allowing managed hooks, set

742`allow_managed_hooks_only = true`.

743 1154 

744```toml

745allow_managed_hooks_only = true

746 1155 

747[features]1156### Precedence for Local computer access with Work Cloud

748hooks = true

749 1157 

750[hooks]1158For Work with local access and dots, distinguish Global orchestrator policy from execution policy. Applicable local requirements govern the connected computer. Work cloud containers and dots cloud computers use their own execution configuration and requirements, rather than the managed environment bundle used by other executors.

751managed_dir = "/enterprise/hooks"

752windows_managed_dir = 'C:\enterprise\hooks'

753 1159 

754[[hooks.PreToolUse]]1160For local execution, MDM and legacy managed-device requirements rank above Agent Security. The device's system requirements file ranks below Agent Security. Within each policy, resolve OS-specific environment overrides before all-OS environment overrides, then Global. Policy priority wins over specificity across policies.

755matcher = "^Bash$"

756 1161 

757[[hooks.PreToolUse.hooks]]1162| Control | Local Work without sync and local Codex | Local computer access with Work Cloud |

758type = "command"1163| ----------------------------- | ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |

759command = "python3 /enterprise/hooks/pre_tool_use_policy.py"1164| Enterprise requirements | Follow the local requirements order above. | Apply to local executors. Work cloud containers retain existing Work Cloud policies. |

760command_windows = 'py -3 C:\enterprise\hooks\pre_tool_use_policy.py'1165| Device execution restrictions | Enforced by supported local controls. | Follow the local requirements order above, including MDM and legacy requirements above Agent Security. |

761timeout = 301166| Environment overrides | Use the configuration model for the relevant product. | Within one policy: OS-specific environment override, then all-OS environment override, then Global. A lower-priority policy cannot win through specificity. |

762statusMessage = "Checking managed Bash command"

763```

764 1167 

765Notes:1168Requirements impose constraints, while configuration defaults supply starting values. For Work with local access and dots, supported Global policy applies through the shared cloud orchestrator when managed policy is enabled. Applicable local `requirements.toml` requirements govern execution on a connected computer. Work cloud containers and dots cloud computers use their own execution configuration and requirements, rather than the managed environment bundle used by other executor types. Local execution restrictions do not automatically apply to these cloud computers. Review cloud capability permissions and test local and cloud execution separately.

766 1169 

767- The local runtime enforces the hook configuration from `requirements.toml`,1170Keep orchestrator controls, including approvals and web search, in Global. Use the dedicated Allowed approval policies and Allowed web search modes controls where available, and TOML for other supported fields. See the [Configuration Reference](https://learn.chatgpt.com/docs/config-file/config-reference) for the field list and execution scope.

768 but it doesn't distribute the scripts in `managed_dir`.

769- Deliver those scripts with your MDM or device-management solution.

770- Managed hook commands should reference absolute script paths under the

771 configured managed directory.

772- `allow_managed_hooks_only = true` skips hooks from user, project, session, and

773 plugin sources, but still loads hooks from `requirements.toml` and other

774 managed config layers.

775 1171 

776### Enforce command rules from requirements1172### Cloud-managed requirements

777 1173 

778Admins can also enforce restrictive command rules from `requirements.toml`1174When a user signs in with ChatGPT on a supported plan, supported local clients

779using a `[rules]` table. These rules merge with regular `.rules` files, and the1175can receive admin-enforced requirements associated with the workspace. This is

780most restrictive decision still wins.1176a delivery channel for `requirements.toml`-compatible policy. It doesn't grant

1177workspace access or replace workspace RBAC. Authentication requirements must be

1178[managed locally](#manage-authentication-locally).

781 1179 

782Unlike `.rules`, requirements rules must specify `decision`, and that decision1180Configure common requirements with the [Agent security

783must be `"prompt"` or `"forbidden"` (not `"allow"`).1181controls](#configure-a-policy-in-agent-security). For a policy that allows only

1182on-request approvals and read-only or workspace-write sandboxes, use **Approval

1183policies** and **Sandbox modes** under **Policy guardrails**. To also prompt before

1184a supported shell entry point runs, use **Edit as TOML** to add the `[rules]`

1185table to Global `requirements.toml`.

1186 

1187The complete TOML equivalent is:

784 1188 

785```toml1189```toml

1190allowed_approval_policies = ["on-request"]

1191allowed_sandbox_modes = ["read-only", "workspace-write"]

1192 

786[rules]1193[rules]

787prefix_rules = [1194prefix_rules = [

788 { pattern = [{ token = "rm" }], decision = "forbidden", justification = "Use git clean -fd instead." },1195 { pattern = [{ any_of = ["bash", "sh", "zsh"] }], decision = "prompt", justification = "Require explicit approval for shell entry points" },

789 { pattern = [{ token = "git" }, { any_of = ["push", "commit"] }], decision = "prompt", justification = "Require review before mutating history." },

790]1196]

791```1197```

792 1198 

793To restrict which MCP servers a local client can enable, add an `mcp_servers`1199Check that every managed client version supports the keys you select. Assign the policy to the intended users or groups and verify that it takes effect on their supported clients. Use

794approved list. For stdio servers, match on `command`; for streamable HTTP1200the configuration reference for the current schema and the administration

795servers, match on `url`:1201surface for current assignment behavior.

796 

797```toml

798[mcp_servers.docs]

799identity = { command = "codex-mcp" }

800 1202 

801[mcp_servers.remote]1203The service selects the enterprise-managed requirement layers that apply to the

802identity = { url = "https://example.com/mcp" }1204signed-in identity. The local client evaluates those layers with the other

803```1205requirements sources described in [Locations and precedence](#locations-and-precedence).

1206Use the current administration surface for workspace-side creation and

1207assignment. Don't rely on a copied group-matching algorithm; the administration

1208service owns that behavior and can change it independently of the local

1209requirements format.

804 1210 

805The string form of `identity.command` matches only the configured `command`. It1211For supported keys and examples, see

806doesn't inspect `args`, `cwd`, `env`, or `env_vars`.1212[Example requirements.toml](#example-requirementstoml) and the

1213[`requirements.toml` reference](https://learn.chatgpt.com/docs/config-file/config-reference#requirementstoml).

807 1214 

808To constrain a complete stdio invocation, match the executable and each1215#### How local clients apply cloud-managed requirements

809positional argument:

810 1216 

811```toml1217The local loading and cache behavior below describes supported local clients. It does not establish when a changed cloud policy takes effect in an already-running task using Local computer access with Work Cloud. Verify the effective policy before relying on a changed restriction.

812[mcp_servers.internal.identity]

813command = { executable = "/usr/local/bin/codex-mcp", args = [

814 { match = "exact", value = "serve" },

815 { match = "prefix", value = "--workspace=" },

816] }

817```

818 1218 

819The executable, argument count, and argument order must match. Argument and URL1219When a user starts a supported local client and signs in with ChatGPT on a

820rules support `exact`, `prefix`, and full-value `regex` matching. Structured1220supported plan, the client first checks for a valid, identity-matched cache

821command rules still don't inspect `cwd`, `env`, or `env_vars`. Plugin-bundled1221entry. If no valid entry is available, the client fetches the applicable bundle

822MCP servers use the same identity shapes under1222with retries and writes a signed cache entry on success. If the request fails or

823`plugins.<plugin>.mcp_servers.<server>`.1223times out and no valid cache is available, the cloud config bundle load returns

1224an error rather than silently starting without the cloud-managed requirements

1225layer.

824 1226 

825If `mcp_servers` is present but empty, the local client disables all MCP servers.1227After cache resolution, the client composes the cloud requirements with the

1228other requirements layers described above. A background refresh updates the

1229cached bundle and makes it available to subsequent configuration loads. This

1230doesn't guarantee that an already-running task immediately uses a changed policy.

1231Some desktop settings require an app restart; follow any restart prompt and

1232verify the effective settings before relying on the change.

826 1233 

827### Control plugin availability1234### Confirm the admin and employee experience

828 1235 

829To turn off plugins in supported local clients, set `features.plugins` to1236Assign a person to own each managed policy, record which users or groups should

830`false` in `requirements.toml`:1237receive it, and document the business reason for any filesystem, network,

1238approval, or permission-profile restriction.

831 1239 

832```toml1240Test an allowed workflow and a blocked workflow with a user who has the intended permissions. Check the effective settings in the supported client. A workspace role or group alone does not enforce a local runtime restriction.

833features.plugins = false

834```

835 1241 

836This setting also applies when users sign in to Codex with an API key. See the1242Use **Test policies** in Agent security to check which policies match a member,

837[`features.plugins`1243group, or role selection. In an editable session, this checks the current draft

838reference](https://learn.chatgpt.com/docs/config-file/config-reference#requirementstoml) for the1244without saving it. The result shows policy selection, not the final merged

839supported configuration.1245configuration or whether a client enforces a restriction. After saving, test

1246the allowed and blocked workflows on each relevant client and execution path.

840 1247 

841### Restrict plugin marketplace sources1248## Deploy device-managed configuration

842 1249 

843To restrict plugin marketplace sources, set1250Use local system requirements or MDM for authentication restrictions and device-managed policies. The legacy `managed_config.toml` mechanism has different startup precedence from Agent security **Defaults**. The MDM workflow covers both requirements and legacy defaults.

844`restrict_to_allowed_sources = true` and define one or more source rules:

845 1251 

846```toml1252### Manage authentication locally

847[marketplaces]

848restrict_to_allowed_sources = true

849 1253 

850[marketplaces.allowed_sources.company_plugins]1254Set `allowed_login_methods`, `allowed_chatgpt_workspaces`,

851source = "git"1255`cli_auth_credentials_store`, and `chatgpt_base_url` in the local system

852url = "https://github.com/example/company-plugins.git"1256`requirements.toml` or macOS MDM requirements. Codex ignores these four fields

853ref = "main"1257in cloud-managed requirements. Local authentication requirements apply before

1258credentials load and before Codex retrieves cloud policy.

854 1259 

855[marketplaces.allowed_sources.internal_git]1260To require ChatGPT login to an approved workspace and store credentials in the

856source = "host_pattern"1261OS credential store, use:

857host_pattern = '^git\.example\.com$'

858 1262 

859[marketplaces.allowed_sources.local_plugins]1263```toml

860source = "local"1264allowed_login_methods = ["chatgpt"]

861path = "/opt/company/codex-plugins"1265allowed_chatgpt_workspaces = ["00000000-0000-0000-0000-000000000000"]

1266cli_auth_credentials_store = "keyring"

862```1267```

863 1268 

864Git rules match the normalized repository URL and, when present, an exact1269`allowed_login_methods` accepts `chatgpt`, `api`, or both. If omitted, this setting

865`ref`. Host patterns are regular expressions matched against the lowercase Git1270doesn't restrict login methods. If set, the list must contain at least one method.

866host; use `^` and `$` for a whole-host match. Local rules require an absolute,1271`api` permits API authentication, including Amazon Bedrock.

867normalized path. See the [`requirements.toml` reference](https://learn.chatgpt.com/docs/config-file/config-reference#requirementstoml)1272The workspace restriction also applies to

868for the full schema and merge behavior.1273[Codex access tokens](https://learn.chatgpt.com/docs/enterprise/access-tokens).

869 

870These requirements reject unmatched marketplace add, plugin install, and

871configured Git marketplace refresh operations. They also filter configured

872marketplaces and their plugins at runtime.

873 

874The OpenAI-curated Git marketplaces, including the API-key catalog, must also

875match the source allowlist. To allow them, include the following Git source

876without a `ref` constraint:

877 1274 

878```toml1275User-configured `forced_login_method` and `forced_chatgpt_workspace_id` must

879[marketplaces.allowed_sources.openai_curated]1276follow the requirements. When a user selects a workspace, it must also appear

880source = "git"1277in the managed workspace allowlist. If no workspaces match, ChatGPT login is

881url = "https://github.com/openai/plugins.git"1278unavailable. API authentication remains available when permitted. If no login method

882```1279is available, Codex refuses to start.

883 1280 

884To exclude the curated catalogs, omit that source and ensure no broader host1281See the [requirements reference](https://learn.chatgpt.com/docs/config-file/config-reference#requirementstoml)

885rule allows it. Bundled plugins and remotely installed workspace plugins are1282for credential storage modes and service URL configuration.

886separate from this curated Git source policy.

887 1283 

888These source restrictions apply only where a local client supports plugin1284### Managed defaults (`managed_config.toml`)

889marketplace operations: ChatGPT and Codex in the desktop app, and Codex CLI.

890They don't control plugin use in ChatGPT on the web or mobile, and they don't

891add plugins to the IDE extension.

892 1285 

893## Managed defaults (`managed_config.toml`)1286Use [Agent security Defaults](#set-configuration-defaults) for supported

1287cloud-managed starting values. This section covers the legacy device-managed

1288`managed_config.toml` mechanism and its different startup precedence. Editing

1289**Defaults** in Agent security doesn't deploy a `managed_config.toml` file to

1290members' devices.

894 1291 

895Managed defaults set the configuration a supported local client starts with. At1292Managed defaults set the configuration a supported local client starts with. At

896startup, they override the user's local `config.toml` and any CLI `--config`1293startup, they override the user's local `config.toml` and any CLI `--config`


910Make sure your managed defaults meet your requirements; the local runtime1307Make sure your managed defaults meet your requirements; the local runtime

911rejects disallowed values.1308rejects disallowed values.

912 1309 

913### Precedence and layering1310#### Precedence and layering

914 1311 

915The local runtime assembles the effective configuration in this order (top1312The local runtime assembles the effective configuration in this order (top

916overrides bottom):1313overrides bottom):


925not the legacy ordering above. Cloud `requirements.toml` uses1322not the legacy ordering above. Cloud `requirements.toml` uses

926[requirements precedence](#locations-and-precedence).1323[requirements precedence](#locations-and-precedence).

927 1324 

928### Locations1325#### Locations

929 1326 

930- Linux/macOS (Unix): `/etc/codex/managed_config.toml`1327- Linux/macOS (Unix): `/etc/codex/managed_config.toml`

931- Windows/non-Unix: `~/.codex/managed_config.toml`1328- Windows/non-Unix: `~/.codex/managed_config.toml`

932 1329 

933If the file is missing, the local runtime skips the managed layer.1330If the file is missing, the local runtime skips the managed layer.

934 1331 

1332#### Example managed_config.toml

1333 

1334```toml

1335# Set conservative defaults

1336approval_policy = "on-request"

1337sandbox_mode = "workspace-write"

1338 

1339[sandbox_workspace_write]

1340network_access = false # keep network disabled unless explicitly allowed

1341 

1342[otel]

1343environment = "prod"

1344exporter = "otlp-http" # point at your collector

1345log_user_prompt = false # keep prompts redacted

1346# exporter details live under exporter tables; see Monitoring and telemetry above

1347```

1348 

1349#### Recommended guardrails

1350 

1351- Prefer `workspace-write` with approvals for most users; reserve full access for controlled containers.

1352- Keep `network_access = false` unless your security review allows a collector or domains required by your workflows.

1353- Use managed configuration to pin OTel settings (exporter, environment), but keep `log_user_prompt = false` unless your policy explicitly allows storing prompt contents.

1354- Periodically audit diffs between local `config.toml` and managed policy to catch drift; managed layers should win over local flags and files.

1355 

935### macOS managed preferences (MDM)1356### macOS managed preferences (MDM)

936 1357 

937On macOS, admins can push a device profile that provides base64-encoded TOML payloads at:1358On macOS, admins can push a device profile that provides base64-encoded TOML payloads at:


944The local runtime parses these "managed preferences" payloads as TOML. For1365The local runtime parses these "managed preferences" payloads as TOML. For

945managed defaults (`config_toml_base64`), managed preferences have the highest1366managed defaults (`config_toml_base64`), managed preferences have the highest

946precedence. For requirements (`requirements_toml_base64`), precedence follows1367precedence. For requirements (`requirements_toml_base64`), precedence follows

947the cloud-managed requirements order described above. The same1368the [requirements order](#locations-and-precedence). The same

948requirements-side `[features]` table works in `requirements_toml_base64`; use1369requirements-side `[features]` table works in `requirements_toml_base64`; use

949canonical feature keys there as well.1370canonical feature keys there as well.

950 1371 

951### MDM setup workflow1372#### MDM setup workflow

952 1373 

953The local runtime honors standard macOS MDM payloads, so you can distribute1374The local runtime honors standard macOS MDM payloads, so you can distribute

954settings with tooling like `Jamf Pro`, `Fleet`, or `Kandji`. A lightweight1375settings with tooling like `Jamf Pro`, `Fleet`, or `Kandji`. A lightweight


962 reads the refreshed preference the next time it launches.1383 reads the refreshed preference the next time it launches.

963 1384 

964Avoid embedding secrets or high-churn dynamic values in the payload. Treat the managed TOML like any other MDM setting under change control.1385Avoid embedding secrets or high-churn dynamic values in the payload. Treat the managed TOML like any other MDM setting under change control.

965 

966### Example managed_config.toml

967 

968```toml

969# Set conservative defaults

970approval_policy = "on-request"

971sandbox_mode = "workspace-write"

972 

973[sandbox_workspace_write]

974network_access = false # keep network disabled unless explicitly allowed

975 

976[otel]

977environment = "prod"

978exporter = "otlp-http" # point at your collector

979log_user_prompt = false # keep prompts redacted

980# exporter details live under exporter tables; see Monitoring and telemetry above

981```

982 

983### Recommended guardrails

984 

985- Prefer `workspace-write` with approvals for most users; reserve full access for controlled containers.

986- Keep `network_access = false` unless your security review allows a collector or domains required by your workflows.

987- Use managed configuration to pin OTel settings (exporter, environment), but keep `log_user_prompt = false` unless your policy explicitly allows storing prompt contents.

988- Periodically audit diffs between local `config.toml` and managed policy to catch drift; managed layers should win over local flags and files.

security/cli.md +3 −2

Details

152## Choose the next scan152## Choose the next scan

153 153 

154| Goal | Guide |154| Goal | Guide |

155| ---------------------------------------- | ---------------------------------------------------------------------------------------- |155| ------------------------------------------------ | ---------------------------------------------------------------------------------------- |

156| Scan selected paths or a diff | [Select the scan target](https://learn.chatgpt.com/docs/security/cli/reference#select-the-scan-target) |156| Scan selected paths or a diff | [Select the scan target](https://learn.chatgpt.com/docs/security/cli/reference#select-the-scan-target) |

157| Use deep scans or limit their runtime | [Configure deep scans](https://learn.chatgpt.com/docs/security/cli/reference#configure-deep-scans) |157| Use deep scans or limit their runtime | [Configure deep scans](https://learn.chatgpt.com/docs/security/cli/reference#configure-deep-scans) |

158| Supply architecture or security policies | [Add security context](https://learn.chatgpt.com/docs/security/cli/reference#add-security-context) |158| Supply architecture or security policies | [Add security context](https://learn.chatgpt.com/docs/security/cli/reference#add-security-context) |

159| Change the model or reasoning effort | [Configure the runtime](https://learn.chatgpt.com/docs/security/cli/reference#configure-the-runtime) |159| Change the model or reasoning effort | [Configure the runtime](https://learn.chatgpt.com/docs/security/cli/reference#configure-the-runtime) |

160| Set an estimated cost limit | [Output and policy options](https://learn.chatgpt.com/docs/security/cli/reference#set-output-and-policy-options) |160| Set an estimated cost limit | [Output and policy options](https://learn.chatgpt.com/docs/security/cli/reference#set-output-and-policy-options) |

161| Scan multiple repositories | [Bulk scans](https://learn.chatgpt.com/docs/security/cli/bulk-scans) |161| Scan multiple repositories | [Bulk scans](https://learn.chatgpt.com/docs/security/cli/bulk-scans) |

162| Check pull requests automatically | [CI guide](https://learn.chatgpt.com/docs/security/cli/ci) |162| Scan GitHub pull requests or run scheduled scans | [GitHub Actions guide](https://learn.chatgpt.com/docs/security/cli/ci/github) |

163| Choose another CI provider | [CI/CD overview](https://learn.chatgpt.com/docs/security/cli/ci) |

163 164 

164For authentication problems, repeat-scan differences, or false-positive165For authentication problems, repeat-scan differences, or false-positive

165feedback, see the [CLI FAQ](https://learn.chatgpt.com/docs/security/cli/faq).166feedback, see the [CLI FAQ](https://learn.chatgpt.com/docs/security/cli/faq).

security/cli/ci.md +69 −245

Details

1# Run Codex Security in CI1# Codex Security CI/CD overview

2 2 

3> For the complete documentation index, see [llms.txt](https://learn.chatgpt.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to the page URL.3> For the complete documentation index, see [llms.txt](https://learn.chatgpt.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to the page URL.

4 4 

5Run the Codex Security CLI in CI to review the exact changes in a pull request5Run Codex Security in CI to review pull-request or merge-request changes, scan

6or merge request, keep findings and coverage, and optionally fail the check at6your default branch, and preserve findings and coverage. See your CI

7a chosen severity. Start with advisory results, review scan quality and7provider's guide for the workflow, report handling, and enforcement options.

8runtime, then add a severity policy that fits your repository.

9 8 

10Install the public `@openai/codex-security` package. Running scans still9## Prepare the workflow

11 requires Codex Security access.

12 10 

13This page provides a GitHub Actions workflow. For GitLab, use the11Running scans requires Codex Security access. Store an OpenAI API key in your

14[GitLab CI/CD guide](https://learn.chatgpt.com/docs/security/cli/ci/gitlab). The same scan and export12CI provider's secret store as `CODEX_SECURITY_API_KEY`, then map it to the scan

15commands work in other CI systems.13process's `OPENAI_API_KEY` environment variable.

16 14 

17## Prepare the workflow15Run scans only for repositories and changes you trust. Scans use the runner's

16local permissions and don't pause for approval. Keep unrelated credentials and

17deployment steps in separate jobs.

18 

19### Use an approved Daybreak model

20 

21For Daybreak Blue access through [Trusted Access for

22Cyber](https://learn.chatgpt.com/docs/cyber-safety#trusted-access-for-cyber), set the GitHub Action's

23`model` input to `gpt-6-sol` and `cyber-access-program` to

24`daybreak_blue`. For direct CLI scans, use `--model gpt-6-sol`

25and `--cyber-access-program daybreak_blue`.

26 

27Use an API key from a project that has Daybreak Blue enabled and access to the

28selected model. Setting the model or program does not grant access. See

29[Configure optional Daybreak access](https://learn.chatgpt.com/docs/security/cli/ci/github#configure-optional-daybreak-access)

30for the Action settings.

31 

32## Choose an integration

33 

34### Add the GitHub Actions workflow

35 

36Use the [GitHub Actions guide](https://learn.chatgpt.com/docs/security/cli/ci/github) for pull-request

37checks and scheduled repository scans. The Codex Security Action installs the CLI,

38saves reports, and adds a job summary and source annotations. The guide includes

39runner setup, optional Daybreak access, SARIF upload, and severity enforcement.

40 

41### Add the GitLab CI/CD pipeline

42 

43Use the [GitLab CI/CD guide](https://learn.chatgpt.com/docs/security/cli/ci/gitlab) for merge-request,

44default-branch, and scheduled scans. Start with a scan-only pipeline, then

45adopt report handling, policy enforcement, and optional verified remediation.

46 

47### Use another CI system

48 

49Install the public `@openai/codex-security` package and run the CLI directly.

50Use `--auth api-key`, choose a repository or diff scan, and save the output in a

51private directory outside the Git worktree. Your runner must provide the

52dependencies described in the [CLI quickstart](https://learn.chatgpt.com/docs/security/cli#check-the-prerequisites).

18 53 

19Store an OpenAI API key in your CI provider's secret store as54See the [CLI reference](https://learn.chatgpt.com/docs/security/cli/reference) for scan options, diff

20`CODEX_SECURITY_API_KEY`.55revisions, report formats, state and output directories, and retry behavior.

21 

22Map this secret directly to the scan step's `OPENAI_API_KEY` environment

23variable. Keep the credential scoped to the scan process and use

24`--auth api-key` to select it explicitly.

25 

26Run the workflow only for repositories and pull requests you trust. Scans use

27the runner's local permissions and don't pause for approval. Scan processes

28can inherit the job environment, so keep unrelated tokens and cloud

29credentials out of it.

30 

31The runner needs:

32 

33- Node.js 24 or 26, or Node.js 22 starting with 22.13.0.

34- Python 3.10 or later.

35- The published `@openai/codex-security` package, installed outside the

36 repository checkout.

37- The pull-request or merge-request head and base history so Git can calculate

38 the merge base.

39 

40## Add the GitHub Actions workflow

41 

42For private or internal repositories, enable [GitHub Code Security](https://docs.github.com/en/code-security/code-scanning/integrating-with-code-scanning/uploading-a-sarif-file-to-github)

43before you upload SARIF.

44 

45Create `.github/workflows/codex-security.yml`. Before checking out the pull

46request, install `@openai/codex-security` under

47`$RUNNER_TEMP/codex-security` so the trusted executable is available at

48`$RUNNER_TEMP/codex-security/node_modules/.bin/codex-security`:

49 

50```yaml

51name: Codex Security scan

52 

53on:

54 pull_request:

55 

56jobs:

57 codex-security:

58 if: github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]'

59 runs-on: ubuntu-latest

60 permissions:

61 actions: read

62 contents: read

63 security-events: write

64 steps:

65 - name: Set up Node.js

66 uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7

67 with:

68 node-version: "26"

69 

70 - name: Set up Python

71 uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7

72 with:

73 python-version: "3.14"

74 

75 - name: Install Codex Security

76 run: |

77 set -euo pipefail

78 npm install \

79 --prefix "$RUNNER_TEMP/codex-security" \

80 --ignore-scripts \

81 --no-audit \

82 --no-fund \

83 @openai/codex-security

84 

85 - name: Verify Codex Security

86 env:

87 CODEX_SECURITY_BIN: ${{ runner.temp }}/codex-security/node_modules/.bin/codex-security

88 run: |

89 set -euo pipefail

90 test -x "$CODEX_SECURITY_BIN"

91 "$CODEX_SECURITY_BIN" --version

92 

93 - name: Check out the pull request

94 uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7

95 with:

96 ref: ${{ github.event.pull_request.head.sha }}

97 fetch-depth: 0

98 persist-credentials: false

99 

100 - name: Scan the pull request

101 env:

102 OPENAI_API_KEY: ${{ secrets.CODEX_SECURITY_API_KEY }}

103 CODEX_SECURITY_BIN: ${{ runner.temp }}/codex-security/node_modules/.bin/codex-security

104 CODEX_SECURITY_STATE_DIR: ${{ runner.temp }}/codex-security-state

105 BASE_SHA: ${{ github.event.pull_request.base.sha }}

106 HEAD_SHA: ${{ github.event.pull_request.head.sha }}

107 SCAN_DIR: ${{ runner.temp }}/codex-security-results

108 run: |

109 set -euo pipefail

110 BASE_REVISION="$(git merge-base "$BASE_SHA" "$HEAD_SHA")"

111 "$CODEX_SECURITY_BIN" scan . \

112 --diff "$BASE_REVISION" \

113 --head "$HEAD_SHA" \

114 --auth api-key \

115 --output-dir "$SCAN_DIR" \

116 --json > "$RUNNER_TEMP/codex-security.json"

117 

118 - name: Export SARIF

119 id: export-sarif

120 if: always()

121 env:

122 CODEX_SECURITY_BIN: ${{ runner.temp }}/codex-security/node_modules/.bin/codex-security

123 SCAN_DIR: ${{ runner.temp }}/codex-security-results

124 SARIF_FILE: ${{ runner.temp }}/codex-security.sarif

125 run: |

126 set -euo pipefail

127 if test -f "$SCAN_DIR/scan-manifest.json"; then

128 "$CODEX_SECURITY_BIN" export "$SCAN_DIR" \

129 --export-format sarif \

130 --source-root "$GITHUB_WORKSPACE" \

131 --output "$SARIF_FILE"

132 echo "available=true" >> "$GITHUB_OUTPUT"

133 fi

134 

135 - name: Upload SARIF

136 if: always() && steps.export-sarif.outputs.available == 'true'

137 uses: github/codeql-action/upload-sarif@e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81 # v4

138 with:

139 sarif_file: ${{ runner.temp }}/codex-security.sarif

140 ref: refs/pull/${{ github.event.pull_request.number }}/head

141 sha: ${{ github.event.pull_request.head.sha }}

142 category: codex-security

143 

144 - name: Preserve scan results

145 if: always()

146 uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7

147 with:

148 name: codex-security-results

149 path: |

150 ${{ runner.temp }}/codex-security-results

151 ${{ runner.temp }}/codex-security.json

152 if-no-files-found: warn

153 retention-days: 7

154```

155 

156The workflow checks out the pull-request head, calculates its merge base, and

157scans the committed changes between those revisions. Full history keeps the

158target exact. `persist-credentials: false` keeps the repository token out of

159the checked-out Git configuration. Installing the CLI before checkout and

160running its absolute path keeps repository-controlled executables away from

161the scan credential. `--auth api-key` explicitly selects the scoped API key.

162The scan saves its history in a writable state directory outside the

163repository.

164 

165`--json` writes one complete JSON document to stdout, so the workflow can save

166it directly. Progress, completion summaries, and errors remain on stderr. This

167differs from `codex exec --json`, which emits a JSON Lines event stream.

168 

169The export step reads a completed, sealed scan and writes SARIF. It leaves the

170Codex runtime and credentials untouched. Scan artifacts can contain vulnerable

171source snippets, evidence, and remediation details. Set who can read them and

172how long to keep them.

173 

174## Add the GitLab CI/CD pipeline

175 

176For a production workflow with protected default-branch scans, opt-in scheduled

177deep scans, separate SARIF policy gating, and optional verified draft merge

178requests, use [Run Codex Security in GitLab

179CI/CD](https://learn.chatgpt.com/docs/security/cli/ci/gitlab).

180 

181The GitLab guide includes a scan-only starting point and the complete pipeline.

182It covers protected variables, artifact access, and a separate policy gate so

183GitLab can ingest findings even when the scanner returns a nonzero exit code.

184 56 

185## Choose a severity policy57## Choose a severity policy

186 58 

187The GitHub example is report-only because it omits `--fail-on-severity`. Once you59Start with advisory results. Review representative findings, scan coverage,

188are ready to make findings affect the check, add a threshold to the scan60cost, and runtime before deciding which outcomes should block a merge.

189command:61 

190 62Evaluate both findings and scan completeness. The severity policy evaluates

191```bash63findings from the current scan at or above the configured threshold. Earlier

192"$CODEX_SECURITY_BIN" scan . \64open findings in the repository summary don't affect that policy. An

193 --diff origin/main \65incomplete scan can leave areas without a review even when it reports no

194 --output-dir /path/outside/repository/results \66findings.

195 --fail-on-severity high67 

196```68In the Action release `action-v0.3.0`, a completed scan means the configured analysis

197 69produced a valid result. Scope exclusions, deferred investigations, and other

198The supported thresholds are `critical`, `high`, `medium`, and `low`. A70coverage notes do not bypass the severity policy. Scanner and required

199threshold includes findings from the current scan at that severity and above.71reporting errors fail the job. CLI `0.3.0` returns exit code `2` for input,

200Earlier open findings shown in the repository summary don't affect the policy.72execution, result-integrity, or required-output failures. Review `coverage.json` when assessing the result; completion does

201 73not certify that every vulnerability was found.

202The scan step uses these exit codes:74 

203 75Configure enforcement in the [GitHub Actions

204| Exit | Meaning |76guide](https://learn.chatgpt.com/docs/security/cli/ci/github#choose-a-severity-policy) or the [GitLab

205| ----- | --------------------------------------------------------------------------- |77CI/CD guide](https://learn.chatgpt.com/docs/security/cli/ci/gitlab#separate-reporting-from-policy-enforcement).

206| `0` | The scan completed, and any configured severity policy passed. |78For direct CLI integrations, see [severity enforcement and exit

207| `1` | The completed scan contains a finding at or above the threshold. |79codes](https://learn.chatgpt.com/docs/security/cli/reference#exit-codes-and-signals).

208| `2` | An input, execution, result-integrity, or required-output failure occurred. |

209| `130` | Ctrl-C interrupted the scan. |

210| `143` | SIGTERM terminated the scan. |

211 

212Coverage gaps don't change a completed scan's exit code or bypass its severity

213policy. Exit `0` doesn't mean every file was reviewed. Review excluded paths,

214deferred work, and open questions in `coverage.json` when assessing the result.

215 

216## Retry with an existing result directory

217 

218Use a fresh runner directory for each CI job. For a persistent or self-hosted

219runner, preserve an earlier result with `--archive-existing`:

220 

221```bash

222"$CODEX_SECURITY_BIN" scan . \

223 --diff origin/main \

224 --output-dir /path/outside/repository/results \

225 --archive-existing

226```

227 

228The command archives the earlier results and starts with an empty scan directory.

229 

230## Troubleshoot a CI scan

231 

232- **Unknown Git ref or unexpected diff:** Fetch the base and head history,

233 calculate the merge base, and pass both revisions explicitly.

234- **Protected or non-empty output directory:** Choose a private directory

235 outside the enclosing Git worktree. Use `--archive-existing` when the

236 directory already contains results.

237- **Missing credentials:** Confirm that `CODEX_SECURITY_API_KEY` is available to

238 the trusted workflow or pipeline and mapped directly to the scan process's

239 `OPENAI_API_KEY` environment variable.

240- **Scan history error:** Set `CODEX_SECURITY_STATE_DIR` to a writable

241 directory outside the repository.

242- **Python setup error:** Confirm that the runner uses Python 3.10 or later.

243- **Incomplete coverage:** Review `coverage.json`, including deferred surfaces

244 and open questions. Resolve the reported gaps before rerunning the scan.

245- **SARIF export error:** Confirm that the scan completed and the full scan

246 directory is available. Export validates the sealed artifacts before writing

247 SARIF.

248- **SARIF upload error:** For GitHub Actions, confirm that your organization

249 turned on GitHub Code Security for the repository and the workflow grants

250 `actions: read`, `contents: read`, and `security-events: write`. For GitLab

251 CI/CD, confirm that the project uses GitLab Ultimate 19.2 or later and that

252 the job uploads a SARIF 2.1.0 file through `artifacts:reports:sarif`.

253 

254For every command, flag, artifact, and output field, see the [CLI

255reference](https://learn.chatgpt.com/docs/security/cli/reference). To invoke the plugin through `codex exec`, see [Review code changes for security](https://learn.chatgpt.com/docs/security/plugin/code-changes#automate-reviews-in-cicd).

security/cli/ci/github.md +357 −0 created

Details

1# Run Codex Security in GitHub Actions

2 

3> For the complete documentation index, see [llms.txt](https://learn.chatgpt.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to the page URL.

4 

5Run Codex Security in GitHub Actions to review pull-request changes or scan

6your repository on a schedule. The Action installs the CLI, saves structured

7reports, and adds a job summary and source annotations. Start with advisory

8results, then configure enforcement after reviewing coverage and scan quality.

9 

10## Prepare the workflow

11 

12Running scans requires Codex Security access. To add your OpenAI API key:

13 

141. In your GitHub repository, open **Settings → Secrets and variables → Actions**.

152. Select **New repository secret**.

163. Enter `CODEX_SECURITY_API_KEY` as the name and paste your OpenAI API key as

17 the value. Save the secret.

18 

19The workflow examples below pass this secret to the Codex Security Action

20automatically. You don't need to put your API key in the workflow file.

21 

22Run the workflow only for repositories and pull requests you trust. Scans use

23the runner's local permissions and don't pause for approval. Keep unrelated

24credentials and deployment steps in separate jobs.

25 

26## Add the GitHub Actions workflow

27 

28**Scan costs:** These workflows use your API key and may incur charges. Both

29 examples omit `max-cost`, so they have no estimated cost stop threshold. To

30 set a threshold of $5 per scan, add `max-cost: "5"` to the Codex Security

31 Action's `with` settings. This isn't a hard spending cap: requests already in

32 progress can exceed it. See [Set an optional scan

33 budget](#set-an-optional-scan-budget) for pricing-support requirements.

34 

35### Scan the repository on a schedule

36 

37The workflow below scans your default branch every Monday at 07:23 UTC. You

38can also run it manually from GitHub's **Actions** tab. It uses an x64

39GitHub-hosted Ubuntu 24.04 runner and sets up the required sandbox automatically.

40 

411. In your repository, select **Add file → Create new file**.

422. Name the file `.github/workflows/codex-security-repository.yml`.

433. Paste the workflow below and commit it to your default branch.

44 

45```yaml

46name: Codex Security repository

47 

48on:

49 workflow_dispatch:

50 schedule:

51 - cron: "23 7 * * 1" # Mondays at 07:23 UTC

52 

53permissions:

54 contents: read

55 

56jobs:

57 security:

58 runs-on: ubuntu-24.04

59 timeout-minutes: 120

60 steps:

61 - name: Set up the Ubuntu sandbox

62 run: |

63 sudo apt-get update

64 sudo apt-get install --yes bubblewrap apparmor-profiles

65 sudo apparmor_parser -r /usr/share/apparmor/extra-profiles/bwrap-userns-restrict

66 

67 - name: Check out the repository

68 uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

69 with:

70 persist-credentials: false

71 

72 - name: Scan the repository

73 id: security

74 uses: openai/codex-security@3f61e5150981a5087c32e4395bbaa8ce5ce0c3e3 # action-v0.3.0

75 with:

76 scope: repository

77 model: gpt-6-sol

78 # For approved Daybreak Blue access, uncomment the next input.

79 # cyber-access-program: daybreak_blue

80 effort: high

81 fail-on-severity: none

82 upload-artifacts: "true"

83 env:

84 OPENAI_API_KEY: ${{ secrets.CODEX_SECURITY_API_KEY }}

85```

86 

87**About the version:** Both examples pin the Codex Security Action to commit

88 `3f61e5150981a5087c32e4395bbaa8ce5ce0c3e3` for the `action-v0.3.0` release,

89 which installs CLI `0.3.0`. Review a newer Action release before updating the

90 pinned commit.

91 

92**Adapting the runner:** The Action needs Node.js 24 and Python 3.11 or later,

93which this runner provides. The sandbox setup installs the `bubblewrap`

94package and loads the supplied AppArmor profile before the scan. Installing

95the package alone is not enough on this runner.

96 

97To run the workflow manually, open **Actions → Codex Security repository →

98Run workflow**. Open a completed run to review the summary, annotations, and

99downloadable reports.

100 

101Findings are report-only because `fail-on-severity` is `none`. Scanner and

102required reporting errors still fail the job.

103 

104To scan selected folders, add newline-separated literal paths to the scan

105step's `with` block:

106 

107```yaml

108paths: |

109 src/api

110 src/auth

111```

112 

113Paths require `scope: repository` and do not expand globs. For diff scans, omit

114`paths`. Keep `persist-credentials: false` and run the scan

115immediately after checkout.

116 

117### Scan pull-request changes

118 

119Using the same secret, create `.github/workflows/codex-security-pr.yml`:

120 

121```yaml

122name: Codex Security PR

123 

124on:

125 pull_request:

126 types: [opened, synchronize, reopened, ready_for_review]

127 

128permissions:

129 contents: read

130 

131concurrency:

132 group: codex-security-pr-${{ github.event.pull_request.number }}

133 cancel-in-progress: true

134 

135jobs:

136 security:

137 if: github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]'

138 name: Codex Security

139 runs-on: ubuntu-24.04

140 timeout-minutes: 60

141 steps:

142 - name: Set up the Ubuntu sandbox

143 run: |

144 sudo apt-get update

145 sudo apt-get install --yes bubblewrap apparmor-profiles

146 sudo apparmor_parser -r /usr/share/apparmor/extra-profiles/bwrap-userns-restrict

147 

148 - name: Check out the pull request

149 uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

150 with:

151 ref: ${{ github.event.pull_request.head.sha }}

152 fetch-depth: 0

153 persist-credentials: false

154 

155 - name: Scan PR changes

156 id: security

157 uses: openai/codex-security@3f61e5150981a5087c32e4395bbaa8ce5ce0c3e3 # action-v0.3.0

158 with:

159 scope: diff

160 model: gpt-6-sol

161 # For approved Daybreak Blue access, uncomment the next input.

162 # cyber-access-program: daybreak_blue

163 effort: high

164 fail-on-severity: none

165 upload-artifacts: "true"

166 env:

167 OPENAI_API_KEY: ${{ secrets.CODEX_SECURITY_API_KEY }}

168```

169 

170Open or update a PR from a branch in the same repository. The Action uses

171the full history to find the exact merge base and scans changes through the

172checked-out PR head. View the **Codex Security**

173check under **Checks** in the PR. Start with advisory findings, then [choose a severity

174policy](#choose-a-severity-policy) when you are ready to gate changes.

175 

176This example skips fork PRs and PRs opened by `dependabot[bot]`. A skipped job

177is not evidence of a security review. To include these bot PRs, remove the actor

178exclusion and also

179configure `CODEX_SECURITY_API_KEY` as a [secret

180for `dependabot[bot]`](https://docs.github.com/en/code-security/reference/supply-chain-security/troubleshoot-dependabot/dependabot-on-actions#accessing-secrets). The Action does not support `pull_request_target` or `workflow_run`.

181 

182The scanner reads applicable `SECURITY.md` guidance from the checkout,

183including policy changes in the PR. Review those changes alongside the code.

184 

185### Configure optional Daybreak access

186 

187Daybreak is optional. Both workflow examples use `gpt-6-sol`. If your

188organization has been approved for [Trusted Access for

189Cyber](https://learn.chatgpt.com/docs/cyber-safety#trusted-access-for-cyber), remove the `#` before

190`cyber-access-program` in the scan step's `with` block:

191 

192```yaml

193model: gpt-6-sol

194cyber-access-program: daybreak_blue

195```

196 

197Use an API key from a project enabled for Daybreak Blue with access to

198`gpt-6-sol`.

199 

200The program input also accepts `standard`. Without Daybreak access, use a

201model your API key can access under standard safeguards and omit

202`cyber-access-program` or set it to `standard`. Selecting a model or program

203does not grant access. See the Action's [Daybreak access guidance](https://github.com/openai/codex-security/blob/3f61e5150981a5087c32e4395bbaa8ce5ce0c3e3/github-action/README.md#daybreak-access-and-refusals).

204 

205A refusal or safety block that aborts the scan fails the Action, including when

206`fail-on-severity` is `none`. That input controls findings policy, not scanner

207errors.

208 

209### Set an optional scan budget

210 

211Both workflow examples omit `max-cost`, so they have no estimated cost stop

212threshold. To set one, add a positive USD amount with the `max-cost` input.

213For direct CLI scans, use `--max-cost`.

214 

215The cost limit requires CLI pricing support for the selected model. The

216estimated threshold is not a hard spending cap: the cost of requests already

217in progress can exceed it.

218Review findings and `coverage.json` if a scan stops at the threshold. See

219[output and policy options](https://learn.chatgpt.com/docs/security/cli/reference#set-output-and-policy-options)

220for cost-limit behavior.

221 

222### Save reports and upload SARIF

223 

224The examples set `upload-artifacts: "true"` to save downloadable reports with a

225seven-day retention window. Reports can contain source snippets, vulnerability

226evidence, and remediation details. Choose a retention window and repository

227access appropriate for your code. The Action uploads only validated reports

228on its allowlist; do not recursively upload its `results-directory` output.

229 

230SARIF upload is optional. For private or internal repositories, enable [GitHub Code Security](https://docs.github.com/en/code-security/how-tos/find-and-fix-code-vulnerabilities/integrate-with-existing-tools/upload-sarif-file) before uploading. Replace the workflow's `permissions` block with:

231 

232```yaml

233permissions:

234 contents: read

235 security-events: write

236 actions: read # Required for private repositories

237```

238 

239Then add this step after the scan in either workflow:

240 

241```yaml

242- name: Upload security findings

243 if: ${{ always() && steps.security.outputs.sarif-upload-ready == 'true' }}

244 uses: github/codeql-action/upload-sarif@b96794f015dfd88f77b49b1c93e0fa7110f94c63 # v4.38.0

245 with:

246 sarif_file: ${{ steps.security.outputs.sarif-path }}

247 sha: ${{ steps.security.outputs.scanned-sha }}

248 ref: ${{ steps.security.outputs.analysis-ref }}

249 category: codex-security-repository

250```

251 

252For the PR workflow, use `category: codex-security-pr` so each scope has a

253distinct category. Keep `id: security` on the scan step. Complete, validated

254reports remain available for upload when findings fail the severity policy.

255SARIF is not uploaded for failed or interrupted scans, empty diffs, or dry

256runs.

257 

258See the Action's [input

259and output reference](https://github.com/openai/codex-security/blob/3f61e5150981a5087c32e4395bbaa8ce5ce0c3e3/github-action/README.md#inputs) for all settings, status fields, and report paths.

260 

261## Choose a severity policy

262 

263The GitHub workflows start with `fail-on-severity: none`. To fail on high or

264critical findings from a completed scan, change the scan step's input:

265 

266```yaml

267fail-on-severity: high

268```

269 

270Make **Codex Security** a required status check in your repository rules to

271block merges when the PR job fails. GitHub treats a [conditionally skipped job as successful](https://docs.github.com/en/pull-requests/how-tos/merge-and-close-pull-requests/troubleshooting-required-status-checks#handling-skipped-but-required-checks),

272even for required checks. Fork PRs and PRs from `dependabot[bot]` pass this

273check without a scan. To block those skips, [require a

274successful, completed scan](#require-a-successful-completed-scan).

275 

276The Action follows the CLI outcome:

277 

278- Exit code `0` sets `scan-status: completed` and `policy-status: passed`.

279- Exit code `1` sets `scan-status: completed` and `policy-status: failed`;

280 the step fails on findings at or above the configured severity.

281- Exit code `2` or an interrupted process sets `scan-status: failed` and

282 `policy-status: not-evaluated`; the step fails.

283- Invalid or missing required reports, a changed checkout, failures to upload

284 requested artifacts, and runtime cleanup failures also fail the step.

285 

286A completed scan means the configured analysis produced a valid result.

287Scope exclusions, deferred investigations, and other notes in `coverage.json`

288do not create a separate scan outcome or bypass the severity policy.

289Completion does not certify that every vulnerability was found. Review

290`coverage.json` when assessing the result.

291 

292### Require a successful, completed scan

293 

294For a stricter policy, add a separate gate that runs even if the scan job

295fails or GitHub skips it. A step inside the scan job can't check a skipped job

296because none of its steps run.

297 

298In the PR workflow, add this `outputs` mapping to the existing `security` job,

299at the same indentation as `runs-on` and `steps`:

300 

301```yaml

302outputs:

303 scan-status: ${{ steps.security.outputs.scan-status }}

304```

305 

306Then add this job under `jobs`, alongside the existing `security` job:

307 

308```yaml

309security-gate:

310 name: Codex Security gate

311 needs: security

312 if: ${{ always() }}

313 runs-on: ubuntu-24.04

314 steps:

315 - name: Require a successful, completed scan

316 env:

317 SCAN_RESULT: ${{ needs.security.result }}

318 SCAN_STATUS: ${{ needs.security.outputs.scan-status }}

319 run: test "$SCAN_RESULT" = success && test "$SCAN_STATUS" = completed

320```

321 

322Make **Codex Security gate** the required status check for this policy. It

323requires both a successful scan job and `scan-status: completed`. Checking

324both preserves failures from the severity policy, reporting, and cleanup,

325even when the scan itself completed.

326 

327With the example's exclusions, this gate blocks fork PRs and PRs from

328`dependabot[bot]`. It also blocks empty diffs and dry runs, which the Action

329marks as `skipped`.

330The gate doesn't scan excluded PRs. Choose this policy only if these cases

331should prevent merging.

332 

333## Troubleshoot a scan

334 

335- **Unknown Git ref or unexpected diff:** Check out the PR head with

336 `fetch-depth: 0`.

337- **Sandbox startup error:** On Ubuntu 24.04, install the `bubblewrap` package

338 and load the AppArmor profile before the Action. Installing the package alone

339 does not load the required profile.

340- **Missing credentials:** Confirm that `CODEX_SECURITY_API_KEY` is available to

341 the trusted workflow and mapped to the scan step's `OPENAI_API_KEY`

342 environment variable.

343- **Python setup error:** The Action requires Python 3.11 or later.

344- **Coverage notes:** Review scope exclusions and deferred investigations in

345 `coverage.json`. These notes do not cause execution failures or bypass the

346 severity policy.

347- **Missing SARIF:** Inspect `scan-status`, `report-status`, and

348 `sarif-upload-ready`. If optional SARIF is missing, the Action warns without

349 changing the scan outcome; requested artifact-upload failures still fail the

350 job.

351- **SARIF upload error:** Confirm that your organization has enabled GitHub Code

352 Security for the repository and that the workflow grants `actions: read`,

353 `contents: read`, and `security-events: write`.

354 

355For every command, flag, artifact, and output field, see the [CLI

356reference](https://learn.chatgpt.com/docs/security/cli/reference). For other providers, see the

357[CI/CD overview](https://learn.chatgpt.com/docs/security/cli/ci).

Details

357a hard billing cap.357a hard billing cap.

358 358 

359Start with report-only scans. Add `--fail-on-severity` after your team has359Start with report-only scans. Add `--fail-on-severity` after your team has

360reviewed representative findings, coverage, cost, and runtime. See [Run Codex360reviewed representative findings, coverage, cost, and runtime. See the

361Security in CI](https://learn.chatgpt.com/docs/security/cli/ci) for severity policies and exit-code361[CI/CD overview](https://learn.chatgpt.com/docs/security/cli/ci#choose-a-severity-policy) for severity

362details.362policies and the [CLI reference](https://learn.chatgpt.com/docs/security/cli/reference#exit-codes-and-signals)

363for exit-code details.

363 364 

364When a job fails:365When a job fails:

365 366 

Details

213configured severity threshold. If it can't produce a valid completed result,213configured severity threshold. If it can't produce a valid completed result,

214it returns `2` and preserves any available output.214it returns `2` and preserves any available output.

215 215 

216For pull-request checks, see [Run scans in CI](https://learn.chatgpt.com/docs/security/cli/ci).216For GitHub pull-request checks and scheduled repository scans, use the

217[Codex Security GitHub Action](https://learn.chatgpt.com/docs/security/cli/ci/github). With

218`action-v0.3.0`, a completed scan means the configured analysis produced a

219valid result. Scope exclusions and deferred investigations do not bypass the

220severity policy. Review `coverage.json` to assess the scan's scope and

221limitations. To also reject empty diffs and dry runs, require the Action's

222`scan-status` output to be `completed`; see [Choose a severity

223policy](https://learn.chatgpt.com/docs/security/cli/ci/github#choose-a-severity-policy).

224 

225For other providers, see the [CI/CD overview](https://learn.chatgpt.com/docs/security/cli/ci).

217For a check before each commit, use226For a check before each commit, use

218[`install-hook`](https://learn.chatgpt.com/docs/security/cli/reference#codex-security-install-hook).227[`install-hook`](https://learn.chatgpt.com/docs/security/cli/reference#codex-security-install-hook).