openai / openai/codex

[Windows App 26.908.9136.0] Guarded local API restart blocked before execution; possible cross-command URL-launch match

Open
#46,364 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

app bug sandbox tool-calls windows-os
Dominant language
Rust
Stars
125k
Forks
19.4k
PR merge metrics
PR metrics pending

Description

Summary

Codex Desktop on Windows rejects an explicitly authorized restart of a local, loopback-only development API before PowerShell executes. The tool returns only:

exec_command failed: CreateProcess {
  message: "Rejected(... rejected: blocked by policy)"
}

The affected command first queries local application state over HTTP, verifies that no work is running and that the target PID belongs to the expected service, then stops and restarts that service with a separately installed newer model executor. The user explicitly approved this exact restart after the first rejection; the retry was rejected in the same way.

There is a specific source-level hypothesis: the Windows URL-launch heuristic scans flattened PowerShell tokens for a URL and a launch command anywhere in the script. Our HTTP preflight and later Start-Process can satisfy those conditions even though the launched executable receives no URL. The generic rejection hides whether this was actually the matched rule.

This report adds an observation on Windows App package 26.908.9136.0 and links it to existing reports. It is not a claim of a newly introduced regression, a clean-machine reproduction, or a confirmed identification of the exact classifier bundled in this App version.

Codex App version

  • Installed Windows package: OpenAI.Codex 26.908.9136.0.
  • Verified using Get-AppxPackage -Name OpenAI.Codex; the About dialog was not inspected.
  • The App's bundled execution-component version has not been independently identified. The standalone CLI versions below must not be treated as the App's bundled version.

Subscription

Not included in this public report. No account identifiers, credentials, usage headers, or private logs are attached.

Platform and runtime

Component Observed value
OS Windows 11 Home, Chinese-language edition, 64-bit
Windows version/build 10.0.26200, build 26200
PowerShell 7.6.6 (pwsh.exe)
Node.js v24.14.1
Existing standalone Codex CLI 0.144.1
Separately installed replacement CLI 0.155.0
Current task's effective sandbox setting DangerFullAccess / danger-full-access
Current task's approval policy Never / never
Local service Node.js API bound to 127.0.0.1:4310
Observation date September 18, 2026, Asia/Shanghai (UTC+08:00)

The permission values above are task-level values observed in the active task configuration/logs, not an assumption based only on a user configuration file. I am not assuming that full filesystem access disables other command-safety controls, or that natural-language approval automatically changes an execution policy.

What the user was trying to do

The user asked Codex to run an existing design application's native processing pipeline against already uploaded product-design documents. The application has its own conversation, work, execution, validation, and result storage flow. The integration only forwards requests to that application; it does not replace the application's processing with a separate implementation.

An earlier application request had failed with a separate, explicit model-provider error:

The 'gpt-6-astra' model requires a newer version of Codex.
Please upgrade to the latest app or CLI and try again.

The application had been using standalone CLI 0.144.1. Codex installed @openai/codex@0.155.0 in a dedicated local runtime directory and successfully ran that executable's --version. It did not replace the user's global CLI installation. The service startup adapter had been prepared to select that executable while retaining the application's original processing and model selection.

Switching the executor required restarting the local API. This is the operation blocked by the tool. The CLI/model compatibility error and the command-policy rejection are separate failures. Successful installation and --version do not establish that a full model request with 0.155.0 would succeed; that remains untested because the service has not switched executors.

