mirror of
https://github.com/openai/codex.git
synced 2026-05-04 13:21:54 +03:00
Feat: Preserve network access on read-only sandbox policies (#13409)
## Summary
`PermissionProfile.network` could not be preserved when additional or
compiled permissions resolved to
`SandboxPolicy::ReadOnly`, because `ReadOnly` had no network_access
field. This change makes read-only + network
enabled representable directly and threads that through the protocol,
app-server v2 mirror, and permission-
merging logic.
## What changed
- Added `network_access: bool` to `SandboxPolicy::ReadOnly` in the core
protocol and app-server v2 protocol.
- Kept backward compatibility by defaulting the new field to false, so
legacy read-only payloads still
deserialize unchanged.
- Updated `has_full_network_access()` and sandbox summaries to respect
read-only network access.
- Preserved PermissionProfile.network when:
- compiling skill permission profiles into sandbox policies
- normalizing additional permissions
- merging additional permissions into existing sandbox policies
- Updated the approval overlay to show network in the rendered
permission rule when requested.
- Regenerated app-server schema fixtures for the new v2 wire shape.
This commit is contained in:
@@ -641,6 +641,9 @@ fn format_additional_permissions_rule(
|
||||
additional_permissions: &PermissionProfile,
|
||||
) -> Option<String> {
|
||||
let mut parts = Vec::new();
|
||||
if matches!(additional_permissions.network, Some(true)) {
|
||||
parts.push("network".to_string());
|
||||
}
|
||||
if let Some(file_system) = additional_permissions.file_system.as_ref() {
|
||||
if let Some(read) = file_system.read.as_ref() {
|
||||
let reads = read
|
||||
@@ -1074,6 +1077,7 @@ mod tests {
|
||||
available_decisions: vec![ReviewDecision::Approved, ReviewDecision::Abort],
|
||||
network_approval_context: None,
|
||||
additional_permissions: Some(PermissionProfile {
|
||||
network: Some(true),
|
||||
file_system: Some(FileSystemPermissions {
|
||||
read: Some(vec![absolute_path("/tmp/readme.txt")]),
|
||||
write: Some(vec![absolute_path("/tmp/out.txt")]),
|
||||
@@ -1100,6 +1104,10 @@ mod tests {
|
||||
.any(|line| line.contains("Permission rule:")),
|
||||
"expected permission-rule line, got {rendered:?}"
|
||||
);
|
||||
assert!(
|
||||
rendered.iter().any(|line| line.contains("network;")),
|
||||
"expected network permission text, got {rendered:?}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1115,6 +1123,7 @@ mod tests {
|
||||
available_decisions: vec![ReviewDecision::Approved, ReviewDecision::Abort],
|
||||
network_approval_context: None,
|
||||
additional_permissions: Some(PermissionProfile {
|
||||
network: Some(true),
|
||||
file_system: Some(FileSystemPermissions {
|
||||
read: Some(vec![absolute_path("/tmp/readme.txt")]),
|
||||
write: Some(vec![absolute_path("/tmp/out.txt")]),
|
||||
|
||||
@@ -7,7 +7,7 @@ expression: "render_overlay_lines(&view, 120)"
|
||||
|
||||
Reason: need filesystem access
|
||||
|
||||
Permission rule: read `/tmp/readme.txt`; write `/tmp/out.txt`
|
||||
Permission rule: network; read `/tmp/readme.txt`; write `/tmp/out.txt`
|
||||
|
||||
$ cat /tmp/readme.txt
|
||||
|
||||
|
||||
Reference in New Issue
Block a user