Desktop project task creation forces :read-only and ignores trusted project permission profile
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.4k
- PR merge metrics
- PR metrics pending
Description
What version of the Codex App are you using?
Codex Desktop 26.820.60940; bundled codex-cli 0.150.0-alpha.8.
What subscription do you have?
ChatGPT Pro.
What platform is your computer?
macOS 15.1, Apple Silicon.
What issue are you seeing?
Codex Desktop project tasks created through the built-in create_thread path receive the global :read-only permission profile even when the target is a trusted saved project whose project-local .codex/config.toml selects a valid named permission profile.
The target project configuration is equivalent to:
approval_policy = "on-request"
default_permissions = "project-write"
[permissions.project-write]
extends = ":read-only"
[permissions.project-write.filesystem]
"/Users/me/project" = "write"
"/Users/me/project-vault" = "write"
[permissions.project-write.network]
enabled = true
The exact saved project path is trusted in the user-level config. There are no legacy sandbox_mode or sandbox_workspace_write settings. The saved project primary path points to the execution root, not the Vault.
Despite this, every created task reports:
active_permission_profile.id = :read-only
sandbox_policy.type = read-only
permission_profile.filesystem = read :root
permission_profile.network = restricted
Source evidence isolates the transition:
- The
create_threadrequest contained the correct saved project id and environment, but no permission-profile parameter. - At the same launch boundary, the Desktop log recorded:
requestPermissionProfile=:read-only
useAppServerPermissionDefault=false
The transport therefore selected :read-only explicitly instead of allowing the trusted project default to resolve.
What steps can reproduce the bug?
- Set global
default_permissions = ":read-only". - Trust a saved Git project.
- In that project, define and select a named write profile in
.codex/config.toml, with project writes and network enabled. - Create a project task through Codex Desktop task creation using a worktree environment.
- Inspect the first
turn_context: it receives:read-only. - Hand the same task from the worktree to the saved-project checkout and start another turn: it remains
:read-only. - Create a second task directly in the saved-project checkout using the local environment.
- Inspect its first
turn_context: it also receives:read-only.
Observed finite reproduction set: 2/2 fresh creation modes fail (worktree, local); handoff also preserves the wrong profile.
What is the expected behavior?
For a trusted project target, Desktop should either:
- resolve and pass the projects selected
default_permissionsprofile to app-serverthread/start; or - expose a named permission-profile parameter in
create_threadand select it afterpermissionProfile/listvalidates it for the targetcwd.
Desktop should not silently force global :read-only while the UI identifies the task as belonging to a project whose selected permission profile is different.
Additional information
- The project selector, saved primary path, trust entry, and project config were independently verified.
- Worktree versus local checkout does not change the result.
- Handoff is not a permission-refresh mechanism.
- Existing task snapshots are not the whole problem: a genuinely new local project task reproduces it.
- No Codex database, rollout, app bundle, or private Desktop state was modified during diagnosis.
- Raw task ids, user paths, and task contents are omitted. Exact timestamps and sanitized log spans can be supplied privately if needed.
Relevant app-server documentation already supports named permissions on thread/start and recommends permissionProfile/list with the target cwd; the Desktop task-creation wrapper appears to omit that selection and then disable the app-server default.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Trace the Desktop create_thread wrapper and the requestPermissionProfile/useAppServerPermissionDefault launch boundary. Compare its behavior with app-server thread/start and permissionProfile/list documentation for the target cwd. Done means trusted project tasks resolve the selected profile rather than global :read-only in both worktree and local creation paths.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- macos, rust
- Domain
- desktop, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100