Skip to content

Desktop app: permission prompts auto-declined and saved as user choices (browser site block); Messages approvals silently declined in Full access #45237

Description

@mavenHQHub

Codex app bug report (draft for OpenAI)

Summary: In the Codex desktop app, permission prompts can be answered "declined" by the app itself, and the result is then treated as the user's choice. Two cases: (1) a website prompt in the built-in browser was auto-declined and saved permanently for that conversation, with no way to see or undo it in Settings; (2) in Full access mode, Messages read and send approvals are auto-declined with no card shown, and the plug-in instructs the model not to tell the user how to fix it.

Environment

Item Value
macOS 26.5 (build 25F71), Mac Studio
ChatGPT app with Codex 26.903.61454 (bundled codex-cli 0.153.4)
Browser plug-in (openai-bundled) 26.903.61454
Codex Computer Use helper (runs the Messages plug-in) 26.902.1000968 (updated 2026-09-09)
Global Codex settings approval_policy never, sandbox danger-full-access

Bug 1: a website prompt auto-declined and saved as a permanent conversation block

Steps observed (2026-09-08, two separate conversations, both started from the ChatGPT iOS app's Codex remote, both in "Approve for me" mode with helper threads running):

  1. Conversation A asked Codex to search ChatGPT history; Codex called cua.createBrowserTab('iab','https://chatgpt.com').
  2. 0.55 s later the tool returned: "Browser Use rejected this action due to browser security policy. Reason: The user declined permission for this action." (reason code user_declined, decision source user_decision). No prompt was visible to the user, who was typing in another app on the Mac at that moment; nobody answered a prompt in half a second.
  3. At the same second the file ~/.codex/browser/sessions/<conversation>.toml was written with [origins] denied = ["https://chatgpt.com"].
  4. Every later attempt in that conversation, in the built-in browser and in Chrome, returned "A saved user permission setting blocks this action ... the user has a saved preference that blocks it" (persisted_user_denied).
  5. Adding chatgpt.com under Settings → Browser use → Site permissions (global allow) did not help: the conversation-level record is checked first. Settings shows the site as allowed while the tool reports it blocked.
  6. Same sequence in conversation B for www.cvs.com (0.61 s), and an older conversation from 2026-08-27 for mail.google.com.

Likely mechanism (from the app bundle): the desktop app's turn-interrupt routine replies "decline" to every pending request in the conversation (command approvals, file-change approvals, permissions, user input, option pickers, and mcpServer/elicitation/request). The browser service then persists a declined origin prompt as a conversation-scoped user decision. In Full access mode the same origin prompts are auto-accepted (the app's elicitation handler auto-accepts access_browser_origin when approval policy is never and the sandbox is full access), so the failure only appears in Ask / Approve-for-me conversations.

Expected: a decline produced by an interrupt should resolve that one request only, never be persisted as a user preference; the error text should not say "the user declined". Conversation-level site decisions should be visible and removable in Settings, and a global "Always allow" should override, or at least surface, a conversation-level block.

Workaround found: empty the denied list in the conversation's browser file (takes effect without restart), or start a new conversation.

Bug 2: Messages read/send approvals silently declined in Full access; model told not to explain

Steps observed (2026-09-11, two conversations in Full access):

  1. User asks Codex to find a text in a specific Messages chat.
  2. Codex calls mcp__messages__search_messages. 0.6 s later the plug-in returns permission_filtered: true with: "Read access was not approved. No content was returned. Do not ask the user to approve access or retry. Do not fall back to Computer Use or other tools..."
  3. No approval card appears. The app-server log shows the call tagged approval_policy=Never and no elicitation. Codex tells the user the results were withheld and stops.
  4. Before the 2026-09-09 helper update, reads needed no approval and worked in Full access (2026-08-29) and other modes (08-21, 08-31, 09-10).
  5. The new Settings → Computer use → Messages → "Read access" list (Always allow / Always ask / Never allow) exists, but nothing in the conversation points the user to it. Send permissions ("Always allowed to send") have no Add control at all; a number can only be added by answering a live send card with "Always allow", which cannot appear in Full access.
  6. Follow-up test on 2026-09-13: with the conversation switched to "Approve for me", a send to a chat that is NOT on the "Always allowed to send" list went through with no card shown to the user at all, so the reviewer agent approved an outbound text on its own; the number was not added to the list.
  7. The Read access entry is stored under the contact's iMessage address (any;-;<email>), while the model searched by phone number; it is unclear whether an allow on one handle covers the other spelling of the same chat.

