mirror of
https://github.com/openai/codex.git
synced 2026-04-30 09:26:44 +00:00
## Stack 1. Base PR: #18443 stops granting ACLs on `USERPROFILE`. 2. This PR: filters additional SSH-owned profile roots discovered from SSH config. ## Bug The base PR removes the broadest bad grant: `USERPROFILE` itself. That still leaves one important case. A user profile child can be SSH-owned even when its name is not one of our fixed exclusions. For example: ```sshconfig Host devbox IdentityFile ~/.keys/devbox CertificateFile ~/.certs/devbox-cert.pub UserKnownHostsFile ~/.known_hosts_custom Include ~/.ssh/conf.d/*.conf ``` After profile expansion, the sandbox might see these as normal profile children: ```text C:\Users\me\.keys C:\Users\me\.certs C:\Users\me\.known_hosts_custom C:\Users\me\.ssh ``` Those paths have another owner: OpenSSH and the tools that manage SSH identity and host-key state. Codex should not add sandbox ACLs to them. OpenSSH describes this dependency tree in [`ssh_config(5)`](https://man.openbsd.org/ssh_config.5), and the client parser follows the same shape in `readconf.c`: - `Include` recursively reads more config files and expands globs - `IdentityFile` and `CertificateFile` name authentication files - `UserKnownHostsFile`, `GlobalKnownHostsFile`, and `RevokedHostKeys` name host-key files - `ControlPath` and `IdentityAgent` can name profile-owned sockets or control files - these path directives can use forms such as `~`, `%d`, and `${HOME}` ## Change This PR adds a small SSH config dependency scanner. It starts at: ```text ~/.ssh/config ``` Then it returns concrete paths named by `Include` and by path-valued SSH config directives: ```text IdentityFile CertificateFile UserKnownHostsFile GlobalKnownHostsFile RevokedHostKeys ControlPath IdentityAgent ``` For example: ```sshconfig IdentityFile ~/.keys/devbox CertificateFile ~/.certs/devbox-cert.pub Include ~/.ssh/conf.d/*.conf ``` returns paths like: ```text C:\Users\me\.keys\devbox C:\Users\me\.certs\devbox-cert.pub C:\Users\me\.ssh\conf.d\devbox.conf ``` The setup code then maps those paths back to their top-level `USERPROFILE` child and filters matching sandbox roots out of both the writable and readable root lists. ## Why this shape The parser reports what SSH config references. The sandbox setup code decides which `USERPROFILE` roots are unsafe to grant. That keeps the policy simple: 1. expand broad profile grants 2. remove the profile root 3. remove fixed sensitive profile folders 4. remove profile folders referenced by SSH config dependencies If a path has two possible owners, the sandbox steps back. SSH keeps control of SSH config, keys, certificates, known-hosts files, sockets, and included config files. ## Tests - `cargo test -p codex-windows-sandbox --lib` - `just bazel-lock-check` - `just fix -p codex-windows-sandbox` - `git diff --check`
98 lines
2.3 KiB
TOML
98 lines
2.3 KiB
TOML
[package]
|
|
build = "build.rs"
|
|
edition.workspace = true
|
|
license.workspace = true
|
|
name = "codex-windows-sandbox"
|
|
version.workspace = true
|
|
|
|
[lib]
|
|
name = "codex_windows_sandbox"
|
|
path = "src/lib.rs"
|
|
|
|
[[bin]]
|
|
name = "codex-windows-sandbox-setup"
|
|
path = "src/bin/setup_main.rs"
|
|
|
|
[[bin]]
|
|
name = "codex-command-runner"
|
|
path = "src/bin/command_runner.rs"
|
|
|
|
[lints]
|
|
workspace = true
|
|
|
|
[dependencies]
|
|
anyhow = "1.0"
|
|
base64 = { workspace = true }
|
|
chrono = { version = "0.4.42", default-features = false, features = [
|
|
"clock",
|
|
"std",
|
|
] }
|
|
codex-utils-pty = { workspace = true }
|
|
codex-utils-absolute-path = { workspace = true }
|
|
codex-utils-string = { workspace = true }
|
|
dunce = "1.0"
|
|
glob = { workspace = true }
|
|
serde = { version = "1.0", features = ["derive"] }
|
|
serde_json = "1.0"
|
|
tempfile = "3"
|
|
tokio = { workspace = true, features = ["sync", "rt"] }
|
|
windows = { version = "0.58", features = [
|
|
"Win32_Foundation",
|
|
"Win32_NetworkManagement_WindowsFirewall",
|
|
"Win32_System_Com",
|
|
"Win32_System_Variant",
|
|
] }
|
|
|
|
[dependencies.codex-protocol]
|
|
package = "codex-protocol"
|
|
path = "../protocol"
|
|
|
|
[dependencies.rand]
|
|
default-features = false
|
|
features = ["std", "small_rng"]
|
|
version = "0.8"
|
|
|
|
[dependencies.dirs-next]
|
|
version = "2.0"
|
|
|
|
[target.'cfg(windows)'.dependencies.windows-sys]
|
|
features = [
|
|
"Win32_Foundation",
|
|
"Win32_System_Diagnostics_Debug",
|
|
"Win32_Security",
|
|
"Win32_Security_Authorization",
|
|
"Win32_System_Threading",
|
|
"Win32_System_JobObjects",
|
|
"Win32_System_SystemServices",
|
|
"Win32_System_Environment",
|
|
"Win32_System_Pipes",
|
|
"Win32_System_WindowsProgramming",
|
|
"Win32_System_IO",
|
|
"Win32_System_Memory",
|
|
"Win32_System_Kernel",
|
|
"Win32_System_Console",
|
|
"Win32_Storage_FileSystem",
|
|
"Win32_System_Diagnostics_ToolHelp",
|
|
"Win32_NetworkManagement_NetManagement",
|
|
"Win32_Networking_WinSock",
|
|
"Win32_System_LibraryLoader",
|
|
"Win32_System_Com",
|
|
"Win32_Security_Cryptography",
|
|
"Win32_Security_Authentication_Identity",
|
|
"Win32_Graphics_Gdi",
|
|
"Win32_System_StationsAndDesktops",
|
|
"Win32_UI_WindowsAndMessaging",
|
|
"Win32_UI_Shell",
|
|
"Win32_System_Registry",
|
|
]
|
|
version = "0.52"
|
|
|
|
[dev-dependencies]
|
|
pretty_assertions = { workspace = true }
|
|
|
|
[build-dependencies]
|
|
winres = "0.1"
|
|
|
|
[package.metadata.cargo-shear]
|
|
ignored = ["codex-utils-pty", "tokio"]
|