Codex macOS build missing NSLocalNetworkUsageDescription causing remote control enrollment failure
Environment
- macOS: [26.5.1]
- Codex Desktop: latest (upgraded recently)
- iPhone ChatGPT app: latest
- Account: MFA enabled
- Passkey enabled
Problem
Trying to connect iPhone ChatGPT to Mac Codex for remote control.
iPhone shows:
"Couldn't enable remote control. Try again"
What I observed
- Authentication works normally
- MFA is enabled
- Re-login does not fix it
- Removing Codex cache does not fix it
- Removing Keychain entries does not fix it
- Reinstalling/restarting does not fix it
Important:
Codex does NOT appear under:
System Settings -> Privacy & Security -> Local Network
Only ChatGPTHelper appears.
Bundle ID:
com.openai.codex
Config
~/.codex/config.toml:
[features]
js_repl = false
remote_connections = true
This key persists after restart.
Expected
Codex should request Local Network permission and complete remote enrollment.
Actual
Remote control enable fails immediately.
No Local Network permission prompt.
No remote enrollment token created in Keychain.
Additional notes
Looks like embedded remote host/app-server never initializes or never reaches local network entitlement trigger.
Critical finding:
Running:
plutil -p /Applications/Codex.app/Contents/Info.plist | grep NSLocalNetworkUsageDescription
returns nothing.
This suggests the app bundle does not declare Local Network usage.
As a result:
- Codex never appears in macOS Local Network permissions
- no permission prompt is shown
- iPhone remote control fails with "Couldn't enable remote control"
➜ ~ sw_vers
ProductName: macOS
ProductVersion: 26.5.1
BuildVersion: 25F80
➜ ~ defaults read /Applications/Codex.app/Contents/Info CFBundleShortVersionString
26.609.30741
➜ ~ plutil -p /Applications/Codex.app/Contents/Info.plist | grep -i network
➜ ~
7 Comments
error is shown on Mac Codex Desktop, not on iPhone
also have same problem
Additional reproduction — Mac-to-Mac, version 26.609.71450, macOS 26.6 beta2
Environment
Host: Mac Studio (Apple Silicon), macOS 26.6 beta2
Controller: MacBook Air (Apple Silicon), macOS 26.6 beta2
Both machines: Codex Desktop 26.609.71450 (updated Jun 16, then again Jun 17, 2026)
ChatGPT subscription: Pro
Account: MFA enabled
Symptom
Mac-to-Mac remote control is permanently stuck at "Connecting". The handshake never completes. Re-pairing multiple times does not help — the connection attempt fails before the handshake on most attempts. iPhone (iOS 26.6 beta2, latest ChatGPT app, same account) connects to the Mac Studio host normally via cloud relay, confirming the host enrollment itself is not the issue.
Confirmed reproduction of the missing key — on both machines
plutil -p /Applications/Codex.app/Contents/Info.plist | grep -i NSLocalNetworkUsageDescription
Returns empty on both Mac Studio (host) and MacBook Air (controller). Neither machine shows Codex under System Settings → Privacy & Security → Local Network. No Local Network permission prompt has ever appeared.
Update history
Jun 16 update (26.609.71450): key absent
Jun 17 update (same version string pushed again): key still absent
The Jun 17 update did not fix this. The missing NSLocalNetworkUsageDescription entry persists across both updates. Mac-to-Mac remote control remains completely non-functional.
I found the root cause.
This is not a Codex account or iPhone issue.
In my case, Codex Remote Control does not properly inherit the system proxy settings. It tries to connect directly to OpenAI relay (likely via HTTP2/WebSocket), which fails on my network unless traffic is transparently proxied (TUN mode).
That explains why:
The fix is to explicitly set proxy environment variables for Codex.
Create this file:
macOS:
~/.codex/.env
Windows:
C:\Users<username>.codex.env
Add:
HTTP_PROXY=http://127.0.0.1/:<your_http_proxy_port>
HTTPS_PROXY=http://127.0.0.1/:<your_http_proxy_port>
ALL_PROXY=http://127.0.0.1/:<your_http_proxy_port>
WS_PROXY=http://127.0.0.1/:<your_http_proxy_port>
WSS_PROXY=http://127.0.0.1/:<your_http_proxy_port>
NO_PROXY=localhost,127.0.0.1,::1
Then fully restart Codex.
After that, Remote Control works without enabling TUN.
This confirms Codex supports proxy env vars, but may not correctly use system proxy settings by default.
Still stuck on 'Connecting' after testing your env config (no errors thrown). For Mac-to-Mac remote control: proxy is ruled out as the root cause. The issue appears to be a missing NSLocalNetworkUsageDescriptionin Info.plist.
Same class of bug — we investigated this in our project (Hermes desktop) and found the mechanism; please verify in your environment
We hit the identical symptom (Electron app, macOS 27, LAN access silently denied, no Local Network permission prompt ever) and spent two nights isolating it. Everything below was verified on our setup (macOS 27.0 26A5406e, Hermes desktop, standard electron-builder packaging). Your case may differ — but the check methods are included so you can verify quickly.
1. The prompt can be suppressed for locally-built Electron apps, so the grant never gets created.
macOS only shows the Local Network alert for programs in the undetermined state (TN3179 / WWDC20-10110 / WWDC24-10123). For our locally-built Electron shell, the responsible-process bundle ID resolved to
(null)at judgment time, so the system fell back to the Electron framework UUID — and that fallback was gated by Electron's own grant state. Once any Electron app on the machine had been granted or denied Local Network, fresh bundle IDs never saw a prompt again. No prompt → no grant → permanentNo route to host/EHOSTUNREACH.2. The grant store is per bundle ID (and per interpreter path).
Grants live in
/Library/Preferences/com.apple.networkextension.plist→PathController.Rules(NSKeyedArchiver), keyed bySigningIdentifier(bundle ID) orPath. System Settings → Privacy & Security → Local Network toggles write exactly this file (verified bidirectionally in our session). Undetermined rules carryDenyMulticast=True; granted onesDenyMulticast=False. You can read this file directly to see whether your app has a rule at all.3. The usage-description key was not the fix in our case.
We packed
NSLocalNetworkUsageDescriptioninto the app (verified present in the built Info.plist) — a fresh bundle ID still never prompted and never connected. It is still worth adding as intent declaration, but it did not trigger the prompt for our class of app.4. A workaround that worked for us (single-variable experiment).
Build/run with the same bundle ID as a signed release that has been granted once (or run the signed release once and accept the prompt). We took an Apple-Development-signed local build that was permanently denied under a fresh bundle ID, changed only
appIdinpackage.jsonto the granted ID, rebuilt — and it connected immediately. The grant survived arbitrary rebuilds (adhoc re-signing, repacks).5. Quick check on an affected machine.
Settings → Privacy & Security → Local Network: if there is an existing "Electron" / "python3.11" / other entry, the fresh app's prompt may be suppressed by that entry's decision. Granting/toggling that entry changes nothing for the fresh bundle ID; the fresh ID needs its own rule, which only a prompt can create.
Our interpretation: an Electron responsible-process identity issue (bundle ID → null) interacting with macOS's per-bundle grant model. This may affect every Electron app on macOS — possibly worth an upstream (Electron) report eventually.
Full write-up with the complete test matrix, logs, grant-store dumps, and methodology: https://github.com/NousResearch/hermes-agent/issues/81563#issuecomment-5309147670
I can provide a reproducible case showing that the ChatGPT desktop Remote Control WebSocket ignores proxy environment variables, even when those variables are present in the desktop process.
Environment
0.148.0-alpha.15Proxy configuration tested
The following variables were configured in
~/.codex/.env:I also launched the desktop executable directly after exporting the file:
Inspection of the running ChatGPT process confirmed that these variables were actually present:
Therefore, this does not appear to be a
.envloading or GUI-process inheritance problem.Reproduction
Actual behavior
The normal HTTPS enrollment requests succeed, including token refresh:
The subsequent Remote Control WebSocket fails before opening:
This repeats on every reconnect attempt.
Independent tests from the same machine show:
successfully establishes the proxy CONNECT/TLS connection and receives an HTTP response (
404, as expected for/).In contrast:
fails immediately with connection refused, matching the desktop application’s error.
This strongly indicates that the Remote Control WebSocket is attempting a direct
node:netconnection instead of tunneling through the configured proxy.Expected behavior
The
wss://ws.chatgpt.comconnection should honorHTTPS_PROXY/https_proxyandNO_PROXY/no_proxy, using HTTP CONNECT for the TLS WebSocket connection. Authenticated HTTP proxies should ideally be supported as well.Possible implementation boundary
The failing stack originates in the ChatGPT desktop Electron process (
app.asar), rather than the spawned Codexapp-server. This suggests that applying proxy configuration only toapp-serverwould not fix controller-side Remote Control connections; the proxy agent likely needs to be applied where the desktop process constructs the Remote Control WebSocket.I am separately working with IT on allowing a direct connection as a temporary workaround, but that does not resolve the underlying proxy-support issue.
I can provide a sanitized desktop log or feedback session ID if useful.