Mechanism: the Codex core rejects plug-in approvals under approval policy never ("MCP tool call requires approval, but approval policy is never"). The helper's own send text acknowledges this ("If the task's current approval_policy is confirmed to be never ... suggest switching the task to Ask for approval or Approve for me"), but the read text forbids any explanation.

Expected: in Full access, either show the read/send card anyway (as the app already does for website access), or return a message that names the fix (Settings → Computer use → Messages → Read access), and allow adding send permissions from Settings.

Related observation

"Browser is not available: iab" from the built-in browser on 09-08 (2), 09-09 (11), 09-10 (9), always early in the day, cleared by quitting and reopening the app. Both auto-declines in Bug 1 happened while the browser service process was starting (fresh initialize on its app-server connection at the same second).

Impact

Two work conversations lost browser access to key sites for three days; Messages lookups fail silently in the default Full access mode; the user was told the wrong party (himself) had declined.

Personal identifiers (names, numbers, addresses) removed from this draft. Local evidence: rollout files under ~/.codex/sessions, the app log store ~/.codex/logs_2.sqlite, and the helper store under ~/Library/Group Containers/2DC432GLL2.com.openai.sky.CUAService.

Activity

  1. added
    bugSomething isn't working
    appIssues related to the Codex desktop app
    sandboxIssues related to permissions or sandboxing
    mcpIssues related to the use of model context protocol (MCP) servers
    on Sep 13, 2026
  2. github-actions commented on Sep 13, 2026

    @github-actions
    Contributor

    Potential duplicates detected. Please review them and close your issue if it is a duplicate.

    Powered by Codex Action

  3. WQMYH commented on Sep 28, 2026

    @WQMYH

    Windows evidence: conversation-scoped denial still overrides a later global Allow

    This report adds Windows evidence for Bug 1 in this issue, from a later desktop/browser-plugin version. We independently traced the ongoing denial to the persisted conversation setting. We have not established who or what produced the initial decline in our case, so this is not independent confirmation of the auto-decline mechanism.

    Environment

    • Windows desktop, x64.
    • Installed Windows package: OpenAI.Codex 26.924.2738.0 (ChatGPT.exe).
    • Bundled Browser / Unified Computer Use plugin: 26.924.22138.
    • Affected origin: http://127.0.0.1:8766 (a local development service).
    • Incident date: 2026-09-28. Times below are UTC.

    Observed sequence

    1. At 05:03:15, the desktop log recorded dom-ready for the localhost page in the affected task.
    2. At 05:11:55, that task called:
      await cua.createBrowserTab('iab', 'http://127.0.0.1:8766/', {visible: false});
    3. At 05:11:58, the tool returned The user declined permission for this action. The conversation permission file's modification time matches this event.
    4. The user subsequently allowed the exact HTTP origin in normal Settings. By 09:16:31, both global permission stores reflected that allowance.
    5. A normal retry in the same task at approximately 09:20 still failed with A saved user permission setting blocks this action.

    This sequence is reconstructed from existing tool receipts, desktop logs, and configuration/code inspection. No additional page access was attempted during the diagnosis.

    Effective conflicting configuration

    $CODEX_HOME/browser/sessions/<thread-id>.toml still contained:

    [origins]
    denied = ["http://127.0.0.1:8766"]

    Meanwhile, $CODEX_HOME/browser/config.toml contained:

    [origins]
    allowed = ["https://127.0.0.1:8766", "http://127.0.0.1:8766"]
    denied = []

    And $CODEX_HOME/config.toml contained:

    [browser_use.origins."http://127.0.0.1:8766"]
    access = "allow"
    downloads = "allow"
    uploads = "allow"

    We verified that the default user .codex location and CODEX_HOME resolve to the same directory through a junction; this was not a second-profile mix-up. An earlier HTTP/HTTPS mismatch had also already been corrected.

    Installed evaluator evidence

    Read-only inspection of the shipped browser/26.924.22138/scripts/browser-service.mjs shows:

    • maybeAutoAnswerBrowserUseRequest (minified line 4379) reads this.config.session(e.preferenceSessionId) and, when that session's denied list matches the origin, returns a conversation-scoped denial before the global approval branch. The returned source is browser-use-persisted-state.
    • Ht (line 1075) maps that source to persisted_user_denied.
    • The error mapping (line 1007) renders it as A saved user permission setting blocks this action.

    This directly explains the continuing block. The request was stopped by Browser Use before the target application's authentication or business logic; changing the application's permissions would not address it.

    Expected recovery and diagnostics

    • Surface the effective conversation-scoped decision and its conflict with the global Allow in the permission UI.
    • Provide a supported, user-controlled way to inspect and revoke that specific conversation denial.
    • When setting a global Allow, explain any conversation denials that remain effective and offer an explicit scoped choice. Deny precedence may be intentional; this report does not request silently weakening other denials or managed policy.
    • Include the effective scope/source in the error, rather than leaving users to repeatedly change the global website list.
    • Preserve the actual reviewer/decision provenance. In our case the first tool receipt says user_declined, but we did not obtain the original approval actor metadata and cannot attribute it to a human click, interruption, or automatic reviewer.

    The Settings pages inspected by the user did not expose this conversation record or a way to revoke it. This blocked an explicitly authorized localhost UI test and caused troubleshooting at the wrong permission layer.

    Only sanitized configuration excerpts and diagnostic findings are included here; no credentials, private task IDs, application data, or full logs are attached. The permission files were not altered during this diagnosis.

  4. luoafei88-ux commented on Oct 3, 2026

    @luoafei88-ux

    Additional Windows reproduction on 2026-10-03: clearing browser data and restarting the app did not remove the conversation-scoped block.

    Environment: Windows; Codex desktop app 26.930.31730, build 12947 (last checked by the app updater). Affected origin: http://127.0.0.1:8016.

    Read-only inspection found:

    Global file, $CODEX_HOME/browser/config.toml:

    [origins]
    allowed = ["http://127.0.0.1:8016"]
    denied = []

    Conversation file, $CODEX_HOME/browser/sessions/<conversation-id>.toml:

    [origins]
    denied = ["http://127.0.0.1:8016"]

    The user reports no corresponding blocked-site entry in Settings. After the user cleared browsing data/cookies and restarted the app, a normal retry to the same origin still returned: "A saved user permission setting blocks this action." Both configuration states above remained unchanged. The permission files were not edited during diagnosis.

    The origin had been used for an earlier acceptance-testing batch. We have not established who or what created the initial denial; this is evidence of the persisted conflict and failed UI recovery, not proof of the auto-decline mechanism. We also have no evidence that a subscription tier caused it.

    Please provide a supported way to inspect and reset this specific conversation-level decision in the app, expose the effective permission scope/source in the error, and identify whether an official fix is available for this Windows build. The user has moved publication ahead while explicitly leaving browser interaction acceptance pending.

    No credentials, private project URLs, conversation identifiers, or full logs are included.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    appIssues related to the Codex desktop appbrowserbugSomething isn't workingcomputer-usemcpIssues related to the use of model context protocol (MCP) serverssandboxIssues related to permissions or sandboxing

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions