openai / openai/codex

Resolved linked-worktree Git directory is unreadable with `:root = "deny"`

Open
#38,672 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug CLI sandbox
Dominant language
Rust
Stars
125k
Forks
19.5k
PR merge metrics
PR metrics pending

Description

What version of Codex CLI is running?

codex-cli 0.147.0

What subscription do you have?

ChatGPT Plus

Which model were you using?

gpt-5.6-sol

What platform is your computer?

Darwin 25.5.0 arm64 arm macOS 26.5.2 on Apple Silicon.

What terminal emulator and version are you using (if applicable)?

Zed using the Codex integration.

Codex doctor report
Not included because the affected session was running through the Zed integration. A redacted CLI doctor report from the same Codex installation can be provided if useful.
What issue are you seeing?

A custom permission profile extends :workspace but denies filesystem reads by default:

default_permissions = "restricted-workspace"

[permissions.restricted-workspace]
extends = ":workspace"

[permissions.restricted-workspace.filesystem]
":minimal" = "read"
":root" = "deny"

When the active workspace is a Git linked worktree, its .git pointer file is readable, but the resolved Git metadata directory outside the workspace is not.

Example layout:

/Users/me/dev/repo/.git/
/Users/me/dev/worktrees/repo/task/

The worktree contains:

gitdir: /Users/me/dev/repo/.git/worktrees/task

Codex can read the worktree's .git file, but the sandbox denies reads from the resolved directory, including:

/Users/me/dev/repo/.git/worktrees/task/HEAD
/Users/me/dev/repo/.git/worktrees/task/commondir

The worktree is listed as an active workspace root by /status.

Explicitly adding the main repository's .git directory as a read permission works around the problem:

[permissions.restricted-workspace.filesystem]
"/Users/me/dev/repo/.git" = "read"

Removing ":root" = "deny" also avoids the problem, but restores broad filesystem read access and defeats the least-privilege purpose of the custom profile.

What steps can reproduce the bug?
  1. Create a normal Git repository.
  2. Create a linked worktree in a directory outside the main checkout.
  3. Configure and select the permission profile shown above.
  4. Launch Codex with the linked worktree as the workspace.
  5. Confirm that /status lists the linked worktree as a workspace root.
  6. Run:
cat .git
gitdir=$(sed -n 's/^gitdir: //p' .git)
cat "$gitdir/HEAD"
cat "$gitdir/commondir"
git status

The .git pointer can be read, but reads from $gitdir are denied by the sandbox.

What is the expected behavior?

When a workspace root contains a .git pointer file, Codex should dynamically add the resolved worktree Git directory and common Git directory to the readable roots.

These paths should remain protected from writes unless separately authorized.

This would match the documented workspace-write behavior:

If /.git is a pointer file (gitdir: ...), the resolved Git directory path is also protected as read-only.

A read-only protected path should remain readable when a custom permission profile replaces ambient root reads with an explicit allowlist.

Additional information

This appears distinct from existing reports about Git metadata being read-only for writes:

Those issues concern operations such as git add and git commit. This report concerns basic read access needed by commands such as git status.

Possible root-cause hypothesis:

In the macOS sandbox implementation, resolved Git metadata appears to be added as a protected path in the write policy. When full-disk reads are disabled, however, the read policy appears to admit only explicitly configured readable roots. The dynamically resolved Git directory does not appear to be added to that set.

Relevant implementation:

https://github.com/openai/codex/blob/rust-v0.147.0/codex-rs/sandboxing/src/seatbelt.rs#L595-L681

A possible fix would be to resolve the active workspace's .git pointer and commondir, add those locations to the sandbox's readable roots, and retain the existing recursive write protection.

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

Read codex-rs/sandboxing/src/seatbelt.rs around lines 595-681, then reproduce the linked-worktree case with the restricted-workspace profile and the commands in the issue. Trace how the .git pointer and commondir are handled for read and write policies; done means git status and reads of HEAD and commondir work while writes remain protected.

Written by the indexing model from the issue text.

Assessment

Tech stack
macos, rust
Domain
operating-systems, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.