Skip to content

Add workspace metadata protection policy primitive#19846

Open
evawong-oai wants to merge 1 commit intomainfrom
codex/bugb15632-policy-primitive
Open

Add workspace metadata protection policy primitive#19846
evawong-oai wants to merge 1 commit intomainfrom
codex/bugb15632-policy-primitive

Conversation

@evawong-oai
Copy link
Copy Markdown
Contributor

@evawong-oai evawong-oai commented Apr 27, 2026

Summary

Add a policy primitive for protected workspace metadata names so writable roots can reserve .git, .codex, and .agents before platform sandbox code consumes the policy.

Scope

  1. Add protected_metadata_names to WritableRoot.
  2. Default workspace writable roots to protect .git, .codex, and .agents.
  3. Make runtime file system checks reject writes to protected metadata path names unless user policy explicitly allows them.
  4. Add the Linux fallback initializer needed before Linux enforcement lands later in the stack.

Reviewer Focus

  1. Metadata protection belongs in policy, not command parsing.
  2. Explicit user write rules can still opt into these metadata paths.
  3. Legacy workspace write behavior still protects existing git metadata and now also covers the missing metadata path case.

Stack

  1. Policy primitive: this PR
  2. macOS Seatbelt enforcement: Enforce workspace metadata protections in Seatbelt #19847
  3. Shell preflight UX: Add workspace metadata shell preflight #19848
  4. Runtime permission propagation: Propagate runtime permission profiles #19849
  5. Linux bubblewrap enforcement: Enforce workspace metadata protections in Linux sandbox #19852

Validation

  1. cargo test --manifest-path codex-rs/Cargo.toml -p codex-protocol permissions
  2. cargo fmt --manifest-path codex-rs/Cargo.toml --package codex-protocol --package codex-linux-sandbox
  3. git diff --check

@evawong-oai evawong-oai force-pushed the codex/bugb15632-policy-primitive branch 5 times, most recently from a99da8c to 5b59ee3 Compare April 27, 2026 19:48
@evawong-oai evawong-oai changed the base branch from main to codex/bugb15632-windows-cmd-test-skip April 27, 2026 19:50
@evawong-oai evawong-oai force-pushed the codex/bugb15632-policy-primitive branch 2 times, most recently from 01771db to 11fa852 Compare April 27, 2026 21:14
@evawong-oai evawong-oai force-pushed the codex/bugb15632-windows-cmd-test-skip branch from 5b8dd2e to 0f697bc Compare April 27, 2026 21:14
@evawong-oai evawong-oai force-pushed the codex/bugb15632-policy-primitive branch from 11fa852 to ab4b378 Compare April 27, 2026 22:21
@evawong-oai evawong-oai changed the base branch from codex/bugb15632-windows-cmd-test-skip to main April 27, 2026 22:24
@evawong-oai evawong-oai marked this pull request as ready for review April 27, 2026 23:02
Copy link
Copy Markdown
Contributor

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

self.semantic_signature(cwd)
!= FileSystemSandboxPolicy::from_legacy_sandbox_policy_for_cwd(&legacy_policy, cwd)
.semantic_signature(cwd)

P1 Badge Include preserved-write semantics in enforcement bridging check

needs_direct_runtime_enforcement decides compatibility by comparing semantic signatures, but preserved-name write denials are enforced in can_write_path_with_cwd and are not represented in the bridged legacy model. This can return false and skip direct enforcement even when .git/.agents/.codex writes should be blocked.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread codex-rs/protocol/src/permissions.rs Outdated
Comment on lines +1513 to +1519
fn first_preserved_component(path: &Path) -> Option<(AbsolutePathBuf, &'static str)> {
let mut candidate = PathBuf::new();
for component in path.components() {
candidate.push(component.as_os_str());
if let Some(preserved_name) = preserved_path_name(component.as_os_str()) {
let absolute = AbsolutePathBuf::from_absolute_path(candidate).ok()?;
return Some((absolute, preserved_name));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Restrict preserved-name blocking to root-level metadata

can_write_path_with_cwd calls first_preserved_component, which scans all path components and denies writes whenever any component is .git, .agents, or .codex unless there is a deeper explicit rule. This blocks legitimate nested repo writes (e.g. /tmp/repo/.git/...) under otherwise writable roots, so common flows like cloning in /tmp regress.

Useful? React with 👍 / 👎.

@evawong-oai evawong-oai force-pushed the codex/bugb15632-policy-primitive branch from ab4b378 to 8e60a50 Compare April 28, 2026 00:10
@evawong-oai evawong-oai force-pushed the codex/bugb15632-policy-primitive branch from 8e60a50 to 0b263d0 Compare April 28, 2026 01:10
@evawong-oai evawong-oai changed the title Add preserved path policy primitive Add workspace metadata protection policy primitive Apr 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant