mirror of
https://github.com/openai/codex.git
synced 2026-05-12 23:32:44 +00:00
Compare commits
1 Commits
dev/vasili
...
codex/remo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ce9811fd5b |
@@ -171,7 +171,7 @@
|
||||
"type": "object"
|
||||
},
|
||||
"CommandExecParams": {
|
||||
"description": "Run a standalone command (argv vector) in the server sandbox without creating a thread or turn.\n\nThe final `command/exec` response is deferred until the process exits and is sent only after all `command/exec/outputDelta` notifications for that connection have been emitted.",
|
||||
"description": "Run a standalone command (argv vector) without creating a thread or turn.\n\nThe final `command/exec` response is deferred until the process exits and is sent only after all `command/exec/outputDelta` notifications for that connection have been emitted.",
|
||||
"properties": {
|
||||
"command": {
|
||||
"description": "Command argv vector. Empty arrays are rejected.",
|
||||
@@ -224,17 +224,6 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"sandboxPolicy": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/SandboxPolicy"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"description": "Optional sandbox policy for this command.\n\nUses the same shape as thread/turn execution sandbox configuration and defaults to the user's configured policy when omitted."
|
||||
},
|
||||
"size": {
|
||||
"anyOf": [
|
||||
{
|
||||
|
||||
@@ -6358,7 +6358,7 @@
|
||||
},
|
||||
"CommandExecParams": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"description": "Run a standalone command (argv vector) in the server sandbox without creating a thread or turn.\n\nThe final `command/exec` response is deferred until the process exits and is sent only after all `command/exec/outputDelta` notifications for that connection have been emitted.",
|
||||
"description": "Run a standalone command (argv vector) without creating a thread or turn.\n\nThe final `command/exec` response is deferred until the process exits and is sent only after all `command/exec/outputDelta` notifications for that connection have been emitted.",
|
||||
"properties": {
|
||||
"command": {
|
||||
"description": "Command argv vector. Empty arrays are rejected.",
|
||||
@@ -6411,17 +6411,6 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"sandboxPolicy": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/SandboxPolicy"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"description": "Optional sandbox policy for this command.\n\nUses the same shape as thread/turn execution sandbox configuration and defaults to the user's configured policy when omitted."
|
||||
},
|
||||
"size": {
|
||||
"anyOf": [
|
||||
{
|
||||
|
||||
@@ -2965,7 +2965,7 @@
|
||||
},
|
||||
"CommandExecParams": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"description": "Run a standalone command (argv vector) in the server sandbox without creating a thread or turn.\n\nThe final `command/exec` response is deferred until the process exits and is sent only after all `command/exec/outputDelta` notifications for that connection have been emitted.",
|
||||
"description": "Run a standalone command (argv vector) without creating a thread or turn.\n\nThe final `command/exec` response is deferred until the process exits and is sent only after all `command/exec/outputDelta` notifications for that connection have been emitted.",
|
||||
"properties": {
|
||||
"command": {
|
||||
"description": "Command argv vector. Empty arrays are rejected.",
|
||||
@@ -3018,17 +3018,6 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"sandboxPolicy": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/SandboxPolicy"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"description": "Optional sandbox policy for this command.\n\nUses the same shape as thread/turn execution sandbox configuration and defaults to the user's configured policy when omitted."
|
||||
},
|
||||
"size": {
|
||||
"anyOf": [
|
||||
{
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"definitions": {
|
||||
"AbsolutePathBuf": {
|
||||
"description": "A path that is guaranteed to be absolute and normalized (though it is not guaranteed to be canonicalized or exist on the filesystem).\n\nIMPORTANT: When deserializing an `AbsolutePathBuf`, a base path must be set using [AbsolutePathBufGuard::new]. If no base path is set, the deserialization will fail unless the path being deserialized is already absolute.",
|
||||
"type": "string"
|
||||
},
|
||||
"CommandExecTerminalSize": {
|
||||
"description": "PTY size in character cells for `command/exec` PTY sessions.",
|
||||
"properties": {
|
||||
@@ -26,182 +22,9 @@
|
||||
"rows"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"NetworkAccess": {
|
||||
"enum": [
|
||||
"restricted",
|
||||
"enabled"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"ReadOnlyAccess": {
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"includePlatformDefaults": {
|
||||
"default": true,
|
||||
"type": "boolean"
|
||||
},
|
||||
"readableRoots": {
|
||||
"default": [],
|
||||
"items": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"restricted"
|
||||
],
|
||||
"title": "RestrictedReadOnlyAccessType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"title": "RestrictedReadOnlyAccess",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"fullAccess"
|
||||
],
|
||||
"title": "FullAccessReadOnlyAccessType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"title": "FullAccessReadOnlyAccess",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"SandboxPolicy": {
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"dangerFullAccess"
|
||||
],
|
||||
"title": "DangerFullAccessSandboxPolicyType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"title": "DangerFullAccessSandboxPolicy",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"access": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ReadOnlyAccess"
|
||||
}
|
||||
],
|
||||
"default": {
|
||||
"type": "fullAccess"
|
||||
}
|
||||
},
|
||||
"networkAccess": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"readOnly"
|
||||
],
|
||||
"title": "ReadOnlySandboxPolicyType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"title": "ReadOnlySandboxPolicy",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"networkAccess": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/NetworkAccess"
|
||||
}
|
||||
],
|
||||
"default": "restricted"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"externalSandbox"
|
||||
],
|
||||
"title": "ExternalSandboxSandboxPolicyType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"title": "ExternalSandboxSandboxPolicy",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"excludeSlashTmp": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"excludeTmpdirEnvVar": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"networkAccess": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"readOnlyAccess": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ReadOnlyAccess"
|
||||
}
|
||||
],
|
||||
"default": {
|
||||
"type": "fullAccess"
|
||||
}
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"workspaceWrite"
|
||||
],
|
||||
"title": "WorkspaceWriteSandboxPolicyType",
|
||||
"type": "string"
|
||||
},
|
||||
"writableRoots": {
|
||||
"default": [],
|
||||
"items": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"title": "WorkspaceWriteSandboxPolicy",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"description": "Run a standalone command (argv vector) in the server sandbox without creating a thread or turn.\n\nThe final `command/exec` response is deferred until the process exits and is sent only after all `command/exec/outputDelta` notifications for that connection have been emitted.",
|
||||
"description": "Run a standalone command (argv vector) without creating a thread or turn.\n\nThe final `command/exec` response is deferred until the process exits and is sent only after all `command/exec/outputDelta` notifications for that connection have been emitted.",
|
||||
"properties": {
|
||||
"command": {
|
||||
"description": "Command argv vector. Empty arrays are rejected.",
|
||||
@@ -254,17 +77,6 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"sandboxPolicy": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/SandboxPolicy"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"description": "Optional sandbox policy for this command.\n\nUses the same shape as thread/turn execution sandbox configuration and defaults to the user's configured policy when omitted."
|
||||
},
|
||||
"size": {
|
||||
"anyOf": [
|
||||
{
|
||||
|
||||
@@ -2,11 +2,9 @@
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { CommandExecTerminalSize } from "./CommandExecTerminalSize";
|
||||
import type { SandboxPolicy } from "./SandboxPolicy";
|
||||
|
||||
/**
|
||||
* Run a standalone command (argv vector) in the server sandbox without
|
||||
* creating a thread or turn.
|
||||
* Run a standalone command (argv vector) without creating a thread or turn.
|
||||
*
|
||||
* The final `command/exec` response is deferred until the process exits and is
|
||||
* sent only after all `command/exec/outputDelta` notifications for that
|
||||
@@ -87,11 +85,4 @@ env?: { [key in string]?: string | null } | null,
|
||||
* Optional initial PTY size in character cells. Only valid when `tty` is
|
||||
* true.
|
||||
*/
|
||||
size?: CommandExecTerminalSize | null,
|
||||
/**
|
||||
* Optional sandbox policy for this command.
|
||||
*
|
||||
* Uses the same shape as thread/turn execution sandbox configuration and
|
||||
* defaults to the user's configured policy when omitted.
|
||||
*/
|
||||
sandboxPolicy?: SandboxPolicy | null, };
|
||||
size?: CommandExecTerminalSize | null, };
|
||||
|
||||
@@ -17,7 +17,6 @@ impl From<v1::ExecOneOffCommandParams> for v2::CommandExecParams {
|
||||
cwd: value.cwd,
|
||||
env: None,
|
||||
size: None,
|
||||
sandbox_policy: value.sandbox_policy.map(std::convert::Into::into),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ use codex_protocol::protocol::AskForApproval;
|
||||
use codex_protocol::protocol::FileChange;
|
||||
pub use codex_protocol::protocol::GitSha;
|
||||
use codex_protocol::protocol::ReviewDecision;
|
||||
use codex_protocol::protocol::SandboxPolicy;
|
||||
use codex_protocol::protocol::SessionSource;
|
||||
use codex_protocol::protocol::TurnAbortReason;
|
||||
use codex_utils_absolute_path::AbsolutePathBuf;
|
||||
@@ -181,7 +180,6 @@ pub struct ExecOneOffCommandParams {
|
||||
pub command: Vec<String>,
|
||||
pub timeout_ms: Option<u64>,
|
||||
pub cwd: Option<PathBuf>,
|
||||
pub sandbox_policy: Option<SandboxPolicy>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||
|
||||
@@ -2949,8 +2949,7 @@ pub struct CommandExecTerminalSize {
|
||||
pub cols: u16,
|
||||
}
|
||||
|
||||
/// Run a standalone command (argv vector) in the server sandbox without
|
||||
/// creating a thread or turn.
|
||||
/// Run a standalone command (argv vector) without creating a thread or turn.
|
||||
///
|
||||
/// The final `command/exec` response is deferred until the process exits and is
|
||||
/// sent only after all `command/exec/outputDelta` notifications for that
|
||||
@@ -3023,12 +3022,6 @@ pub struct CommandExecParams {
|
||||
/// true.
|
||||
#[ts(optional = nullable)]
|
||||
pub size: Option<CommandExecTerminalSize>,
|
||||
/// Optional sandbox policy for this command.
|
||||
///
|
||||
/// Uses the same shape as thread/turn execution sandbox configuration and
|
||||
/// defaults to the user's configured policy when omitted.
|
||||
#[ts(optional = nullable)]
|
||||
pub sandbox_policy: Option<SandboxPolicy>,
|
||||
}
|
||||
|
||||
/// Final buffered result for `command/exec`.
|
||||
@@ -8103,7 +8096,6 @@ mod tests {
|
||||
cwd: Some(PathBuf::from("/tmp")),
|
||||
env: None,
|
||||
size: None,
|
||||
sandbox_policy: None,
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -8123,7 +8115,6 @@ mod tests {
|
||||
cwd: None,
|
||||
env: None,
|
||||
size: None,
|
||||
sandbox_policy: None,
|
||||
};
|
||||
|
||||
let value = serde_json::to_value(¶ms).expect("serialize command/exec params");
|
||||
@@ -8137,7 +8128,6 @@ mod tests {
|
||||
"cwd": null,
|
||||
"env": null,
|
||||
"size": null,
|
||||
"sandboxPolicy": null,
|
||||
"outputBytesCap": null,
|
||||
})
|
||||
);
|
||||
@@ -8162,7 +8152,6 @@ mod tests {
|
||||
cwd: None,
|
||||
env: None,
|
||||
size: None,
|
||||
sandbox_policy: None,
|
||||
};
|
||||
|
||||
let value = serde_json::to_value(¶ms).expect("serialize command/exec params");
|
||||
@@ -8178,7 +8167,6 @@ mod tests {
|
||||
"cwd": null,
|
||||
"env": null,
|
||||
"size": null,
|
||||
"sandboxPolicy": null,
|
||||
})
|
||||
);
|
||||
|
||||
@@ -8206,7 +8194,6 @@ mod tests {
|
||||
("BAZ".to_string(), None),
|
||||
])),
|
||||
size: None,
|
||||
sandbox_policy: None,
|
||||
};
|
||||
|
||||
let value = serde_json::to_value(¶ms).expect("serialize command/exec params");
|
||||
@@ -8224,7 +8211,6 @@ mod tests {
|
||||
"BAZ": null,
|
||||
},
|
||||
"size": null,
|
||||
"sandboxPolicy": null,
|
||||
})
|
||||
);
|
||||
|
||||
@@ -8293,7 +8279,6 @@ mod tests {
|
||||
rows: 40,
|
||||
cols: 120,
|
||||
}),
|
||||
sandbox_policy: None,
|
||||
};
|
||||
|
||||
let value = serde_json::to_value(¶ms).expect("serialize command/exec params");
|
||||
@@ -8311,7 +8296,6 @@ mod tests {
|
||||
"rows": 40,
|
||||
"cols": 120,
|
||||
},
|
||||
"sandboxPolicy": null,
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
@@ -164,7 +164,7 @@ Example with notification opt-out:
|
||||
- `thread/realtime/appendText` — append text input to the active realtime session (experimental); returns `{}`.
|
||||
- `thread/realtime/stop` — stop the active realtime session for the thread (experimental); returns `{}`.
|
||||
- `review/start` — kick off Codex’s automated reviewer for a thread; responds like `turn/start` and emits `item/started`/`item/completed` notifications with `enteredReviewMode` and `exitedReviewMode` items, plus a final assistant `agentMessage` containing the review.
|
||||
- `command/exec` — run a single command under the server sandbox without starting a thread/turn (handy for utilities and validation).
|
||||
- `command/exec` — run a single command without starting a thread/turn or enforcing a Codex sandbox (handy for utilities and validation).
|
||||
- `command/exec/write` — write base64-decoded stdin bytes to a running `command/exec` session or close stdin; returns `{}`.
|
||||
- `command/exec/resize` — resize a running PTY-backed `command/exec` session by `processId`; returns `{}`.
|
||||
- `command/exec/terminate` — terminate a running `command/exec` session by `processId`; returns `{}`.
|
||||
@@ -806,7 +806,7 @@ The `review` string is plain text that already bundles the overall explanation p
|
||||
|
||||
### Example: One-off command execution
|
||||
|
||||
Run a standalone command (argv vector) in the server’s sandbox without creating a thread or turn:
|
||||
Run a standalone command (argv vector) without creating a thread or turn. This RPC does not accept a sandbox policy and does not enforce a Codex sandbox.
|
||||
|
||||
```json
|
||||
{ "method": "command/exec", "id": 32, "params": {
|
||||
@@ -815,7 +815,6 @@ Run a standalone command (argv vector) in the server’s sandbox without creatin
|
||||
"cwd": "/Users/me/project", // optional; defaults to server cwd
|
||||
"env": { "FOO": "override" }, // optional; merges into the server env and overrides matching names
|
||||
"size": { "rows": 40, "cols": 120 }, // optional; PTY size in character cells, only valid with tty=true
|
||||
"sandboxPolicy": { "type": "workspaceWrite" }, // optional; defaults to user config
|
||||
"outputBytesCap": 1048576, // optional; per-stream capture cap
|
||||
"disableOutputCap": false, // optional; cannot be combined with outputBytesCap
|
||||
"timeoutMs": 10000, // optional; ms timeout; defaults to server timeout
|
||||
@@ -828,12 +827,9 @@ Run a standalone command (argv vector) in the server’s sandbox without creatin
|
||||
} }
|
||||
```
|
||||
|
||||
- For clients that are already sandboxed externally, set `sandboxPolicy` to `{"type":"externalSandbox","networkAccess":"enabled"}` (or omit `networkAccess` to keep it restricted). Codex will not enforce its own sandbox in this mode; it tells the model it has full file-system access and passes the `networkAccess` state through `environment_context`.
|
||||
|
||||
Notes:
|
||||
|
||||
- Empty `command` arrays are rejected.
|
||||
- `sandboxPolicy` accepts the same shape used by `turn/start` (e.g., `dangerFullAccess`, `readOnly`, `workspaceWrite` with flags, `externalSandbox` with `networkAccess` `restricted|enabled`).
|
||||
- `env` merges into the environment produced by the server's shell environment policy. Matching names are overridden; unspecified variables are left intact.
|
||||
- When omitted, `timeoutMs` falls back to the server default.
|
||||
- When omitted, `outputBytesCap` falls back to the server default of 1 MiB per stream.
|
||||
@@ -841,8 +837,6 @@ Notes:
|
||||
- `disableTimeout: true` disables the timeout entirely for that `command/exec` request. It cannot be combined with `timeoutMs`.
|
||||
- `processId` is optional for buffered execution. When omitted, Codex generates an internal id for lifecycle tracking, but `tty`, `streamStdin`, and `streamStdoutStderr` must stay disabled and follow-up `command/exec/write` / `command/exec/terminate` calls are not available for that command.
|
||||
- `size` is only valid when `tty: true`. It sets the initial PTY size in character cells.
|
||||
- Buffered Windows sandbox execution accepts `processId` for correlation, but `command/exec/write` and `command/exec/terminate` are still unsupported for those requests.
|
||||
- Buffered Windows sandbox execution also requires the default output cap; custom `outputBytesCap` and `disableOutputCap` are unsupported there.
|
||||
- `tty`, `streamStdin`, and `streamStdoutStderr` are optional booleans. Legacy requests that omit them continue to use buffered execution.
|
||||
- `tty: true` implies PTY mode plus `streamStdin: true` and `streamStdoutStderr: true`.
|
||||
- `tty` and `streamStdin` do not disable the timeout on their own; omit `timeoutMs` to use the server default timeout, or set `disableTimeout: true` to keep the process alive until exit or explicit termination.
|
||||
|
||||
@@ -228,7 +228,6 @@ use codex_core::ThreadManager;
|
||||
use codex_core::clear_memory_roots_contents;
|
||||
use codex_core::config::Config;
|
||||
use codex_core::config::ConfigOverrides;
|
||||
use codex_core::config::NetworkProxyAuditMetadata;
|
||||
use codex_core::config::edit::ConfigEdit;
|
||||
use codex_core::config::edit::ConfigEditsBuilder;
|
||||
use codex_core::config_loader::CloudRequirementsLoadError;
|
||||
@@ -2070,7 +2069,6 @@ impl CodexMessageProcessor {
|
||||
cwd,
|
||||
env: env_overrides,
|
||||
size,
|
||||
sandbox_policy,
|
||||
} = params;
|
||||
|
||||
if size.is_some() && !tty {
|
||||
@@ -2138,33 +2136,6 @@ impl CodexMessageProcessor {
|
||||
},
|
||||
None => None,
|
||||
};
|
||||
let managed_network_requirements_enabled =
|
||||
self.config.managed_network_requirements_enabled();
|
||||
let started_network_proxy = match self.config.permissions.network.as_ref() {
|
||||
Some(spec) => match spec
|
||||
.start_proxy(
|
||||
self.config.permissions.sandbox_policy.get(),
|
||||
/*policy_decider*/ None,
|
||||
/*blocked_request_observer*/ None,
|
||||
managed_network_requirements_enabled,
|
||||
NetworkProxyAuditMetadata::default(),
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(started) => Some(started),
|
||||
Err(err) => {
|
||||
let error = JSONRPCErrorError {
|
||||
code: INTERNAL_ERROR_CODE,
|
||||
message: format!("failed to start managed network proxy: {err}"),
|
||||
data: None,
|
||||
};
|
||||
self.outgoing.send_error(request, error).await;
|
||||
return;
|
||||
}
|
||||
},
|
||||
None => None,
|
||||
};
|
||||
let windows_sandbox_level = WindowsSandboxLevel::from_config(&self.config);
|
||||
let output_bytes_cap = if disable_output_cap {
|
||||
None
|
||||
} else {
|
||||
@@ -2190,11 +2161,9 @@ impl CodexMessageProcessor {
|
||||
expiration,
|
||||
capture_policy,
|
||||
env,
|
||||
network: started_network_proxy
|
||||
.as_ref()
|
||||
.map(codex_core::config::StartedNetworkProxy::proxy),
|
||||
network: None,
|
||||
sandbox_permissions: SandboxPermissions::UseDefault,
|
||||
windows_sandbox_level,
|
||||
windows_sandbox_level: WindowsSandboxLevel::Disabled,
|
||||
windows_sandbox_private_desktop: self
|
||||
.config
|
||||
.permissions
|
||||
@@ -2203,41 +2172,14 @@ impl CodexMessageProcessor {
|
||||
arg0: None,
|
||||
};
|
||||
|
||||
let requested_policy = sandbox_policy.map(|policy| policy.to_core());
|
||||
let (
|
||||
effective_policy,
|
||||
effective_file_system_sandbox_policy,
|
||||
effective_network_sandbox_policy,
|
||||
) = match requested_policy {
|
||||
Some(policy) => match self.config.permissions.sandbox_policy.can_set(&policy) {
|
||||
Ok(()) => {
|
||||
let file_system_sandbox_policy =
|
||||
codex_protocol::permissions::FileSystemSandboxPolicy::from_legacy_sandbox_policy(&policy, &sandbox_cwd);
|
||||
let network_sandbox_policy =
|
||||
codex_protocol::permissions::NetworkSandboxPolicy::from(&policy);
|
||||
(policy, file_system_sandbox_policy, network_sandbox_policy)
|
||||
}
|
||||
Err(err) => {
|
||||
let error = JSONRPCErrorError {
|
||||
code: INVALID_REQUEST_ERROR_CODE,
|
||||
message: format!("invalid sandbox policy: {err}"),
|
||||
data: None,
|
||||
};
|
||||
self.outgoing.send_error(request, error).await;
|
||||
return;
|
||||
}
|
||||
},
|
||||
None => (
|
||||
self.config.permissions.sandbox_policy.get().clone(),
|
||||
self.config.permissions.file_system_sandbox_policy.clone(),
|
||||
self.config.permissions.network_sandbox_policy,
|
||||
),
|
||||
};
|
||||
let sandbox_policy = codex_protocol::protocol::SandboxPolicy::DangerFullAccess;
|
||||
let file_system_sandbox_policy =
|
||||
codex_protocol::permissions::FileSystemSandboxPolicy::unrestricted();
|
||||
let network_sandbox_policy = codex_protocol::permissions::NetworkSandboxPolicy::Enabled;
|
||||
|
||||
let codex_linux_sandbox_exe = self.arg0_paths.codex_linux_sandbox_exe.clone();
|
||||
let outgoing = self.outgoing.clone();
|
||||
let request_for_task = request.clone();
|
||||
let started_network_proxy_for_task = started_network_proxy;
|
||||
let use_legacy_landlock = self.config.features.use_legacy_landlock();
|
||||
let size = match size.map(crate::command_exec::terminal_size_from_protocol) {
|
||||
Some(Ok(size)) => Some(size),
|
||||
@@ -2250,9 +2192,9 @@ impl CodexMessageProcessor {
|
||||
|
||||
match codex_core::exec::build_exec_request(
|
||||
exec_params,
|
||||
&effective_policy,
|
||||
&effective_file_system_sandbox_policy,
|
||||
effective_network_sandbox_policy,
|
||||
&sandbox_policy,
|
||||
&file_system_sandbox_policy,
|
||||
network_sandbox_policy,
|
||||
&sandbox_cwd,
|
||||
&codex_linux_sandbox_exe,
|
||||
use_legacy_landlock,
|
||||
@@ -2265,7 +2207,7 @@ impl CodexMessageProcessor {
|
||||
request_id: request_for_task,
|
||||
process_id,
|
||||
exec_request,
|
||||
started_network_proxy: started_network_proxy_for_task,
|
||||
started_network_proxy: None,
|
||||
tty,
|
||||
stream_stdin,
|
||||
stream_stdout_stderr,
|
||||
|
||||
@@ -56,7 +56,6 @@ async fn command_exec_without_streams_can_be_terminated() -> Result<()> {
|
||||
cwd: None,
|
||||
env: None,
|
||||
size: None,
|
||||
sandbox_policy: None,
|
||||
})
|
||||
.await?;
|
||||
let terminate_request_id = mcp
|
||||
@@ -108,7 +107,6 @@ async fn command_exec_without_process_id_keeps_buffered_compatibility() -> Resul
|
||||
cwd: None,
|
||||
env: None,
|
||||
size: None,
|
||||
sandbox_policy: None,
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -128,6 +126,55 @@ async fn command_exec_without_process_id_keeps_buffered_compatibility() -> Resul
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn command_exec_ignores_read_only_sandbox_config() -> Result<()> {
|
||||
let server = create_mock_responses_server_sequence_unchecked(Vec::new()).await;
|
||||
let codex_home = TempDir::new()?;
|
||||
create_config_toml(codex_home.path(), &server.uri(), "never")?;
|
||||
let project = TempDir::new()?;
|
||||
let output_path = project.path().join("command-exec-write.txt");
|
||||
let mut mcp = McpProcess::new(codex_home.path()).await?;
|
||||
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
|
||||
|
||||
let command_request_id = mcp
|
||||
.send_command_exec_request(CommandExecParams {
|
||||
command: vec![
|
||||
"sh".to_string(),
|
||||
"-lc".to_string(),
|
||||
"printf 'unsandboxed' > command-exec-write.txt; cat command-exec-write.txt"
|
||||
.to_string(),
|
||||
],
|
||||
process_id: None,
|
||||
tty: false,
|
||||
stream_stdin: false,
|
||||
stream_stdout_stderr: false,
|
||||
output_bytes_cap: None,
|
||||
disable_output_cap: false,
|
||||
disable_timeout: false,
|
||||
timeout_ms: None,
|
||||
cwd: Some(project.path().to_path_buf()),
|
||||
env: None,
|
||||
size: None,
|
||||
})
|
||||
.await?;
|
||||
|
||||
let response = mcp
|
||||
.read_stream_until_response_message(RequestId::Integer(command_request_id))
|
||||
.await?;
|
||||
let response: CommandExecResponse = to_response(response)?;
|
||||
assert_eq!(
|
||||
response,
|
||||
CommandExecResponse {
|
||||
exit_code: 0,
|
||||
stdout: "unsandboxed".to_string(),
|
||||
stderr: String::new(),
|
||||
}
|
||||
);
|
||||
assert_eq!(std::fs::read_to_string(output_path)?, "unsandboxed");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn command_exec_env_overrides_merge_with_server_environment_and_support_unset() -> Result<()>
|
||||
{
|
||||
@@ -166,7 +213,6 @@ async fn command_exec_env_overrides_merge_with_server_environment_and_support_un
|
||||
("RUST_LOG".to_string(), None),
|
||||
])),
|
||||
size: None,
|
||||
sandbox_policy: None,
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -208,7 +254,6 @@ async fn command_exec_rejects_disable_timeout_with_timeout_ms() -> Result<()> {
|
||||
cwd: None,
|
||||
env: None,
|
||||
size: None,
|
||||
sandbox_policy: None,
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -245,7 +290,6 @@ async fn command_exec_rejects_disable_output_cap_with_output_bytes_cap() -> Resu
|
||||
cwd: None,
|
||||
env: None,
|
||||
size: None,
|
||||
sandbox_policy: None,
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -282,7 +326,6 @@ async fn command_exec_rejects_negative_timeout_ms() -> Result<()> {
|
||||
cwd: None,
|
||||
env: None,
|
||||
size: None,
|
||||
sandbox_policy: None,
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -319,7 +362,6 @@ async fn command_exec_without_process_id_rejects_streaming() -> Result<()> {
|
||||
cwd: None,
|
||||
env: None,
|
||||
size: None,
|
||||
sandbox_policy: None,
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -360,7 +402,6 @@ async fn command_exec_non_streaming_respects_output_cap() -> Result<()> {
|
||||
cwd: None,
|
||||
env: None,
|
||||
size: None,
|
||||
sandbox_policy: None,
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -407,7 +448,6 @@ async fn command_exec_streaming_does_not_buffer_output() -> Result<()> {
|
||||
cwd: None,
|
||||
env: None,
|
||||
size: None,
|
||||
sandbox_policy: None,
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -470,7 +510,6 @@ async fn command_exec_pipe_streams_output_and_accepts_write() -> Result<()> {
|
||||
cwd: None,
|
||||
env: None,
|
||||
size: None,
|
||||
sandbox_policy: None,
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -545,7 +584,6 @@ async fn command_exec_tty_implies_streaming_and_reports_pty_output() -> Result<(
|
||||
cwd: None,
|
||||
env: None,
|
||||
size: None,
|
||||
sandbox_policy: None,
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -618,7 +656,6 @@ async fn command_exec_tty_supports_initial_size_and_resize() -> Result<()> {
|
||||
rows: 31,
|
||||
cols: 101,
|
||||
}),
|
||||
sandbox_policy: None,
|
||||
})
|
||||
.await?;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user