fix(codexcli): scope :workspace extends to workspace-wide writes and import extends-only profiles - #1810
Merged
Conversation
…import extends-only profiles
- Emit extends = ":workspace" only for workspace-wide write rules (., ./, **, ./**)
instead of any write rule, since Codex filesystem entries grant access on their
own and :workspace widens write access to the whole workspace plus /tmp/$TMPDIR
- Import extends = ":workspace" as edit: { ".": "allow" } so extends-only
profiles round-trip instead of degrading to default-deny
- Move the domainsHadUnknown flag out of the serialized CodexNetwork type into
an out-of-band parse result, removing the eslint-disable workaround
- Emit network.enabled = true only when an allow rule exists; deny-only domain
sets are emitted without enabled (Codex defaults to restricted) and still
round-trip back into rulesync rules
- Skip global wildcard domain entries that Codex rejects at config load time:
webfetch "*" allow becomes enabled-only, "*" deny is skipped with a warning
- Preserve unix_sockets values verbatim (pass-through) instead of silently
filtering unknown values, and warn when preserving existing network.mode
- Simplify description merge, use object argument for mergeWithExistingProfile,
and document the enabled !== false import rationale
- Update docs/reference/file-formats.md and synced skills/rulesync copy
Closes #1809
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…-domain import on enabled Address review findings on PR #1810: - Codex rejects the global wildcard only in DENIED domains (openai/codex#15549 allows "*" in allowed_domains for denylist-only setups). Emit webfetch "*" allow as a regular "*" = "allow" domain entry (Codex-valid and round-trips), keep skipping "*" deny with a warning. "**" is not a global wildcard in Codex, so no longer special-cased. - On import, take deny entries always but import allow entries only when network.enabled = true is explicit, since Codex treats a missing enabled as restricted; importing allow from a disabled profile would activate a grant Codex never had (privilege escalation on round-trip). - Update e2e import fixture to set enabled = true so allow domains import. - Correct docs/reference/file-formats.md and synced skills copy. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Owner
Author
|
@dyoshikawa Thank you! |
This was referenced Jul 31, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Background
Issue #1809 collected the mid/low review findings from PR #1801 (codexcli permissions round-trip, #1733) so they would not be lost after merge. The findings were re-validated against the upstream Codex CLI source and docs before this fix:
:workspacebaseline grants read access to the whole filesystem and write access to the entire workspace root plus/tmp/$TMPDIR, andfilesystementries grant access on their own withoutextends(verified againstopenai/codexPermissionProfile::workspace_write()/FileSystemSandboxPolicy::workspace_write). Emittingextends = ":workspace"for any write rule therefore over-grants.extends = ":workspace"were dropped on import, degrading to default-deny on regeneration (remaining form of Codex CLI permissions export can lose network and filesystem sandbox baselines #1733).*wildcard innetwork.domainsis rejected at Codex config load time in both allow and deny positions (network-proxy README), so the previous round-trip shapeenabled = true→webfetch: { "*": "allow" }→domains."*" = "allow"generated a config Codex refuses to start with.enabled = trueonly when an allow rule exists, which is behavior-preserving and keeps deny-only sets round-trippable.Changes
extends = ":workspace"only for workspace-wide write rules (.,./,**,./**); narrow or workspace-external writes are expressed purely asfilesystementries (finding 1)extends = ":workspace"asedit: { ".": "allow" }with a round-trip test so extends-only profiles converge instead of being lost (finding 2)domainsHadUnknownout-of-band from profile parsing instead of carrying it inside the serializedCodexNetworktype; removes theeslint-disableworkaround (finding 3)enabled !== falseimport rationale (finding 4)mergeWithExistingProfile(findings 5, 6)unix_socketsvalues verbatim instead of silently filtering unknown values (finding 7)network.enabled = trueonly when at least one allow rule exists; deny-only domain sets are emitted withoutenabledand still re-import (finding 8, with corrected premise)network.mode(finding 9)webfetch: { "*": "allow" }becomesenabled = truewith no domain entry (lossless round-trip with the existing import path),webfetch: { "*": "deny" }is skipped with a warning (finding 10)docs/reference/file-formats.mdandskills/rulesync/file-formats.mdwith the new behaviorpnpm cicheckpasses locally (the content check passes once the synced skills file is committed).Closes #1809
🤖 Generated with Claude Code