Observed sequence

  1. Confirm the existing API is healthy on loopback.
  2. Read the current product state using the application's original API. It has uploaded evidence, no running work, and no candidate results.
  3. Identify the process listening on port 4310 and verify its command line belongs to this task's Node API launcher.
  4. Install the replacement CLI in a dedicated directory and verify codex-cli 0.155.0.
  5. Submit a PowerShell command that repeats the state/identity checks, stops that exact API process, sets process-local executor/runtime paths, and launches the same API with a hidden window and fresh stdout/stderr log files.
  6. Receive CreateProcess ... rejected: blocked by policy before PowerShell starts. The tool reports 0.0 seconds, no shell exit code, and no script output.
  7. Explain the rejected operation to the user and ask specifically about restarting this local API to select the newer executor.
  8. The user explicitly authorizes that restart. Retry the same intended operation, retaining the guards. Receive the same pre-execution rejection.
  9. Perform read-only diagnostics. The original API process still owns port 4310; its health endpoint works; the new log files have not been created; no design work/result has been started.

No further restart attempt was made during the diagnostic pass. No alternative shell, launcher, scheduled task, encoded command, or changed safety setting was used to bypass the rejection.

Sanitized command shape

The following preserves the relevant structure of the rejected command. Usernames, real project paths, the product identifier, executable directory details, and the actual PID are replaced with placeholders. This is a sanitized incident example, not a clean reproduction that has been executed with these placeholder values. It includes a process-stop operation and should not be pasted without adapting and reviewing it.

$trialCodex = 'C:/work/design-runtime/codex-0.155.0/bin/codex.exe'

$trialView = Invoke-RestMethod `
  'http://127.0.0.1:4310/api/autodesign/products/PRODUCT_ID/current-product'
if ($trialView.openWorkIds.Count -ne 0) {
  throw 'Active work exists; refusing restart.'
}

$trialApi = Get-CimInstance Win32_Process -Filter 'ProcessId = 12345'
if ($trialApi.CommandLine -notlike '*boot_design_api.mjs*') {
  throw 'API process identity changed.'
}

Stop-Process -Id 12345

$env:AUTO_DESIGN_CODEX_BIN = $trialCodex
$env:AUTO_DESIGN_BLENDER_BIN = 'C:/work/design-runtime/blender/blender.exe'
$env:AUTO_DESIGN_LOCAL_DATA_DIR = 'C:/work/design-data'

$trialArgs = @(
  '--conditions=development',
  '--import', 'tsx',
  'C:/work/design-integration/boot_design_api.mjs'
)

$trialNewApi = Start-Process `
  -FilePath 'C:/Program Files/nodejs/node.exe' `
  -ArgumentList $trialArgs `
  -WorkingDirectory 'C:/work/design-checkout' `
  -WindowStyle Hidden `
  -RedirectStandardOutput 'C:/work/design-runtime/api-v155.stdout.log' `
  -RedirectStandardError 'C:/work/design-runtime/api-v155.stderr.log' `
  -PassThru

$trialNewApi.Id | Set-Content 'C:/work/design-runtime/api.pid'
$trialNewApi.Id

The HTTP URL belongs to the preflight Invoke-RestMethod call. It is not passed to Start-Process, Node.js, a browser, ShellExecute, or any GUI URL handler. There is no recursive deletion, process-name-wide termination, proxy change, firewall change, privilege elevation, or public network listener in this command.

Actual result

  • The execution tool rejects the compound invocation before the shell starts.
  • The original API process remains running. The rejection did not leave the service half-restarted.
  • The API returns HTTP 200 for health and state reads.
  • State reads show uploaded evidence but no active Work or generated candidate Result.
  • The newly specified log paths do not exist, consistent with Start-Process not executing.
  • The failure identifies no matching rule, rule source, command span, reason category, or supported review mechanism.
  • Explicit user confirmation in the conversation did not change this outcome.

Diagnostic work already performed

  • Checked the actual listening PID with Get-NetTCPConnection and its executable/command line with Get-CimInstance.
  • Rechecked the original API's health and application state after the denial.
  • Verified both standalone CLI versions directly.
  • Inspected the relevant local core-log database, current-day Desktop logs, and sandbox logs. No diagnostic was found that attributes this rejected invocation to a particular rule.
  • Inspected the user configuration and user rules-directory availability. No explanatory user rule was found. This does not exclude built-in classifiers, managed configuration, or other enforcement layers.
  • Found empty exec-policy loading records for an application-created CLI child session, but did not treat those as evidence that the parent Desktop task has no other policy.
  • Found a historical sandbox setup-error record, but no evidence connecting it to this rejection; it is not presented as the cause.
  • Confirmed ordinary reads and HTTP status queries continue to work. Therefore this is not an observation that all shell commands fail.

Private conversation history, product documents, authentication data, raw HTTP headers, and unredacted logs are deliberately omitted.

Source-level lead: URL and launch detection may span separate commands

While preparing this report, I found the analysis in https://github.com/openai/codex/issues/41779#issuecomment-5720480823 and inspected the corresponding upstream source.

At upstream commit 7498521d288b9b3b96ffba4eedf089d8d6e06a84:

  1. windows_dangerous_commands.rs, lines 21–55 describes a flattened token scan. is_dangerous_powershell_words calculates has_url across the words and returns true if any token matches or contains start-process (or related launch tokens).
  2. is_dangerous_command.rs, lines 83–93 maps a PowerShell-specific dangerous-command match to DangerousCommandMatch::Other.
  3. exec_policy.rs, lines 1110–1118 renders DangerousCommandMatch::Other as blocked by policy.

This is consistent with the shape of the incident: a URL used only by a local health/state preflight, followed later by a process launch with filesystem-path arguments. It also explains why the message could discard the useful category even when a specific classifier matched.

Limitations: this source inspection was against the pinned upstream commit, not a confirmed source revision of the installed App's execution component. I have not run a classifier unit test against the exact rejected command or established a deterministic fresh-project reproduction. The lead should therefore be confirmed by maintainers, not treated as a proven root cause for this App build. No command was rewritten or split to test a bypass.

Expected behavior / requested maintainer help

  1. Identify which enforcing component and rule rejected this invocation in the affected App version.
  2. If the URL-launch heuristic is responsible, confirm whether matching a preflight HTTP URL against a separate later process launch is intentional. Please distinguish the URL's actual consumer from unrelated commands in the same script when evaluating this case.
  3. Preserve a useful reason category in the error, rather than collapsing all Windows matches to blocked by policy. Include the policy source and, where feasible, the relevant command span.
  4. Explain the supported, narrowly scoped review/recovery path when a user explicitly authorizes the operation but the tool still refuses it. If no in-app approval is possible for this class of rule, please say that directly in the error.
  5. If behavior is changed, add parser/classifier tests for both genuine URL-bearing launch commands and scripts where a URL is consumed only by an independent preflight request. This is a request for evaluated behavior and diagnostics, not for a blanket allow rule or disabled safeguards.

Impact

The user's requested design run cannot proceed through the native application until its executor can be switched. Repeated conversational permission requests waste time because they do not expose or resolve the enforcing rule. Replacing the original application pipeline with an unrelated local output would not satisfy the user's request and has not been used as a workaround.

Related reports

  • #41779 — local API launch rejected before execution; includes the source-level diagnostic analysis linked above.
  • #44430 — explicit user authorization followed by the same opaque rejection, for a different operation (a tunnel launch).

These are related symptoms, not proof of a shared root cause. Please link or close this as a duplicate if it belongs to an existing tracking issue; the additional App version, guarded restart command shape, and source-level lead are included to aid triage.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with codex-rs/shell-command/src/command_safety/windows_dangerous_commands.rs at commit 7498521d, then trace is_dangerous_command.rs and codex-rs/core/src/exec_policy.rs. Compare the reported compound PowerShell shape with the existing URL and launch detection, and determine whether the exact App component can be matched. Done means the responsible rule and useful error category are confirmed, or the lead is disproved.

Written by the indexing model from the issue text.

Assessment

Tech stack
powershell, rust
Domain
cli, devtools, operating-systems, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.