codex - 💡(How to fix) Fix Support user-provided Seatbelt sandbox rules via config or drop-in file

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Fix Action

Fix / Workaround

Motivation: Codex's Seatbelt base policy (seatbelt_base_policy.sbpl + restricted_read_only_platform_defaults.sbpl) covers common OS interactions but inevitably misses niche-but-legitimate ones. The current workarounds — per-command escalation or :danger-full-access — are either tedious or overly broad.

Related: #21292 (Playwright Chromium fails in sandbox with MachPortRendezvousServer permission denied) — I posted a root-cause analysis and the specific fix there. That issue would be fully resolved by either upstreaming the rule into seatbelt_base_policy.sbpl or by this feature allowing users to add it themselves.

Code Example

[permissions.my-profile]
   sandbox_extra_rules = """
   (allow mach-register (global-name-regex #"^org\\.chromium\\."))
   (allow mach-lookup (global-name "com.apple.CARenderServer"))
   """

---

// After assembling policy_sections from built-in .sbpl files + dynamic rules:
let extra_path = dirs::home_dir()
    .map(|h| h.join(".codex/sandbox-extra.sb"));
if let Some(path) = extra_path {
    if let Ok(extra) = std::fs::read_to_string(&path) {
        policy_sections.push(extra);
    }
}
let full_policy = policy_sections.join("\n");
RAW_BUFFERClick to expand / collapse

What variant of Codex are you using?

CLI (also applies to Desktop app on macOS)

What feature would you like to see?

Allow users to provide additional Seatbelt sandbox rules that get appended to the assembled policy at runtime, without recompiling Codex.

Motivation: Codex's Seatbelt base policy (seatbelt_base_policy.sbpl + restricted_read_only_platform_defaults.sbpl) covers common OS interactions but inevitably misses niche-but-legitimate ones. The current workarounds — per-command escalation or :danger-full-access — are either tedious or overly broad.

A concrete example: Chromium/Playwright headless (#21292) requires (allow mach-register (global-name-regex #"^org\.chromium\.")) for its multi-process IPC. Today, users must escalate every Playwright invocation or disable the sandbox entirely. A one-line user rule would fix it permanently and precisely.

Other cases that benefit from user-provided rules:

  • CLI tools that write config to non-standard ~/Library/Application Support/<tool>/ paths (e.g., glab-cli)
  • Language toolchain telemetry paths (e.g., Go writes to ~/Library/Application Support/go/telemetry/)
  • Platform-specific sysctl-read entries for ARM feature detection (hw.optional.neon_fp16, etc.)
  • Mach service lookups required by domain-specific frameworks

Proposed approach (one of):

  1. Drop-in file: Read ~/.codex/sandbox-extra.sb (or ~/.codex/sandbox.d/*.sb) if it exists, and append its contents to the assembled Seatbelt policy after all built-in sections.

  2. Config key: Add a sandbox_extra_rules key to config.toml under the permission profile:

    [permissions.my-profile]
    sandbox_extra_rules = """
    (allow mach-register (global-name-regex #"^org\\.chromium\\."))
    (allow mach-lookup (global-name "com.apple.CARenderServer"))
    """
  3. Config file reference: A sandbox_extra_rules_file key pointing to an external .sb file.

The drop-in file approach is simplest and follows established patterns (conf.d/ in nginx, systemd, etc.). It also keeps sandbox customization separate from the TOML config, which feels appropriate given that Seatbelt rules are a different language (TinyScheme S-expressions).

Implementation sketch (in codex-rs/sandboxing/src/seatbelt.rs):

// After assembling policy_sections from built-in .sbpl files + dynamic rules:
let extra_path = dirs::home_dir()
    .map(|h| h.join(".codex/sandbox-extra.sb"));
if let Some(path) = extra_path {
    if let Ok(extra) = std::fs::read_to_string(&path) {
        policy_sections.push(extra);
    }
}
let full_policy = policy_sections.join("\n");

This is ~5 lines of Rust with zero breaking changes. Users who don't create the file get identical behavior to today.

Security consideration: Users who can write ~/.codex/sandbox-extra.sb already have full access to their own machine — they could just run commands outside the sandbox. User-provided rules only relax the sandbox (Seatbelt rules are additive on top of (deny default)), and the current permission profile system already trusts user-authored TOML config for filesystem and network policy. This is consistent with that trust model.

Additional information

I maintain a macOS Seatbelt sandbox wrapper (ccbox) for Claude Code that reuses Codex's base .sbpl policies. The wrapper uses a text-file-based approach for user rules (extra-allow.txt + editable sandbox-base.sb), and being able to add the Chromium mach-register rule without recompilation has been essential for Playwright/browser-based verification workflows.

Related: #21292 (Playwright Chromium fails in sandbox with MachPortRendezvousServer permission denied) — I posted a root-cause analysis and the specific fix there. That issue would be fully resolved by either upstreaming the rule into seatbelt_base_policy.sbpl or by this feature allowing users to add it themselves.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

codex - 💡(How to fix) Fix Support user-provided Seatbelt sandbox rules via config or drop-in file