SpyBara
Go Premium

Documentation 2026-10-29 23:59 UTC to 2026-10-30 23:59 UTC

13 files changed +598 −309. 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

173 href: "/codex/enterprise/managed-configuration",173 href: "/codex/enterprise/managed-configuration",

174 icon: "dataControls",174 icon: "dataControls",

175 },175 },

176 {

177 title: "Self-host Codex configuration for your team",

178 description:

179 "Serve Codex defaults and required settings from your own HTTPS endpoint.",

180 href: "/codex/enterprise/configuration-server",

181 icon: "settings",

182 },

176 {183 {

177 title: "Codex security cookbook",184 title: "Codex security cookbook",

178 description:185 description:

Details

1888`requirements.toml` is an admin-enforced configuration file that constrains security-sensitive settings users can't override. For details, locations, and examples, see [Admin-enforced requirements](https://learn.chatgpt.com/docs/enterprise/managed-configuration#admin-enforced-requirements-requirementstoml).1888`requirements.toml` is an admin-enforced configuration file that constrains security-sensitive settings users can't override. For details, locations, and examples, see [Admin-enforced requirements](https://learn.chatgpt.com/docs/enterprise/managed-configuration#admin-enforced-requirements-requirementstoml).

1889 1889 

1890For ChatGPT Business and Enterprise users, Codex can also apply cloud-fetched1890For ChatGPT Business and Enterprise users, Codex can also apply cloud-fetched

1891requirements. See the security page for precedence details.1891requirements. See the security page for precedence details. To serve CLI policy from your own HTTPS endpoint, see [Self-host Codex configuration for your team](https://learn.chatgpt.com/docs/enterprise/configuration-server).

1892 1892 

1893Use `[features]` in `requirements.toml` to pin runtime feature flags by the same1893Use `[features]` in `requirements.toml` to pin runtime feature flags by the same

1894canonical keys that `config.toml` uses. Requirements can also include documented1894canonical keys that `config.toml` uses. Requirements can also include documented


1930 1930 

1931<ConfigTable1931<ConfigTable

1932 options={[1932 options={[

1933 {

1934 key: "config_server",

1935 type: "table",

1936 description:

1937 "Enroll Codex with a configuration server. Set this in local administrator-controlled requirements.",

1938 },

1939 {

1940 key: "config_server.base_url",

1941 type: "string (HTTPS URL)",

1942 description:

1943 "Base URL of the configuration server enrolled by the administrator. Codex appends /codex/config/bundle to this URL.",

1944 },

1945 {

1946 key: "config_server.oauth",

1947 type: "table",

1948 description:

1949 "Optional company sign-in settings. Omit this table to fetch the bundle without credentials.",

1950 },

1951 {

1952 key: "config_server.oauth.authorization_url",

1953 type: "string (HTTPS URL)",

1954 description:

1955 "Authorization endpoint for company browser sign-in. Required when OAuth is configured.",

1956 },

1957 {

1958 key: "config_server.oauth.token_url",

1959 type: "string (HTTPS URL)",

1960 description:

1961 "Token endpoint for company sign-in and refresh. Required when OAuth is configured.",

1962 },

1963 {

1964 key: "config_server.oauth.client_id",

1965 type: "string",

1966 description:

1967 "Public OAuth client ID registered for Codex. Required when OAuth is configured.",

1968 },

1969 {

1970 key: "config_server.oauth.scopes",

1971 type: "array<string>",

1972 description:

1973 "Optional OAuth permissions to request from the identity provider.",

1974 },

1975 {

1976 key: "config_server.oauth.resource",

1977 type: "string",

1978 description:

1979 "Optional OAuth resource identifier required by the identity provider.",

1980 },

1981 {

1982 key: "config_server.oauth.redirect_port",

1983 type: "number",

1984 description:

1985 "Optional port for the browser callback on 127.0.0.1. By default, Codex chooses an available port.",

1986 },

1933 {1987 {

1934 key: "sqlite_home",1988 key: "sqlite_home",

1935 type: "string (path)",1989 type: "string (path)",

Details

1888`requirements.toml` is an admin-enforced configuration file that constrains security-sensitive settings users can't override. For details, locations, and examples, see [Admin-enforced requirements](https://learn.chatgpt.com/docs/enterprise/managed-configuration#admin-enforced-requirements-requirementstoml).1888`requirements.toml` is an admin-enforced configuration file that constrains security-sensitive settings users can't override. For details, locations, and examples, see [Admin-enforced requirements](https://learn.chatgpt.com/docs/enterprise/managed-configuration#admin-enforced-requirements-requirementstoml).

1889 1889 

1890For ChatGPT Business and Enterprise users, Codex can also apply cloud-fetched1890For ChatGPT Business and Enterprise users, Codex can also apply cloud-fetched

1891requirements. See the security page for precedence details.1891requirements. See the security page for precedence details. To serve CLI policy from your own HTTPS endpoint, see [Self-host Codex configuration for your team](https://learn.chatgpt.com/docs/enterprise/configuration-server).

1892 1892 

1893Use `[features]` in `requirements.toml` to pin runtime feature flags by the same1893Use `[features]` in `requirements.toml` to pin runtime feature flags by the same

1894canonical keys that `config.toml` uses. Requirements can also include documented1894canonical keys that `config.toml` uses. Requirements can also include documented


1930 1930 

1931<ConfigTable1931<ConfigTable

1932 options={[1932 options={[

1933 {

1934 key: "config_server",

1935 type: "table",

1936 description:

1937 "Enroll Codex with a configuration server. Set this in local administrator-controlled requirements.",

1938 },

1939 {

1940 key: "config_server.base_url",

1941 type: "string (HTTPS URL)",

1942 description:

1943 "Base URL of the configuration server enrolled by the administrator. Codex appends /codex/config/bundle to this URL.",

1944 },

1945 {

1946 key: "config_server.oauth",

1947 type: "table",

1948 description:

1949 "Optional company sign-in settings. Omit this table to fetch the bundle without credentials.",

1950 },

1951 {

1952 key: "config_server.oauth.authorization_url",

1953 type: "string (HTTPS URL)",

1954 description:

1955 "Authorization endpoint for company browser sign-in. Required when OAuth is configured.",

1956 },

1957 {

1958 key: "config_server.oauth.token_url",

1959 type: "string (HTTPS URL)",

1960 description:

1961 "Token endpoint for company sign-in and refresh. Required when OAuth is configured.",

1962 },

1963 {

1964 key: "config_server.oauth.client_id",

1965 type: "string",

1966 description:

1967 "Public OAuth client ID registered for Codex. Required when OAuth is configured.",

1968 },

1969 {

1970 key: "config_server.oauth.scopes",

1971 type: "array<string>",

1972 description:

1973 "Optional OAuth permissions to request from the identity provider.",

1974 },

1975 {

1976 key: "config_server.oauth.resource",

1977 type: "string",

1978 description:

1979 "Optional OAuth resource identifier required by the identity provider.",

1980 },

1981 {

1982 key: "config_server.oauth.redirect_port",

1983 type: "number",

1984 description:

1985 "Optional port for the browser callback on 127.0.0.1. By default, Codex chooses an available port.",

1986 },

1933 {1987 {

1934 key: "sqlite_home",1988 key: "sqlite_home",

1935 type: "string (path)",1989 type: "string (path)",

Details

1# Self-host Codex configuration for your team

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 

5We recommend that your team sign in to Codex with ChatGPT. On supported plans,

6 you can use [managed configuration](https://learn.chatgpt.com/docs/enterprise/managed-configuration)

7 to set defaults and enforce requirements in **Agent security** in the Admin

8 Console without running your own server.

9 

10If your users don't sign in to Codex with ChatGPT, you can distribute configuration to Codex CLI and the desktop app from an HTTPS server you operate. Codex loads your settings at startup, whether users connect directly to their model provider or through a gateway.

11 

12## Client limitations

13 

14The desktop app can't prompt you to sign in to the configuration server. If your server requires a new sign-in, run `codex login` in a terminal on the same computer, then reopen the app. If the app can't load the required settings, startup pauses.

15 

16## Configure Codex to use the server

17 

18On a test computer, create or update the system `requirements.toml`. Add a `[config_server]` table with the base URL of your configuration server. Use `/etc/codex/requirements.toml` on Linux and macOS, or `%ProgramData%\OpenAI\Codex\requirements.toml` on Windows. On macOS, you can also distribute the table through [managed preferences](https://learn.chatgpt.com/docs/enterprise/managed-configuration#mdm-setup-workflow).

19 

20```toml

21[config_server]

22base_url = "https://codex-config.example.com/team"

23```

24 

25Only local administrator-controlled requirements can select the server. Keep this table on the computer when you move the rest of your policy to the endpoint.

26 

27### Authenticate to the configuration server (optional)

28 

29By default, Codex attempts to fetch configuration without credentials. If your server requires sign-in, add `[config_server.oauth]` to the same `requirements.toml` file. Codex uses the OAuth authorization code flow with Proof Key for Code Exchange (PKCE).

30 

31```toml

32[config_server.oauth]

33authorization_url = "https://login.example.com/oauth/authorize"

34token_url = "https://login.example.com/oauth/token"

35client_id = "codex-policy"

36redirect_port = 43127

37```

38 

39The redirect URI for this example is `http://127.0.0.1:43127/callback`. You can omit `redirect_port` if your provider accepts a loopback callback on any available port. Codex sends the access token in the `Authorization` header. Your server must verify it before returning the bundle.

40 

41## Serve Codex configuration

42 

43Host your managed configuration at an HTTPS endpoint. When Codex CLI fetches the bundle, it sends a GET request using the base URL from the local `requirements.toml`:

44 

45```text

46GET {config_server.base_url}/codex/config/bundle

47```

48 

49With the `base_url` from the bootstrap example above, Codex sends this request:

50 

51```text

52GET https://codex-config.example.com/team/codex/config/bundle

53```

54 

55Respond with `200 OK` and a [JSON configuration bundle](#configuration-bundle-format) in the response body.

56 

57### Configuration bundle format

58 

59The bundle groups TOML entries into two arrays:

60 

61- `config_toml.enterprise_managed` contains the defaults to apply. Each entry's `contents` is [`config.toml` text](https://learn.chatgpt.com/docs/config-file/config-reference#configtoml).

62- `requirements_toml.enterprise_managed` contains the requirements to enforce. Each entry's `contents` is [`requirements.toml` text](https://learn.chatgpt.com/docs/config-file/config-reference#requirementstoml).

63 

64Each array entry has three string fields: `id`, `name` (a display name), and `contents`. Use an empty array for a category you don't need.

65 

66This example sets the web search default to `disabled` and enforces that value with `allowed_web_search_modes`.

67 

68```json

69{

70 "config_toml": {

71 "enterprise_managed": [

72 {

73 "id": "search-default",

74 "name": "Default web search",

75 "contents": "web_search = 'disabled'"

76 }

77 ]

78 },

79 "requirements_toml": {

80 "enterprise_managed": [

81 {

82 "id": "search-policy",

83 "name": "Allowed web search modes",

84 "contents": "allowed_web_search_modes = ['disabled']"

85 }

86 ]

87 }

88}

89```

90 

91## Verify the configuration in Codex

92 

931. On a test computer, open a terminal in your project directory and run `codex`. Complete company sign-in if prompted.

942. At the interactive Codex CLI prompt, type [`/debug-config`](https://learn.chatgpt.com/docs/developer-commands?surface=cli#cli-inspect-config-layers-with-debug-config) and press Enter.

953. If you serve defaults, find their names and IDs under **Config layer stack**. With the example above, look for `enterprise-managed (Default web search, search-default) (enabled)`.

964. If you serve requirements, find a setting you enforce under **Requirements** and check the policy source listed next to it.

97 

98Codex can start with cached settings and refresh them in the background. After you change a policy on the server, wait for Codex to refresh it, then start a new session and repeat the check before rolling it out to other machines.

Details

21 21 

22See [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.

23 23 

24If your users don't sign in to Codex with ChatGPT, you can distribute defaults and requirements to Codex CLI and the desktop app from an HTTPS endpoint you operate. See [Self-host Codex configuration for your team](https://learn.chatgpt.com/docs/enterprise/configuration-server).

25 

24## Configure a policy in Agent security26## Configure a policy in Agent security

25 27 

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

Details

230 230 

231### Distribute defaults and requirements231### Distribute defaults and requirements

232 232 

233If your users don't sign in to Codex with ChatGPT, you can [distribute team settings from your own server](https://learn.chatgpt.com/docs/enterprise/configuration-server). Codex fetches those settings independently of how you route model requests.

234 

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

234to choose where to distribute defaults. For enforced settings and macOS MDM236to choose where to distribute defaults. For enforced settings and macOS MDM

235payloads, see [Managed configuration](https://learn.chatgpt.com/docs/enterprise/managed-configuration#admin-enforced-requirements-requirementstoml).237payloads, see [Managed configuration](https://learn.chatgpt.com/docs/enterprise/managed-configuration#admin-enforced-requirements-requirementstoml).

security/cli.md +27 −17

Details

11 11 

12Use Node.js 24 or 26, or Node.js 22 starting with 22.13.0.12Use Node.js 24 or 26, or Node.js 22 starting with 22.13.0.

13You also need Python 3.10 or later.13You also need Python 3.10 or later.

14Python 3.10 also needs `tomli`. Scans using OpenAI inference require Codex Security access.14If you use Python 3.10, install `tomli`. Some cybersecurity requests and

15Depending on your account and repository, full-repository scans may also15protected findings require [Trusted Access for Cyber](https://chatgpt.com/cyber).

16require [Trusted Access for Cyber](https://chatgpt.com/cyber).

17 16 

18The CLI runs with your operating-system permissions and doesn't pause for17The CLI runs with your operating-system permissions and doesn't pause for

19approval.18approval.


23 22 

24## Set up and verify the CLI23## Set up and verify the CLI

25 24 

26Run the public package with `npx`:25Install the public package globally, then check its version:

26 

27```bash

28npm install -g @openai/codex-security

29codex-security --version

30```

31 

32The package provides the `codex-security` command and its `cs` alias. Ensure

33npm's global executable directory is on your `PATH`.

34 

35To run without a global installation, use `npx`:

27 36 

28```bash37```bash

29npx @openai/codex-security --version38npx @openai/codex-security --version

30```39```

31 40 

41The examples below use `npx @openai/codex-security`. After a global

42installation, you can use `codex-security` instead.

43 

32The command prints the installed package version. Use `info --json` to check44The command prints the installed package version. Use `info --json` to check

33the bundled plugin version, or `--help` to list commands. Package changes are45the bundled plugin version, or `--help` to list commands.

34listed in the [CLI and SDK releases](https://github.com/openai/codex-security/releases).

35 46 

36## Sign in47## Sign in

37 48 


43 54 

44On a machine without a browser, add `--device-auth` if your workspace allows55On a machine without a browser, add `--device-auth` if your workspace allows

45it, and follow the displayed sign-in instructions. If device authentication56it, and follow the displayed sign-in instructions. If device authentication

46is disabled, use the [SSH login instructions](https://github.com/openai/codex-security/blob/npm-v0.3.0/sdk/typescript/docs/cli.md#remote-login-with-ssh-forwarding).57is disabled, use the [SSH login instructions](https://github.com/openai/codex-security/blob/main/sdk/typescript/docs/cli.md#remote-login-with-ssh-forwarding).

47Use `--auth chatgpt` in the scan commands below to select58Use `--auth chatgpt` in the scan commands below to select

48that sign-in even when your environment also contains an API key.59that sign-in even when your environment also contains an API key.

49 60 


98 REPORT /path/outside/repository/codex-security-results/report.md109 REPORT /path/outside/repository/codex-security-results/report.md

99 110 

100 FINDINGS 2 (2 confirmed this scan; 0 previously found; 1 high, 1 medium)111 FINDINGS 2 (2 confirmed this scan; 0 previously found; 1 high, 1 medium)

112 SCOPE repository: .

101 ELAPSED 42s113 ELAPSED 42s

102 RESULTS /path/outside/repository/codex-security-results114 RESULTS /path/outside/repository/codex-security-results

103```115```


108 120 

109## Review the results121## Review the results

110 122 

111Open `report.md` from the reported directory. Confirm the target and revision,123Open `report.md` from the results directory. Confirm the target and revision,

112then read the coverage before reviewing individual findings.124then review the findings. For the recorded status and scope, look at

113 125`scan.status` and `scan.scope` in `scan-manifest.json`.

114Check `scan.status` in `scan-manifest.json` to confirm that the scan completed.

115Review `coverage.json` for reviewed surfaces, excluded paths, deferred work,

116and open questions.

117 126 

118A completed scan exits with `0` unless findings meet a configured severity127A completed scan exits with `0` unless findings meet a configured severity

119threshold, which returns `1`. Coverage gaps don't change the exit code, so128threshold, which returns `1`. Exit `0` doesn't establish that every file was

120exit `0` doesn't mean every file was reviewed. Input, execution, result-integrity,129reviewed. Input, execution, result-integrity, or required-output failures return `2`. The

121or required-output failures return `2`. The

122[CLI reference](https://learn.chatgpt.com/docs/security/cli/reference#exit-codes-and-signals) explains130[CLI reference](https://learn.chatgpt.com/docs/security/cli/reference#exit-codes-and-signals) explains

123the exit codes.131the exit codes.

124 132 


128only after its evidence supports the claimed issue.136only after its evidence supports the claimed issue.

129 137 

130Keep the scan directory together when sharing or archiving it. It contains138Keep the scan directory together when sharing or archiving it. It contains

131`scan-manifest.json`, `findings.json`, and `coverage.json` alongside the report139`scan-manifest.json` and `findings.json` alongside the report

132and supporting artifacts. See [Scan140and supporting artifacts. See [Scan

133artifacts](https://learn.chatgpt.com/docs/security/cli/reference#scan-artifacts) for the full layout.141artifacts](https://learn.chatgpt.com/docs/security/cli/reference#scan-artifacts) for the full layout.

134 142 


170| Goal | Guide |178| Goal | Guide |

171| ------------------------------------------------ | ---------------------------------------------------------------------------------------- |179| ------------------------------------------------ | ---------------------------------------------------------------------------------------- |

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

181| Scan components of one repository in parallel | [Component scans](https://learn.chatgpt.com/docs/security/cli/reference#codex-security-scan-components) |

182| Use a test script to validate candidate findings | [Custom validation](https://learn.chatgpt.com/docs/security/cli/reference#validate-findings-in-your-environment) |

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

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

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

Details

6For a first scan, follow the6For a first scan, follow the

7[CLI quickstart](https://learn.chatgpt.com/docs/security/cli).7[CLI quickstart](https://learn.chatgpt.com/docs/security/cli).

8 8 

9The `@openai/codex-security` package is public. Scans using OpenAI inference9Scans use your local permissions and don't pause for approval. Some

10 require Codex Security access. Scans use your local permissions and don't10 cybersecurity requests and protected findings require

11 pause for approval. Before you start, review [Local scan11 [Trusted Access for Cyber](https://chatgpt.com/cyber)

12 permissions](#local-scan-permissions).12 . See [Local scan permissions](#local-scan-permissions).

13 13 

14Run the CLI with `npx @openai/codex-security`. For older installations, check14Run the CLI with `npx @openai/codex-security`. The installed package also

15`--version` and command-specific `--help`. The installed package also provides15provides the `cs` alias.

16the `cs` alias.

17 16 

18## Command overview17## Command overview

19 18 


133 [--post-scan-prompt-file FILE]132 [--post-scan-prompt-file FILE]

134 [--mode {standard,deep}] [--workers N]133 [--mode {standard,deep}] [--workers N]

135 [--subagents N] [--stop-after-no-new N]134 [--subagents N] [--stop-after-no-new N]

136 [--max-discovery-runs N] [--max-time-hours HOURS]135 [--max-discovery-runs N] [--max-time MINUTES]

137 [--model MODEL]136 [--model MODEL]

138 [--effort EFFORT]137 [--effort EFFORT]

139 [--output-dir DIR]138 [--output-dir DIR]

140 [--archive-existing]139 [--archive-existing]

141 [--plugin-path PATH] [--python PATH]140 [--plugin-path PATH] [--python PATH]

142 [--codex KEY=VALUE] [--fail-on-severity LEVEL]141 [--codex KEY=VALUE] [--fail-on-severity LEVEL]

143 [--patch] [--patch-severity {critical,high,medium,low}]142 [--validate] [--patch] [--patch-severity {critical,high,medium,low}]

144 [--create-pr]143 [--create-pr]

145 [--max-cost USD] [--show-cost] [--dry-run] [--mock]144 [--max-cost USD] [--show-cost] [--dry-run] [--mock]

146 [--workflow-id ID] [--safety-identifier ID]145 [--workflow-id ID] [--safety-identifier ID]


207hashed identifier with API-key authentication. Use 1–64 characters without NUL206hashed identifier with API-key authentication. Use 1–64 characters without NUL

208or personal data such as email addresses.207or personal data such as email addresses.

209 208 

210The bundled runtime doesn't yet support this option. It requires a compatible209To forward the identifier, use `CODEX_CLI_PATH` to select a Codex build that

211Codex build selected with `CODEX_CLI_PATH` and a plugin that forwards the210supports this option and a plugin that passes it to workers. The bundled Codex

212identifier to workers. The SDK validates the identifier format, not runtime211runtime doesn't support it.

213or plugin compatibility; older versions may omit it.

214 212 

215### Use OpenRouter or Fireworks213### Use OpenRouter or Fireworks

216 214 


293scan to check access. For AWS authentication or access-denied errors, check291scan to check access. For AWS authentication or access-denied errors, check

294your credentials, region, and model permissions.292your credentials, region, and model permissions.

295 293 

296#### Bedrock release status294#### Bedrock cost estimates

297 295 

298Starting in 0.2.0, `@openai/codex-security` supports cost estimates and `--max-cost` for296The CLI supports cost estimates and `--max-cost` for the Daybreak Blue and

299the Daybreak Blue and Daybreak Red model IDs above. Estimates use AWS Standard297Daybreak Red model IDs above. Estimates use AWS Standard

300commercial in-region prices, including the AWS fee. The cost limit uses298commercial in-region prices, including the AWS fee. The cost limit uses

301`estimatedUsd`, the short-context baseline. Requests already in progress can299`estimatedUsd`, the short-context baseline. Requests already in progress can

302put this estimate above the limit. Long-context pricing can raise the reported300put this estimate above the limit. Long-context pricing can raise the reported

303`estimatedUsdRange` above it. This limit is not a billing cap.301`estimatedUsdRange` above it. This limit is not a billing cap.

304 302 

305Check your installed package and bundled Codex versions:

306 

307```bash

308npx @openai/codex-security --version

309npx @openai/codex-security info --json

310```

311 

312Use `npx @openai/codex-security scan --help` to check the options available

313in your installed version.

314 

315### Select the scan target303### Select the scan target

316 304 

317Choose one target type for each scan.305Choose one target type for each scan.


364 352 

365### Configure deep scans353### Configure deep scans

366 354 

367Use these options with `--mode deep` to control worker concurrency and runtime:355Use these options with `--mode deep` to control discovery:

368 356 

369| Argument | Description |357| Argument | Description |

370| ------------------------ | -------------------------------------------------------------------------------------- |358| ------------------------ | ----------------------------------------------------------------------------------------------------- |

371| `--workers N` | Limit on concurrent independent standard-scan workers. Defaults to `4`. |359| `--workers N` | Limit on concurrent independent standard-scan workers. Defaults to `4`. |

372| `--subagents N` | Subagents available to each worker. Defaults to `3`. |360| `--subagents N` | Subagents available to each worker. Defaults to `3`. Use `0` to disable them. |

373| `--stop-after-no-new N` | Stop after `N` consecutive completed worker scans find no new issues. Defaults to `4`. |361| `--stop-after-no-new N` | Stop after `N` consecutive completed worker scans find no new issues. Defaults to `4`. |

374| `--max-discovery-runs N` | Limit on total independent standard-scan runs. Defaults to `40`. |362| `--max-discovery-runs N` | Limit on total independent standard-scan runs. Defaults to `40`. |

375| `--max-time-hours HOURS` | Worker execution time limit in hours. Defaults to `96`; accepts fractions. |363| `--max-time MINUTES` | Discovery time limit. Accepts positive fractional minutes. The default and maximum are 5,760 minutes. |

376 364 

377`--subagents` accepts zero or a positive integer. `--max-time-hours` accepts a365For example, use two workers, allow up to ten runs, and stop discovery after 90 minutes:

378positive number no greater than `96`. The remaining options require a positive

379integer. These options aren't available for standard scans.

380 

381For example, use two workers, allow up to ten runs, and stop worker execution

382after 1.5 hours:

383 366 

384```bash367```bash

385npx @openai/codex-security scan . \368npx @openai/codex-security scan . \


388 --subagents 0 \371 --subagents 0 \

389 --stop-after-no-new 3 \372 --stop-after-no-new 3 \

390 --max-discovery-runs 10 \373 --max-discovery-runs 10 \

391 --max-time-hours 1.5374 --max-time 90

392```375```

393 376 

394When the time limit expires, the scan stops unfinished workers, keeps completed377When the time limit expires, the scan stops unfinished workers and combines

395scan results, and aggregates them into the final report. Reaching a configured378completed findings in its report. For a standard scan, `--max-time` sets an

396limit with a valid finalized report isn't an execution failure. Review its379advisory investigation time. Reporting can finish later. Custom validation

397follow-up work and coverage notes; see [Exit codes and signals](#exit-codes-and-signals).380and post-scan instructions run outside that allowance.

398 381 

399Set persistent defaults in `~/.codex/codex-security/config.toml`, or in382To reuse these limits, save them in a

400`$CODEX_HOME/codex-security/config.toml` when you set `CODEX_HOME`:383[project configuration file](#load-project-configuration):

401 384 

402```toml385```yaml

403[deep_scan]386scan:

404workers = 2387 mode: deep

405subagents = 0388 max_time_minutes: 90

406stop_after_no_new = 3389 deep:

407max_discovery_runs = 10390 workers: 2

408max_time_hours = 1.5391 subagents_per_worker: 0

392 stop_after_no_new: 3

393 max_discovery_runs: 10

409```394```

410 395 

411Command-line options override these defaults. `scan --workers` controls396Command-line options override the project configuration. Use

412independent standard-scan workers within one deep scan; `bulk-scan --workers`397`scan.deep.stop_after_consecutive_errors` to change how many consecutive worker

413controls concurrent repository scans. Set `stop_after_consecutive_errors` in398errors stop discovery. The default is `3`. For `bulk-scan`, `--workers`

414the legacy TOML file or `scan.deep.stop_after_consecutive_errors` in a project399controls concurrent repository scans.

415file; its default is `3`.

416 400 

417### Add security context401### Add security context

418 402 


451The follow-up doesn't run after cancellation or when the scan reaches its cost435The follow-up doesn't run after cancellation or when the scan reaches its cost

452limit. When it runs, the follow-up is outside scan cost tracking and `--max-cost`.436limit. When it runs, the follow-up is outside scan cost tracking and `--max-cost`.

453 437 

454Use `--validation-prompt-file FILE` to replace final validation with your own438### Validate findings in your environment

455workflow in Standard and diff scans. Source review still runs. Include setup,439 

456authorized targets, required evidence, and cleanup. Deep scans reject custom440Use `--validation-prompt-file FILE` to replace the final validation step with

457validation; scans with no candidates skip it.441your own test procedure. Codex reviews the source first and skips validation if

442it finds no candidates. Keep the prompt and test script in a directory you

443control outside the checkout:

444 

445```bash

446npx @openai/codex-security scan . \

447 --validation-prompt-file /path/to/security-tests/validation.md

448```

449 

450For example, if your local test server is running, put these instructions in

451`validation.md`:

452 

453```text

454Run /path/to/security-tests/validate.sh against http://localhost:3000.

455Report which findings reproduce and include the relevant test output.

456```

457 

458Use this flag with standard repository, path, diff, or working-tree scans. For

459standard component scans, set `scan.validation_file` in the

460[project configuration](#load-project-configuration). Deep scans reject custom validation.

461 

462Add `--validate` to a new scan command for a separate source-only assessment

463of each reported finding. If the scan reports findings, the CLI writes the

464assessments to a report in the scan directory. They don't change the findings

465or severity-policy decision. You can't combine `--validate` with `--dry-run`,

466`--mock`, or a scan cost limit set on the command line or in the project

467configuration.

458 468 

459### Set output and policy options469### Set output and policy options

460 470 


476| `--dry-run` | Check the repository, target, knowledge base, output directory, and Codex configuration without starting a scan. |486| `--dry-run` | Check the repository, target, knowledge base, output directory, and Codex configuration without starting a scan. |

477| `--headless` | Show plain-text progress instead of the interactive scan dashboard. |487| `--headless` | Show plain-text progress instead of the interactive scan dashboard. |

478| `--verbose` | Print additional lifecycle, authentication, progress, and cost diagnostics to stderr. |488| `--verbose` | Print additional lifecycle, authentication, progress, and cost diagnostics to stderr. |

479| `--json` | Print manifest, findings, coverage, paths, and turn metadata as one JSON document. |489| `--json` | Print the manifest, findings, review exclusions, paths, and turn metadata as one JSON document. |

480| `--format FORMAT` | Print the complete scan result as `toon`, `json`, `yaml`, or `jsonl`. |490| `--format FORMAT` | Print the complete scan result as `toon`, `json`, `yaml`, or `jsonl`. |

481| `--full-output` | Print the complete result using the default structured output format. |491| `--full-output` | Print the complete result using the default structured output format. |

482 492 


563Add `--dry-run --verbose` to your scan command to inspect the resolved model573Add `--dry-run --verbose` to your scan command to inspect the resolved model

564and effort before starting a scan.574and effort before starting a scan.

565 575 

566To select a different model and reasoning effort without writing TOML, choose a576To choose a model and reasoning effort, select a [Codex model](https://learn.chatgpt.com/docs/models)

567model your credentials can access. If you use ChatGPT sign-in, check [GPT-6.1577available to your account:

568Sol availability](https://learn.chatgpt.com/docs/models#gpt-6.1-sol) before using these examples:

569 578 

570```bash579```bash

571npx @openai/codex-security scan . --model gpt-6.1-sol --effort medium580npx @openai/codex-security scan . --model gpt-6.1-sol --effort medium


707 716 

708## `codex-security scan-components`717## `codex-security scan-components`

709 718 

710Run a separate scan for each component of one repository:719Use `scan-components` to scan services or packages in one repository separately.

720Each run, including a plan-only run, needs a new or empty output directory

721outside the enclosing Git worktree. Set it with `--output-dir` or with

722`output.directory` in the project configuration.

723 

724For example, scan two services in parallel:

711 725 

712```bash726```bash

713npx @openai/codex-security scan-components . \727npx @openai/codex-security scan-components . \

714 --component apps/api --component apps/web \728 --component apps/api --component apps/web \

715 --workers 4 --output-dir /path/outside/repository/components729 --output-dir /path/outside/repository/manual-components

716```730```

717 731 

718Unlike `scan --path`, this command produces a scan per component, then combines732Unlike `scan --path`, this command produces a scan per component, then combines

719and matches the findings. Use `--components-file FILE` for a saved plan. To733and matches the findings. By default, four component scans can run at once.

720propose a split for review before scanning:734Set `--workers N` to change that limit. `--max-cost USD` limits each component

735scan. It excludes automatic planning and cross-component matching.

736 

737To have Codex propose a split, save a plan for review before scanning:

721 738 

722```bash739```bash

723npx @openai/codex-security scan-components . --auto --plan-only \740npx @openai/codex-security scan-components . --auto --plan-only \

724 --output-dir /path/outside/repository/component-plan741 --output-dir /path/outside/repository/component-plan

725```742```

726 743 

727Component scans require `--output-dir` or `output.directory` in the project744Review the component names and paths in `components.json`, then run the saved

728configuration, including plan-only runs. Failed scans or matching failures745plan in a new output directory:

729return `2`; severity-policy violations return `1`. See the [component scan guide](https://github.com/openai/codex-security/blob/main/sdk/typescript/docs/cli.md#scan-project-components) for plan syntax and retries.746 

747```bash

748npx @openai/codex-security scan-components . \

749 --components-file /path/outside/repository/component-plan/components.json \

750 --output-dir /path/outside/repository/components

751```

752 

753Open `report.md` in the output directory to review the combined findings. If

754a component fails, use the saved retry plan to rerun only the failed components:

755 

756```bash

757npx @openai/codex-security scan-components . \

758 --components-file /path/outside/repository/components/retry-components.json \

759 --output-dir /path/outside/repository/retry-results

760```

761 

762The retry report covers only the retried components. Keep the original report

763to review findings from components that completed on the first run.

764 

765Failed scans or matching failures return `2`. Severity-policy violations return `1`. See the [component scan guide](https://github.com/openai/codex-security/blob/main/sdk/typescript/docs/cli.md#scan-project-components) for plan syntax and retries.

730 766 

731## `codex-security bulk-scan`767## `codex-security bulk-scan`

732 768 


753Run `npx @openai/codex-security bulk-scan` without arguments to select789Run `npx @openai/codex-security bulk-scan` without arguments to select

754repositories interactively. This flow requires a GitHub CLI sign-in.790repositories interactively. This flow requires a GitHub CLI sign-in.

755 791 

756To choose a model and reasoning effort during interactive discovery, use a model792For interactive discovery, select a [Codex model](https://learn.chatgpt.com/docs/models) available

757your credentials can access. See [GPT-6.1 Sol availability with ChatGPT793to your account:

758sign-in](https://learn.chatgpt.com/docs/models#gpt-6.1-sol):

759 794 

760```bash795```bash

761npx @openai/codex-security bulk-scan --model gpt-6.1-sol --effort medium796npx @openai/codex-security bulk-scan --model gpt-6.1-sol --effort medium


939## `codex-security export`974## `codex-security export`

940 975 

941Export saved findings or a threat model without starting Codex or loading976Export saved findings or a threat model without starting Codex or loading

942credentials. You can export findings as CSV, JSON, or SARIF only from a977credentials. You can export findings as CSV, JSON, SARIF, or a ServiceNow AVIT

943completed, sealed scan. Threat models use Markdown.978CSV only from a completed, sealed scan. Threat models use Markdown.

944 979 

945```text980```text

946usage: codex-security export [scan_dir | --scan SCAN_ID]981usage: codex-security export [scan_dir | --scan SCAN_ID]

947 [--artifact {findings,threat-model}]982 [--artifact {findings,threat-model}]

948 [--export-format {csv,json,sarif,md}]983 [--export-format {csv,json,sarif,md,servicenow-avit}]

984 [--avit-template FILE]

949 [--output FILE|-] [--source-root PATH]985 [--output FILE|-] [--source-root PATH]

950 [--python PATH]986 [--python PATH]

951```987```


956these selectors.992these selectors.

957 993 

958| Argument | Description |994| Argument | Description |

959| ------------------------------------- | ------------------------------------------------------------------------------------------- |995| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------ |

960| `--artifact {findings,threat-model}` | Select the saved artifact. The default is `findings`. |996| `--artifact {findings,threat-model}` | Select the saved artifact. The default is `findings`. |

961| `--scan SCAN_ID` | Select a saved scan by ID or unique prefix of at least eight characters. |997| `--scan SCAN_ID` | Select a saved scan by ID, unique prefix of at least eight characters, or `latest`. |

962| `--export-format {csv,json,sarif,md}` | Select the format. Findings default to `sarif`; threat models support only `md`. |998| `--export-format FORMAT` | Select `csv`, `json`, `sarif`, `md`, or `servicenow-avit`. Findings default to `sarif`; threat models support only `md`. |

999| `--avit-template FILE` | Supply the CSV template that `servicenow-avit` requires. Only this format accepts it. |

963| `--output FILE\|-` | Write the selected format to a file or stdout. Defaults to a file in the current directory. |1000| `--output FILE\|-` | Write the selected format to a file or stdout. Defaults to a file in the current directory. |

964| `--source-root PATH` | Add source-line fingerprints to SARIF using a repository checkout. |1001| `--source-root PATH` | Add source-line fingerprints to SARIF using a repository checkout. |

965| `--python PATH` | Select the Python interpreter for the bundled exporter. |1002| `--python PATH` | Select the Python interpreter for the bundled exporter. |


969not include local workbench triage state.1006not include local workbench triage state.

970 1007 

971Without `--output`, the CLI writes SARIF to `results.sarif`, JSON to1008Without `--output`, the CLI writes SARIF to `results.sarif`, JSON to

972`findings.json`, CSV to `findings.csv`, and Markdown to `threatmodel.md` in the1009`findings.json`, CSV to `findings.csv`, ServiceNow AVIT CSV to

973current working directory.1010`servicenow-avit.csv`, and Markdown to `threatmodel.md` in the current working

1011directory.

974Exports can contain source excerpts and vulnerability details. Pass `--output`1012Exports can contain source excerpts and vulnerability details. Pass `--output`

975with a private path outside the checkout. When running outside the repository,1013with a private path outside the checkout. When running outside the repository,

976also specify a result directory or `--scan`.1014also specify a result directory or `--scan`.


1011 --output /path/outside/repository/exports/findings.csv1049 --output /path/outside/repository/exports/findings.csv

1012```1050```

1013 1051 

1052### Export findings for ServiceNow

1053 

1054ServiceNow requires the **Ethical Hacker** role (`sn_vul.app_pen_tester`).

1055Open **All** > **Manual AVIT Ingestion** > **Upload File UI** and download the

1056CSV template. Keep the original headers and exactly one data row.

1057Use the exact ServiceNow application name. Fill in the purpose, sensitive data

1058types, compliance programs, technology stack, application team, and URLs to test.

1059Set **Requested by**, **Assigned to**, and **Assignment group**. Leave the

1060finding fields blank. Save the template as `app.csv` in a private directory

1061outside the scanned repository. Reuse it for scans of the same application.

1062 

1063From the scanned repository, export the latest findings with that template.

1064Keep the output in the private directory as well:

1065 

1066```bash

1067npx @openai/codex-security export --scan latest \

1068 --export-format servicenow-avit \

1069 --avit-template /path/outside/repository/exports/app.csv \

1070 --output /path/outside/repository/exports/findings-avit.csv

1071```

1072 

1073The CLI writes one row per finding and fills **Steps to reproduce** from the

1074recorded attack path when available. Review those steps and fill in any blanks

1075in the exported CSV. Return to **Upload File UI**, select **Import File**,

1076upload the CSV, and select **Submit**. Each upload creates a new penetration

1077test form for the application.

1078See the [ServiceNow upload instructions](https://www.servicenow.com/docs/r/security-management/application-vulnerability-response/ingest-vulnerabilities-manually-avr.html).

1079 

1014### Export a saved threat model1080### Export a saved threat model

1015 1081 

1016Starting in version 0.2.0, scans save their threat models for reuse without1082Export the latest completed scan's saved threat model to stdout without making

1017another model call. Export the latest completed scan's model to stdout:1083another model call:

1018 1084 

1019```bash1085```bash

1020npx @openai/codex-security export --artifact threat-model --output -1086npx @openai/codex-security export --artifact threat-model --output -


1223 1289 

1224### Patch findings after a scan1290### Patch findings after a scan

1225 1291 

1226Use `scan --patch` to fix findings after a complete scan. This requires1292Use `scan --patch` to fix findings after a completed scan. The default severity

1227`@openai/codex-security` 0.1.15 or later. The default severity threshold is1293threshold is `low`. This command selects high and critical findings:

1228`low`. This command selects high and critical findings:

1229 1294 

1230```bash1295```bash

1231npx @openai/codex-security scan . --patch --patch-severity high --json1296npx @openai/codex-security scan . --patch --patch-severity high --json


1332`--format`, or `--full-output` to send structured scan results to stdout.1397`--format`, or `--full-output` to send structured scan results to stdout.

1333 1398 

1334Interactive terminals show a live dashboard with the current scan phase,1399Interactive terminals show a live dashboard with the current scan phase,

1335reviewed files, activity, token usage, and estimated cost. CI and redirected1400file inventory, activity, token usage, and estimated cost. CI and redirected

1336output use plain-text progress. Add `--headless` to use plain-text progress in1401output use plain-text progress. Add `--headless` to use plain-text progress in

1337an interactive terminal:1402an interactive terminal:

1338 1403 


1362### Completion summary1427### Completion summary

1363 1428 

1364A completed scan writes its open repository finding count, severity breakdown,1429A completed scan writes its open repository finding count, severity breakdown,

1365elapsed time, report path, and result directory to stderr. It includes token1430elapsed time, report path, and result directory to stderr. It also reports token

1366usage when available and estimated cost when you set `--show-cost` or1431usage when available and estimated cost when you set `--show-cost` or

1367`--max-cost`:1432`--max-cost`. For example:

1368 1433 

1369```text1434```text

1370 REPORT /path/to/scan/report.md1435 REPORT /path/to/scan/report.md

1371 1436 

1372 FINDINGS 4 (3 confirmed this scan; 1 previously found; 1 critical, 2 high, 1 informational)1437 FINDINGS 4 (3 confirmed this scan; 1 previously found; 1 critical, 2 high, 1 informational)

1438 SCOPE repository: .

1373 ELAPSED 1s1439 ELAPSED 1s

1374 TOKENS 1,250 input, 200 cached, 30 output

1375 RESULTS /path/to/scan1440 RESULTS /path/to/scan

1376```1441```

1377 1442 


1381 1446 

1382### JSON output1447### JSON output

1383 1448 

1384`scan --json` writes one complete JSON document to stdout. Its top-level shape1449`scan --json` writes one JSON document to stdout. Use `manifest.scan` for

1385is:1450status and scope and `findings` for the current scan's findings. When available,

1386 1451`repositoryFindings` includes those findings and earlier open findings.

1387```text1452`review.excludedPaths` lists path patterns the scan recorded as excluded from

1388manifest1453review. `scanDir`, `reportPath`, and `artifactsDir` point to the saved results.

1389repositoryFindings

1390findings

1391coverage

1392threatModel

1393threatModelPath

1394scanDir

1395threadId

1396reportPath

1397artifactsDir

1398sarifPath

1399cost

1400turn

1401 id

1402 status

1403 durationMs

1404 finalResponse

1405 usage

1406```

1407 1454 

1408`threatModel` contains the saved model as structured data or Markdown.1455`threatModel` contains the saved model as structured data or Markdown.

1409`threatModelPath` points to its saved document. Either can be `null`; the model1456`threatModelPath` points to its saved document. Either can be `null`; the model


1440<scan-directory>/1487<scan-directory>/

1441├── scan-manifest.json1488├── scan-manifest.json

1442├── findings.json1489├── findings.json

1443├── coverage.json

1444├── report.md1490├── report.md

1445├── threatmodel.md # when available1491├── threatmodel.md # when available

1446├── artifacts/1492├── artifacts/


1454| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------- |1500| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------- |

1455| `scan-manifest.json` | Scan identity, status, target, scope, producer, and sealed artifact records. |1501| `scan-manifest.json` | Scan identity, status, target, scope, producer, and sealed artifact records. |

1456| `findings.json` | Finding identifiers, severity, confidence, taxonomy, locations, evidence, validation, data flow, reachability, and remediation. |1502| `findings.json` | Finding identifiers, severity, confidence, taxonomy, locations, evidence, validation, data flow, reachability, and remediation. |

1457| `coverage.json` | Recorded review scope, exclusions, deferred work, and open questions. |

1458| `report.md` | Readable scan report. |1503| `report.md` | Readable scan report. |

1459| `threatmodel.md` | Saved threat model, when available. |1504| `threatmodel.md` | Saved threat model, when available. |

1460| `artifacts/` | Supporting scan artifacts. |1505| `artifacts/` | Supporting scan artifacts. |


1462 1507 

1463### Completion and review coverage1508### Completion and review coverage

1464 1509 

1465A completed scan means the requested workflow finished normally. It doesn't prove that1510Read `scan.status` in `scan-manifest.json` to check whether the scan

1466every file or attack path was reviewed. Read `coverage.json`, `report.md`, and1511completed. Read `scan.scope` for the configured scope and

1467the recorded scope in `scan-manifest.json` for exclusions, deferred work, and1512`scan.review.excludedPaths` for exclusions the scan recorded during review.

1468open questions. Retained input inventories describe scan inputs but don't prove1513Scan comparisons also use those exclusions. A completed scan can still leave

1469that every listed file was reviewed.1514some files in scope unreviewed.

1470 

1471Current reports omit `coverage.completeness`. Older reports may contain

1472`complete`, `partial`, or `unknown`; those legacy values no longer determine

1473the command's status or exit code. Use `manifest.scan.status` and the

1474[exit code](#exit-codes-and-signals) to distinguish execution failures from

1475findings-policy violations.

1476 1515 

1477For unresolved work, inspect the available evidence with `scans show SCAN_ID`1516For unresolved work, inspect the available evidence with `scans show SCAN_ID`

1478and `scans logs SCAN_ID`. An eligible interrupted Deep Scan can continue with1517and `scans logs SCAN_ID`. An eligible interrupted Deep Scan can continue with

Details

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 

5Use a completed Codex Security scan for either of these handoffs:5Export findings from a completed scan to use them in another tool. To track

6 6remediation or coordinate disclosure, ask Codex to prepare an issue or a

7- **Export** creates a portable JSON, CSV, or SARIF file.7private draft GitHub Security Advisory.

8- **Track findings** prepares selected findings as Linear, GitHub, or Jira

9 issues, or as one private draft GitHub Security Advisory. Codex checks for

10 duplicates and waits for your approval before writing.

11 

12Neither workflow changes the sealed scan bundle.

13 

14Available artifact links and export formats depend on your Codex surface and

15 installed plugin version. Check the [plugin

16 changelog](https://learn.chatgpt.com/docs/security/plugin/changelog) before you use a format in

17 automation.

18 8 

19## Export a portable artifact9## Export a portable artifact

20 10 

21In the desktop app, open a completed scan from **Security** > **Scans**. Use its11In the desktop app, open a completed scan from **Security** > **Scans**. Under

22available artifact links to inspect `report.md`, `findings.json`,12**Artifacts**, select **Findings JSON** to open the structured findings or

23`scan-manifest.json`, `coverage.json`, or a SARIF report when present.13**SARIF report** if the scan produced one. Available artifacts depend on the

24 14app and plugin version.

25To create another supported format, ask Codex to export findings from the

26completed scan without modifying its sealed bundle:

27 

28```text

29Export the findings from [completed scan directory] as [JSON, CSV, or SARIF]. Do not modify the sealed scan bundle or upload its contents.

30```

31 15 

32Choose the format that fits your destination:16When Codex offers to export the scan's findings, ask for JSON, CSV, or SARIF.

17To export from a terminal, use the saved scan directory with the

18[CLI export command](https://learn.chatgpt.com/docs/security/cli/reference#codex-security-export).

33 19 

34| Format | Use it for |20| Format | Use it for |

35| ------ | ----------------------------------------------------------------- |21| ------ | ----------------------------------------------------------------- |

36| JSON | Preserve the sealed structured findings for tools and scripts. |22| JSON | Preserve the sealed structured findings for tools and scripts. |

37| CSV | Review findings and current local triage state in a spreadsheet. |23| CSV | Review findings in a spreadsheet. |

38| SARIF | Send findings to tools that support the SARIF interchange format. |24| SARIF | Send findings to tools that support the SARIF interchange format. |

39 25 

26To include your latest triage status, close reasons, or notes, export a CSV

27from the plugin after making those changes. Open `exports/findings.csv` in

28the scan directory. The CLI exports the saved scan without local triage updates.

29 

40<figure className="not-prose my-8">30<figure className="not-prose my-8">

41 <CodexScreenshot31 <CodexScreenshot

42 alt="Completed Codex Security scan showing the real coverage, findings, manifest, Markdown, and SARIF artifacts"32 alt="Completed Codex Security scan showing the real coverage, findings, manifest, Markdown, and SARIF artifacts"


50 </figcaption>40 </figcaption>

51</figure>41</figure>

52 42 

53Select **Markdown report** to open `report.md` in your configured external43Select **Markdown report** to open `report.md` in your configured editor.

54editor. The editor depends on your system settings; the example below shows the

55generated report contents.

56 44 

57<figure className="not-prose my-8">45<figure className="not-prose my-8">

58 <CodexScreenshot46 <CodexScreenshot


67 </figcaption>55 </figcaption>

68</figure>56</figure>

69 57 

70Use the returned artifact path. If another tool needs the complete scan58Keep the whole scan directory when you archive the report. Tracking requires

71context, keep the original `scan-manifest.json`, `findings.json`, and59the original `scan-manifest.json` and `findings.json`. If you need to edit

72`coverage.json` together. Exporting doesn't upload findings to a code-scanning60the findings, make your own copy of `findings.json` first.

73service.

74 61 

75## Track selected findings62## Track selected findings

76 63 

77Run `$codex-security:track-findings` with one validated finding or an64Use `$codex-security:track-findings` with one or more validated findings from

78selected batch of up to 25 findings from the same sealed scan. Each65the same completed scan. Choose one destination for each run.

79run uses one provider and one destination. A private draft GitHub Security

80Advisory accepts only one finding.

81 

82To prepare a Linear issue, send:

83 

84```text

85Use $codex-security:track-findings to prepare finding [finding ID] from

86[completed scan directory] for the Linear team [team] and project [project, if

87any]. Check for duplicates and show me the exact issue title, body, metadata,

88and destination. Do not create or update anything until I approve that payload.

89```

90 

91To prepare a GitHub issue, send:

92 

93```text

94Use $codex-security:track-findings to prepare finding [finding ID] from

95[completed scan directory] for GitHub repository [owner/repository]. Check open

96and closed issues for duplicates and show me the exact issue title, body,

97metadata, repository visibility, and authenticated transport. Do not create or

98update anything until I approve that payload.

99```

100 66 

101To prepare a Jira issue, send:67| Destination | What to specify |

68| -------------------------------------- | ---------------------------------------------------------- |

69| Linear issue | Team and optional project |

70| GitHub issue | Owner and repository |

71| Jira issue | Site, project, and issue type in the Atlassian app |

72| Private draft GitHub Security Advisory | One finding and its public source repository on GitHub.com |

102 73 

103```text74```text

104Use $codex-security:track-findings to prepare finding [finding ID] from75Use $codex-security:track-findings to draft a Linear issue for team [team]

105[completed scan directory] for Jira project [project key] as [issue type].76about finding [finding ID] in [completed scan directory].

106Check for duplicates and show me the exact issue summary, description,

107metadata, and destination. Do not create or update anything until I approve

108that payload.

109```77```

110 78 

111Jira tracking requires the Atlassian Rovo plugin in Codex. Reusing an issue79For a batch, list the finding IDs in your request. To track findings in Jira,

112requires read access; creating or updating one requires read and write access.80connect the Atlassian app in Codex. Confirm who can read issues in the

81project. Creating an issue requires browse and create permissions. You need

82read access to reuse an existing issue and both read and edit access to update it.

113 83 

114To prepare a private draft GitHub Security Advisory, send:84For a draft advisory, sign in to GitHub.com with GitHub CLI (`gh`) using an

85 account with administrator access to the public, non-fork source repository.

86 Select one finding from a scan whose target is a Git revision

87 (`git_revision`). Commit-diff scans don't qualify. Have the package name,

88 ecosystem, and affected versions ready.

115 89 

116```text90<a id="review-the-proposed-write"></a>

117Use $codex-security:track-findings to prepare finding [finding ID] from

118[completed scan directory] as a private draft GitHub Security Advisory in

119[owner/repository]. Verify the sealed source revision, repository, affected

120paths, package metadata, and duplicate state. Show me the exact advisory

121payload, authenticated GitHub CLI identity, and disclosure warnings. Do not

122create anything until I approve that payload.

123```

124 91 

125Draft advisories require one finding from a sealed `git_revision` scan, the92## Review the issue or advisory

126 verified public canonical source repository, and administrator access. The

127 workflow doesn't batch, update, publish, or close advisories. Use a private

128 issue destination when the source doesn't meet those requirements.

129 

130## Review the proposed write

131 93 

132<WorkflowSteps>94<WorkflowSteps>

133 95 

1341. Confirm the finding ID and fingerprint came from the intended sealed scan.961. Check the source scan, selected findings, and signed-in account. Confirm

1352. Confirm the provider, exact Linear team, GitHub repository, Jira project, or97 the destination and who can read it. Use a private destination for sensitive

136 advisory repository, and the live destination visibility.98 findings. An internal or public GitHub issue requires explicit disclosure

1373. Review the duplicate outcome: `create`, `reuse`, `update`, or `blocked`.99 approval.

1384. Read the complete proposed title, body, source locations, and provider1002. Check whether Codex proposes to create, reuse, or update an issue.

139 metadata. Remove exploit detail or internal evidence that the destination101 For advisories, it can create a private draft or reuse a matching draft or

140 shouldn't expose.102 published advisory.

1415. Approve only that exact payload. A changed destination, visibility, finding1033. Read the title, body, and source locations. A draft advisory may become public.

142 set, or body requires a new preview.104 Remove credentials, private evidence, and unnecessary exploit details.

1054. Approve the preview in the Codex conversation before Codex creates or

106 updates an item. If the preview changes, review and approve it again.

143 107 

144</WorkflowSteps>108</WorkflowSteps>

145 109 

146Sensitive findings should go to a private destination. Creating an issue in an110<a id="verify-the-tracked-item"></a>

147internal or public GitHub repository requires an explicit visibility warning

148and approval of the complete content. Treat a draft advisory description as

149eventually public and remove credentials, private evidence, and unnecessary

150exploit details before approval.

151 

152Review and approve external actions in the Codex conversation. Approval

153doesn't create a separate issue or advisory screen in the Security workbench.

154 111 

155## Verify the tracked item112Save the issue ID or link the tracker returns, even if Codex can't reopen the

113issue. For a new advisory, Codex checks that the draft matches what you

114approved.

156 115 

157After you approve the proposed write, Codex rechecks the sealed source,116If Codex can't tell whether it created or updated an item, it stops the batch.

158destination, access, and duplicate state. For a batch, it processes findings117Before retrying, check the tracker for the issue or advisory and ask Codex

159one at a time and stops at the first uncertain result. Creation, update, or118which findings it hasn't tried yet.

160reuse is complete only after Codex reads the exact issue back and verifies its

161binding identifiers and content.

162 119 

163Keep the returned canonical issue or advisory URL with your triage record.

164Continue with [Fix and verify a finding](https://learn.chatgpt.com/docs/security/plugin/fix-findings)120Continue with [Fix and verify a finding](https://learn.chatgpt.com/docs/security/plugin/fix-findings)

165when the owner accepts the item for remediation.121when the owner accepts the item for remediation.

security/sdk.md +125 −58

Details

4 4 

5Use the Codex Security TypeScript SDK to run security scans on repositories and5Use the Codex Security TypeScript SDK to run security scans on repositories and

6code changes from your application or developer tool. The SDK returns typed6code changes from your application or developer tool. The SDK returns typed

7findings, coverage details, and paths to scan artifacts. For longer scans, it7findings, the scan manifest, and paths to saved reports.

8supports preflight checks, cost limits, progress callbacks, and cancellation.

9 8 

10The SDK uses ECMAScript modules (ESM) and runs server-side with Node.js 24 or 26,9The SDK uses ECMAScript modules (ESM) and runs server-side with Node.js 24 or 26,

11or Node.js 22 starting with 22.13.0. Scanning also requires Python 3.10 or later.10or Node.js 22 starting with 22.13.0. Scanning also requires Python 3.10 or later.


1522.15.0 or later within 22.x, or Node.js 24 or 26. Plain `.jsonl` sessions work1422.15.0 or later within 22.x, or Node.js 24 or 26. Plain `.jsonl` sessions work

16on all supported Node.js versions.15on all supported Node.js versions.

17 16 

18Scans using OpenAI inference require Codex Security access. For general coding17For general coding agents, see the [Codex SDK guide](https://learn.chatgpt.com/docs/codex-sdk). For

19 agents, see the [Codex SDK guide](https://learn.chatgpt.com/docs/codex-sdk). For terminal and CI18 terminal and CI workflows, see the [Codex Security CLI

20 workflows, see the [Codex Security CLI quickstart](https://learn.chatgpt.com/docs/security/cli).19 quickstart](https://learn.chatgpt.com/docs/security/cli).

21 20 

22## Set up the SDK21## Set up the SDK

23 22 


27npm install @openai/codex-security26npm install @openai/codex-security

28```27```

29 28 

30This guide covers the released 0.3.0 SDK. Read the [0.3.0 release notes](https://github.com/openai/codex-security/releases/tag/npm-v0.3.0) for changes to scan results, validation, and resume behavior.

31 

32Before starting a scan, set `OPENAI_API_KEY` or `CODEX_API_KEY`, use an29Before starting a scan, set `OPENAI_API_KEY` or `CODEX_API_KEY`, use an

33existing file-backed Codex sign-in, or [configure another30existing file-backed Codex sign-in, or [configure another

34provider](#configure-the-runtime-and-credentials). Amazon Bedrock uses AWS31provider](#configure-the-runtime-and-credentials). Amazon Bedrock uses AWS

35credentials; OpenRouter and Fireworks use provider-specific API keys and32credentials; OpenRouter and Fireworks use provider-specific API keys and

36configuration.33configuration.

37 34 

38For best results, use an account verified for [Trusted Access for Cyber](https://chatgpt.com/cyber). Signing in or providing an API key does not35Some cybersecurity requests and protected findings require [Trusted Access for Cyber](https://chatgpt.com/cyber) for your ChatGPT account or API organization.

39grant Trusted Access.

40 36 

41## Run a scan37## Run a scan

42 38 


82Open the report to review the evidence.78Open the report to review the evidence.

83 79 

84`run` validates the saved artifacts and returns a `ScanResult` when80`run` validates the saved artifacts and returns a `ScanResult` when

85`result.manifest.scan.status` is `"completed"`. Check `result.coverage` for81`result.manifest.scan.status` is `"completed"`. Check `result.manifest.scan.scope`

86reviewed surfaces, exclusions, and deferred work. A completed scan can still82for the requested target and `result.manifest.scan.warnings` for any warnings.

87have coverage gaps. Runtime, input, or result-integrity failures can throw an83Completion alone doesn't tell you which files were reviewed. Runtime, input, or

88[error](#handle-scan-errors).84result-integrity failures can throw an [error](#handle-scan-errors).

89 85 

90In later examples, reuse the open `security` client and keep `close()` in86In later examples, reuse the open `security` client and keep `close()` in

91`finally` to release the runtime. Add any additional imports at the top of87`finally` to release the runtime. Add any additional imports at the top of


176const result = await security.run("/path/to/repository", { target });172const result = await security.run("/path/to/repository", { target });

177```173```

178 174 

179The head defaults to `HEAD`. Diff targets require the repository argument to175The head defaults to `HEAD`. Pass the Git worktree root as the repository and

180be the Git worktree root.176check out the requested head before scanning.

181 177 

182### Scan the working tree178### Scan the working tree

183 179 


204 subagents: 0,200 subagents: 0,

205 stopAfterNoNew: 3,201 stopAfterNoNew: 3,

206 maxDiscoveryRuns: 10,202 maxDiscoveryRuns: 10,

207 maxTimeHours: 1.5,203 maxTimeMinutes: 90,

208});204});

209```205```

210 206 

211Deep mode supports repository and path targets. Use standard mode for diff and207Deep mode supports repository and path targets. Use standard mode for diff and

212working-tree scans. The optional settings control concurrent independent208working-tree scans. In deep mode, `workers` limits concurrent scan workers and

213standard-scan workers, subagents per worker, consecutive completed worker scans209`subagents` sets the number of subagents per worker. `stopAfterNoNew` stops

214without new findings, and the total number and duration of worker runs. They210discovery after that many consecutive worker runs without new findings.

215require `mode: "deep"`.211`maxDiscoveryRuns` limits the total number of worker runs.

216 212 

217`maxTimeHours` defaults to `96` and accepts a positive number up to `96`,213Set `maxTimeMinutes` to limit deep discovery. The default and maximum are

218including fractional hours. At the deadline, Codex Security stops unfinished2145,760 minutes (96 hours). At the deadline, discovery stops and the SDK combines

219workers, keeps completed scan results, and aggregates them into the final215the results from completed workers. Standard scans treat `maxTimeMinutes` as an

220report. Review `result.coverage` for deferred work and open questions.216advisory allowance for investigation. Reporting can finish later. Custom

217validation and post-scan instructions run outside that allowance.

221 218 

222### Add a security knowledge base219### Add a security knowledge base

223 220 


259follow-up changed. The follow-up runs after scan cost tracking stops and256follow-up changed. The follow-up runs after scan cost tracking stops and

260is outside `maxCostUsd`.257is outside `maxCostUsd`.

261 258 

259### Validate findings in your environment

260 

261Pass `validationPrompt` to check candidate findings with your own test

262procedure. For example, point the prompt at a script you control outside the

263checkout and run it against your local test server:

264 

265```ts

266const result = await security.run("/path/to/repository", {

267 validationPrompt:

268 "Run /path/to/security-tests/validate.sh against http://localhost:3000 and report which findings reproduce.",

269});

270```

271 

272Use `validationPrompt` with standard repository, path, committed-diff, or

273working-tree scans. To use the same procedure for each standard component

274scan, pass `scanOptions.validationPrompt` to `runComponentScans`. Deep scans

275reject custom validation.

276 

262### Set a scan budget277### Set a scan budget

263 278 

264Set `maxCostUsd` to stop a scan when its estimated model cost exceeds a limit.279Set `maxCostUsd` to stop a scan when its estimated model cost exceeds a limit.


282If a deep scan reaches the limit after297If a deep scan reaches the limit after

283Codex Security aggregates completed worker results, `run` can return a result298Codex Security aggregates completed worker results, `run` can return a result

284with `manifest.scan.status` set to `"completed"` and report the budget warning299with `manifest.scan.status` set to `"completed"` and report the budget warning

285through `onWarning`. Check `result.coverage` for the work left unfinished.300through `onWarning`.

286 301 

287If the scan can't produce a valid completed result, `run` throws302If the scan can't produce a valid completed result, `run` throws

288`ScanCostLimitExceededError` and preserves any available output.303`ScanCostLimitExceededError` and preserves any available output.

289 304 

305## Scan project components

306 

307Use `runComponentScans` to scan services or packages in parallel and combine

308their findings. Give each component a name and one or more repository-relative

309paths. Choose a new or empty output directory outside the enclosing Git worktree.

310 

311```ts

312 

313 

314const result = await runComponentScans({

315 repository: "/path/to/project",

316 outputDir: "/path/outside/project/component-results",

317 components: [

318 { name: "API", paths: ["apps/api", "packages/auth"] },

319 { name: "Web", paths: ["apps/web"] },

320 ],

321 workers: 2,

322 onProgress: ({ name, status }) => console.log(name, status),

323});

324 

325console.log(result.reportPath);

326```

327 

328Set `workers` to control how many components run at once. The default is four.

329 

330To let Codex propose components, pass `auto: true` instead of `components`.

331Add `planOnly: true` to save the plan in `components.json` without running any

332scans:

333 

334```ts

335const plan = await runComponentScans({

336 repository: "/path/to/project",

337 outputDir: "/path/outside/project/component-plan",

338 auto: true,

339 planOnly: true,

340});

341 

342console.log(plan.planPath);

343```

344 

345If the run returns with failed components, read the JSON file at

346`result.retryPlanPath`. Pass its `components` array to `runComponentScans`

347with a new `outputDir`. The retry report covers only those components. Review

348the reports from both runs.

349 

290## Work with scan results350## Work with scan results

291 351 

292`ScanResult` exposes the structured documents, scan metadata, and artifact352`ScanResult` exposes the structured documents, scan metadata, and artifact


297| `manifest` | The sealed scan manifest, including target, scope, producer, and artifact records. |357| `manifest` | The sealed scan manifest, including target, scope, producer, and artifact records. |

298| `findings` | Findings from the current scan. Read finding objects from `findings.findings`. |358| `findings` | Findings from the current scan. Read finding objects from `findings.findings`. |

299| `repositoryFindings` | Open findings across repository scans, when scan history is available. |359| `repositoryFindings` | Open findings across repository scans, when scan history is available. |

300| `coverage` | Reviewed surfaces, exclusions, deferred work, and open questions. |360| `review` | Path patterns excluded from review (`review.excludedPaths`). |

301| `scanDir` | The scan directory. |361| `scanDir` | The scan directory. |

302| `threadId` | The Codex thread identifier for the scan. |362| `threadId` | The Codex thread identifier for the scan. |

303| `turnResult` | Turn status, response, and available usage metadata. |363| `turnResult` | Turn status, response, and available usage metadata. |


307| `threatModelPath` | The saved threat-model document path, or `null` when unavailable. |367| `threatModelPath` | The saved threat-model document path, or `null` when unavailable. |

308| `manifestPath` | The path to `scan-manifest.json`. |368| `manifestPath` | The path to `scan-manifest.json`. |

309| `findingsPath` | The path to `findings.json`. |369| `findingsPath` | The path to `findings.json`. |

310| `coveragePath` | The path to `coverage.json`. |

311| `artifactsDir` | The supporting-artifacts directory. |370| `artifactsDir` | The supporting-artifacts directory. |

312| `sarifPath` | The generated SARIF path, or `null` when SARIF is absent. |371| `sarifPath` | The generated SARIF path, or `null` when SARIF is absent. |

313| `pluginVersion` | The version recorded by the scan producer. |372| `pluginVersion` | The version recorded by the scan producer. |


316`expectedPluginVersion: result.pluginVersion`. The SDK rejects the scan if375`expectedPluginVersion: result.pluginVersion`. The SDK rejects the scan if

317the installed plugin version differs.376the installed plugin version differs.

318 377 

319Use the structured findings and coverage directly:378Read the severity and first source location for each finding:

320 379 

321```ts380```ts

322for (const finding of result.findings.findings) {381for (const finding of result.findings.findings) {


329 finding.title388 finding.title

330 );389 );

331}390}

332 

333for (const deferred of result.coverage.deferred) {

334 console.log(deferred.id, deferred.reason);

335}

336```391```

337 392 

338Findings can include optional `codeEvidence`, `rootCause`, `validation`,393Findings can include optional `codeEvidence`, `rootCause`, `validation`,


347}402}

348```403```

349 404 

350New results don't include `coverage.completeness`. Use `manifest.scan.status`405Use `result.toJSON()` to serialize the manifest, findings, recorded review exclusions,

351for execution status, and review deferred surfaces, exclusions, and open406artifact paths, and turn metadata.

352questions in `coverage` to understand what the scan reviewed.

353 

354`result.toJSON()` returns the manifest, repository and current-scan findings,

355coverage, scan and thread identifiers, `reportPath`, `threatModel`,

356`threatModelPath`, `artifactsDir`, `sarifPath`, cost, and turn metadata in one

357JSON-ready object.

358 407 

359### Read saved threat models408### Read saved threat models

360 409 


362still export a saved model if Codex Security couldn't write its Markdown file.411still export a saved model if Codex Security couldn't write its Markdown file.

363Use the path returned by the export instead of assuming a filename.412Use the path returned by the export instead of assuming a filename.

364 413 

365Starting in 0.2.0, saved models can contain Markdown (`format: "markdown"`

366and `content`) or the earlier structured format. Integrations that read

367`threatModel` must handle both. Existing models remain readable and exportable

368without migration. Policy generation now writes `threatmodel.md` instead of

369`THREAT_MODEL.md`; `SecurityPolicyDraft.threatModelPath` can also be `null`.

370 

371### Export saved artifacts414### Export saved artifacts

372 415 

373Export saved results without starting Codex, loading credentials, or making a416Export saved results without starting Codex, loading credentials, or making a


395`provenance` from the same saved results. Both fields are `null` when438`provenance` from the same saved results. Both fields are `null` when

396`output: "-"` writes to stdout. Export requires Python 3.10 or later.439`output: "-"` writes to stdout. Export requires Python 3.10 or later.

397 440 

441## Validate an existing finding

442 

443Use `validate` to check a finding from another tool or workflow against the

444source. It doesn't start a new scan, run the application, or execute its tests.

445Run a separate reproduction if you need runtime evidence.

446 

447```ts

448const validation = await security.validate({

449 repositoryPath: "/path/to/repository",

450 finding: {

451 title: "Possible SQL injection",

452 location: "src/query.ts:42",

453 },

454});

455 

456console.log(validation.disposition);

457console.log(validation.report);

458```

459 

460Pass the finding as nonempty text or a JSON object. If it's in a file, read

461the file and pass its contents.

462 

463The `disposition` tells you whether the finding is `reportable`, `suppressed`,

464`not_applicable`, or `deferred`. The Markdown in `validation.report` explains the evidence and remaining gaps.

465Save that string if you need a report file.

466 

398## Track or cancel a scan467## Track or cancel a scan

399 468 

400Pass `ScanOptions` callbacks to report scan startup, worker progress, and469Pass `ScanOptions` callbacks to report scan startup, worker progress, and


463| `onReconnect(attempt, maxAttempts)` | The SDK retries a disconnected scan stream. |532| `onReconnect(attempt, maxAttempts)` | The SDK retries a disconnected scan stream. |

464| `onActivity(activity)` | A command, tool, reasoning step, or message updates. |533| `onActivity(activity)` | A command, tool, reasoning step, or message updates. |

465| `onProgress(progress)` | The scan phase or reviewed file count changes. |534| `onProgress(progress)` | The scan phase or reviewed file count changes. |

466| `onWorkerStatus(status)` | Worker preflight or dispatch status changes. |535| `onWorkerStatus(status)` | Best-effort counts of workers planned and started. |

467| `onSessionEvent(session)` | A scan or worker session emits an event. |536| `onSessionEvent(session)` | A scan or worker session emits an event. |

468| `onCost(cost)` | An updated estimated scan cost is available. |537| `onCost(cost)` | An updated estimated scan cost is available. |

469| `onWarning(warning)` | The scan reports a warning. |538| `onWarning(warning)` | The scan reports a warning. |


479## Configure the runtime and credentials548## Configure the runtime and credentials

480 549 

481Pass runtime configuration when you need a specific plugin, interpreter, or550Pass runtime configuration when you need a specific plugin, interpreter, or

482Codex setting. Choose a model your credentials can access. If you use ChatGPT551Codex setting. Choose a [model](https://learn.chatgpt.com/docs/models) available to your account:

483sign-in, check [GPT-6.1 Sol availability](https://learn.chatgpt.com/docs/models#gpt-6.1-sol) before

484using this example:

485 552 

486```typescript553```typescript

487const security = new CodexSecurity({554const security = new CodexSecurity({


497 564 

498`pluginPath` accepts a plugin directory or ZIP. `pythonPath` selects the565`pluginPath` accepts a plugin directory or ZIP. `pythonPath` selects the

499plugin interpreter. `codexOverrides` merges supported values into the isolated566plugin interpreter. `codexOverrides` merges supported values into the isolated

500Codex configuration. Scans use `gpt-5.6-sol` with extra-high reasoning effort567Codex configuration. To use [Amazon

501by default. Set `model` and `model_reasoning_effort` in `codexOverrides` to use

502a different model or reasoning effort. To use [Amazon

503Bedrock](https://learn.chatgpt.com/docs/security/cli/reference#use-amazon-bedrock), set568Bedrock](https://learn.chatgpt.com/docs/security/cli/reference#use-amazon-bedrock), set

504`model_provider` and `model` in `codexOverrides`.569`model_provider` and `model` in `codexOverrides`.

505 570 


509access and inherited credentials.574access and inherited credentials.

510 575 

511For OpenRouter or Fireworks, also provide the matching API key and a complete576For OpenRouter or Fireworks, also provide the matching API key and a complete

512provider configuration in `codexOverrides`. For example, set577provider configuration in `codexOverrides`. Set `OPENROUTER_API_KEY`

513`OPENROUTER_API_KEY` and configure OpenRouter:578and pass an available OpenRouter model ID to this TypeScript function:

514 579 

515```ts580```ts

516const security = new CodexSecurity({581function createOpenRouterClient(model: string) {

582 return new CodexSecurity({

517 codexOverrides: {583 codexOverrides: {

518 model: "anthropic/claude-sonnet-4.5",584 model,

519 model_provider: "openrouter",585 model_provider: "openrouter",

520 model_providers: {586 model_providers: {

521 openrouter: {587 openrouter: {


526 },592 },

527 },593 },

528 },594 },

529});595 });

596}

530```597```

531 598 

532For Fireworks, change both `openrouter` keys to `fireworks`, set `name` to599For Fireworks, change both `openrouter` keys to `fireworks`, set `name` to

whats-new.md +2 −2

Details

198 198 

199### MCP Events199### MCP Events

200 200 

201Let users ask ChatGPT to act on updates from your MCP server. Requires MCP 2.0 and webhook delivery.201Let users ask ChatGPT to act on updates from your MCP server. ChatGPT supports webhook delivery.

202 202 

203[Build event subscriptions](https://developers.openai.com/plugins/build/mcp-events)203[Build event subscriptions](https://developers.openai.com/plugins/build/mcp-events)

204 204 


383 383 

384### Respond to MCP events384### Respond to MCP events

385 385 

386Build [webhook subscriptions](https://developers.openai.com/plugins/build/mcp-events) so users can ask ChatGPT to act on updates from your MCP server. Requires MCP 2.0.386Build [webhook subscriptions](https://developers.openai.com/plugins/build/mcp-events) so users can ask ChatGPT to act on updates from your MCP server.

387 387 

388 388 

389 389 

Details

152 152 

153### MCP Events153### MCP Events

154 154 

155Let users ask ChatGPT to monitor updates from your MCP server and act when matching events arrive. ChatGPT requires MCP 2.0 and supports webhook delivery from the draft MCP Events specification.155Let users ask ChatGPT to monitor updates from your MCP server and act when matching events arrive. ChatGPT supports webhook delivery from the draft MCP Events specification.

156 156 

157[Build event subscriptions](https://developers.openai.com/plugins/build/mcp-events)157[Build event subscriptions](https://developers.openai.com/plugins/build/mcp-events)

158 158 

Details

108updates from your server and act when matching events arrive. For example,108updates from your server and act when matching events arrive. For example,

109a user can ask ChatGPT to summarize new messages or respond to document feedback.109a user can ask ChatGPT to summarize new messages or respond to document feedback.

110 110 

111This integration requires MCP 2.0. ChatGPT supports webhook delivery from111ChatGPT supports webhook delivery from

112the draft MCP Events specification; polling and streaming aren't supported.112the draft MCP Events specification; polling and streaming aren't supported.

113 113 

114## Customize website annotations114## Customize website annotations