Skip to content

Add codex-rs --dangerously-run-with-no-sandbox #1307

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

cliff-openai
Copy link

@cliff-openai cliff-openai commented Jun 11, 2025

This should address #1254 (and motivation/justification is available there)

In short, the sandbox, even with network+disk access, still blocks some things on osx (like access to the keychain most likely). Also, in some environments people are already fully sandboxed (externally to codex), so this gives an option in those environments.

Copy link

github-actions bot commented Jun 11, 2025

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@cliff-openai
Copy link
Author

I have read the CLA Document and I hereby sign the CLA

github-actions bot added a commit that referenced this pull request Jun 11, 2025
@bolinfest
Copy link
Collaborator

Given that this fails for me today:

$ codex debug seatbelt -s disk-full-read-access -s disk-full-write-access -s network-full-access -- gh issue list --limit 10
Post "https://api.github.com/graphql": tls: failed to verify certificate: x509: OSStatus -26276

I don't think this quite accomplishes the goal (or at least, I'm not sure it matches user expectations). It's a little tricky because the are two dimensions to "permissiveness" that can be configured independently:

  • which commands are auto-approved
  • what sandbox configuration to apply when running a command

Note the latter is determined by enum SandboxType and I suspect users expect --dangerously-auto-approve-everything to correspond to SandboxType::None. Or at least, I believe SandboxType::None needs to be used for Codex to be able to run gh issue list --limit 10.

#[derive(Clone, Copy, Debug, PartialEq)]
pub enum SandboxType {
None,
/// Only available on macOS.
MacosSeatbelt,
/// Only available on Linux.
LinuxSeccomp,
}

To that end, I don't know if --dangerously-auto-approve-everything is quite the right name anymore because it would not just be relaxing approvals, but sandbox constraints, as well.

For reference, my personal config.toml has:

approval_policy = "never"

sandbox_permissions = [
    "disk-full-read-access",
    "disk-write-platform-user-temp-folder",
    "disk-write-platform-global-temp-folder",
    "disk-write-cwd",
    "disk-write-folder=/Users/mbolin/.pyenv/shims",
]

In other words, this already satisfies the case where I don't want to be prompted for anything, but I do want it everything to be run under a sandbox policy that is roughly equivalent to --full-auto.

@cliff-openai
Copy link
Author

Ok, I renamed the option to --dangerously-auto-approve-and-run-without-sandbox. If you would prefer, I could instead make the option just be --dangerously-run-commands-without-sandbox and then users may also need/want to set -a never?

@bolinfest
Copy link
Collaborator

I just went to check where we decide what variant of SandboxType to use and I see it is effectively here:

if sandbox_policy.is_unrestricted() {
approve_without_sandbox()
} else {
match get_platform_sandbox() {
// We have a sandbox, so we can approve the command in all modes
Some(sandbox_type) => SafetyCheck::AutoApprove { sandbox_type },
None => {
// We do not have a sandbox, so we need to consider the approval policy
match approval_policy {
// Never is our "non-interactive" mode; it must automatically reject
AskForApproval::Never => SafetyCheck::Reject {
reason: "auto-rejected by user approval settings".to_string(),
},
// Otherwise, we ask the user for approval
_ => SafetyCheck::AskUser,
}
}
}
}

where is_unrestricted() is defined as:

pub fn is_unrestricted(&self) -> bool {
self.has_full_disk_read_access()
&& self.has_full_disk_write_access()
&& self.has_full_network_access()
}
}

so I see how your new_unrestricted_policy() results in exercising the approve_without_sandbox() codepath.

The thing that I don't love about this is that the relationship between this two codepaths is not completely obvious, so I'm worried it makes it too easy to change one in a way that inadvertently breaks --dangerously-auto-approve-everything (again).

I'm looking now to see if there's an easy way to make this relationship more straightforward.

@bolinfest
Copy link
Collaborator

#1248 is somewhat related in that I am not 100% happy with the contract I implemented for --sandbox-permission today.

@bolinfest
Copy link
Collaborator

@cliff-openai though given this investigation, would using the following config unblock you for the moment?

sandbox_permissions = [
    "disk-full-read-access",
    "disk-full-write-access",
    "network-full-access",
]

Though assuming this works, this feels like a bug because it should be possible to use this in concert with approval_policy = "unless-allow-listed", which should mean, "Always ask me, but if I approve, do not run the command in a sandbox," but based on the code above, it appears that if is_unrestricted() is true, then AskForApproval is not considered.

@@ -176,6 +176,18 @@ impl SandboxPolicy {
}
}

/// Unrestricted policy: allow full disk read/write and network access.
/// Commands will be auto-approved without sandbox enforcement.
pub fn new_unrestricted_policy() -> Self {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this will still end up invoking Landlock/Seccomp on linux. In the actual exec.rs code I think we want a conditional to just straight up not sandbox at all to achieve the properties you're looking for here.

Copy link
Author

Choose a reason for hiding this comment

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

ok, I think that the current version now does this (more explicitly has a "NoSandbox" implementation)

This option is now explicitly just about sandbox policy, and we are
explicit/clear about the "NoSandbox" state.
@cliff-openai cliff-openai changed the title Add codex-rs --dangerously-auto-approve-everything Add codex-rs --dangerously-run-with-no-sandbox Jun 13, 2025
@cliff-openai
Copy link
Author

ok, I've updated the change to be more explicitly just about creating a "no sandbox" option.

I am not blocked, and am happy to just abandon this change if it is not helpful. I was assuming that the presence of issue #1254 meant that this change was wanted, but no worries if not.

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.

3 participants