mirror of
https://github.com/openai/codex.git
synced 2026-04-30 19:32:04 +03:00
Clarify sandbox permission override helper semantics (#13703)
## Summary Today `SandboxPermissions::requires_additional_permissions()` does not actually mean "is `WithAdditionalPermissions`". It returns `true` for any non-default sandbox override, including `RequireEscalated`. That broad behavior is relied on in multiple `main` callsites. The naming is security-sensitive because `SandboxPermissions` is used on shell-like tool calls to tell the executor how a single command should relate to the turn sandbox: - `UseDefault`: run with the turn sandbox unchanged - `RequireEscalated`: request execution outside the sandbox - `WithAdditionalPermissions`: stay sandboxed but widen permissions for that command only ## Problem The old helper name reads as if it only applies to the `WithAdditionalPermissions` variant. In practice it means "this command requested any explicit sandbox override." That ambiguity made it easy to read production checks incorrectly and made the guardian change look like a standalone `main` fix when it is not. On `main` today: - `shell` and `unified_exec` intentionally reject any explicit `sandbox_permissions` request unless approval policy is `OnRequest` - `exec_policy` intentionally treats any explicit sandbox override as prompt-worthy in restricted sandboxes - tests intentionally serialize both `RequireEscalated` and `WithAdditionalPermissions` as explicit sandbox override requests So changing those callsites from the broad helper to a narrow `WithAdditionalPermissions` check would be a behavior change, not a pure cleanup. ## What This PR Does - documents `SandboxPermissions` as a per-command sandbox override, not a generic permissions bag - adds `requests_sandbox_override()` for the broad meaning: anything except `UseDefault` - adds `uses_additional_permissions()` for the narrow meaning: only `WithAdditionalPermissions` - keeps `requires_additional_permissions()` as a compatibility alias to the broad meaning for now - updates the current broad callsites to use the accurately named broad helper - adds unit coverage that locks in the semantics of all three helpers ## What This PR Does Not Do This PR does not change runtime behavior. That is intentional. --------- Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
committed by
GitHub
parent
c8f4b5bc1e
commit
cb1a182bbe
@@ -28,18 +28,19 @@ use schemars::JsonSchema;
|
||||
|
||||
use crate::mcp::CallToolResult;
|
||||
|
||||
/// Controls whether a command should use the session sandbox or bypass it.
|
||||
/// Controls the per-command sandbox override requested by a shell-like tool call.
|
||||
#[derive(
|
||||
Debug, Clone, Copy, Default, Eq, Hash, PartialEq, Serialize, Deserialize, JsonSchema, TS,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum SandboxPermissions {
|
||||
/// Run with the configured sandbox
|
||||
/// Run with the turn's configured sandbox policy unchanged.
|
||||
#[default]
|
||||
UseDefault,
|
||||
/// Request to run outside the sandbox
|
||||
/// Request to run outside the sandbox.
|
||||
RequireEscalated,
|
||||
/// Request to run in the sandbox with additional per-command permissions.
|
||||
/// Request to stay in the sandbox while widening permissions for this
|
||||
/// command only.
|
||||
WithAdditionalPermissions,
|
||||
}
|
||||
|
||||
@@ -49,10 +50,17 @@ impl SandboxPermissions {
|
||||
matches!(self, SandboxPermissions::RequireEscalated)
|
||||
}
|
||||
|
||||
/// True if SandboxPermissions requires permissions beyond UseDefault
|
||||
pub fn requires_additional_permissions(self) -> bool {
|
||||
/// True if SandboxPermissions requests any explicit per-command override
|
||||
/// beyond `UseDefault`.
|
||||
pub fn requests_sandbox_override(self) -> bool {
|
||||
!matches!(self, SandboxPermissions::UseDefault)
|
||||
}
|
||||
|
||||
/// True if SandboxPermissions uses the sandboxed per-command permission
|
||||
/// widening flow.
|
||||
pub fn uses_additional_permissions(self) -> bool {
|
||||
matches!(self, SandboxPermissions::WithAdditionalPermissions)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Eq, Hash, PartialEq, Serialize, Deserialize, JsonSchema, TS)]
|
||||
@@ -1305,6 +1313,41 @@ mod tests {
|
||||
use std::path::PathBuf;
|
||||
use tempfile::tempdir;
|
||||
|
||||
#[test]
|
||||
fn sandbox_permissions_helpers_match_documented_semantics() {
|
||||
let cases = [
|
||||
(SandboxPermissions::UseDefault, false, false, false),
|
||||
(SandboxPermissions::RequireEscalated, true, true, false),
|
||||
(
|
||||
SandboxPermissions::WithAdditionalPermissions,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
),
|
||||
];
|
||||
|
||||
for (
|
||||
sandbox_permissions,
|
||||
requires_escalated_permissions,
|
||||
requests_sandbox_override,
|
||||
uses_additional_permissions,
|
||||
) in cases
|
||||
{
|
||||
assert_eq!(
|
||||
sandbox_permissions.requires_escalated_permissions(),
|
||||
requires_escalated_permissions
|
||||
);
|
||||
assert_eq!(
|
||||
sandbox_permissions.requests_sandbox_override(),
|
||||
requests_sandbox_override
|
||||
);
|
||||
assert_eq!(
|
||||
sandbox_permissions.uses_additional_permissions(),
|
||||
uses_additional_permissions
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn convert_mcp_content_to_items_preserves_data_urls() {
|
||||
let contents = vec![serde_json::json!({
|
||||
|
||||
Reference in New Issue
Block a user