-
Notifications
You must be signed in to change notification settings - Fork 6.7k
Elevated Sandbox 2 #7792
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
Elevated Sandbox 2 #7792
Conversation
iceweasel-oai
commented
Dec 9, 2025
- DPAPI helpers for storing Sandbox user passwords securely
- creation of Offline/Online sandbox users
- ACL setup for sandbox users
- firewall rule setup
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
c483107 to
a7e1dd6
Compare
|
@codex review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| let offline_blob = dpapi_protect(offline_pwd.as_bytes())?; | ||
| let online_blob = dpapi_protect(online_pwd.as_bytes())?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DPAPI blobs unusable for non-admin caller
Sandbox passwords are encrypted in the elevated helper with dpapi_protect (CryptProtectData default scope) and written to sandbox_users.json, but later are decrypted in identity::decode_password using dpapi::unprotect under the invoking user’s profile. If the setup runs via UAC with alternate admin credentials (a common case for non-admin users), the DPAPI blobs are bound to that admin account and cannot be decrypted by the original caller, so sandbox credential loading will consistently fail even though setup succeeded. Consider encrypting with machine scope or otherwise ensuring the same user context is used for both protect/unprotect.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@iceweasel-oai, this looks like a legit bug.
etraut-openai
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this looks reasonable overall. I left a few comments and questions to consider. Before this functionality ships:
- I think the "marker file" mechanism should be removed. It seems unnecessary and will result in a long tail of support issues if it's left in.
- Like the current sandbox mechanism, this implementation "bleeds" access rights across instances of the CLI and extension. For example, if you start two instances of the CLI in two different directories, they will have write access to each other's workspace directory, but they shouldn't. At a minimum, this should be documented. Ideally, it should be fixed.
- We're currently adding DACLs and allocating users, but we never clean up these artifacts. Since there's no uninstaller, these are left on the user's machine, contributing to system rot. We should think about ways to mitigate this.
- Since the new mechanism involves escalation, I think it needs to go through a thorough security review and preferably include a formal threat model.
| /// command should be run privileged outside the sandbox. | ||
| // Flaky: failing on some runners due to codex-linux-sandbox not being present. | ||
| #[ignore] | ||
| #[tokio::test(flavor = "current_thread")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bolinfest has been working to fix for this, so this can be removed.
| let offline_blob = dpapi_protect(offline_pwd.as_bytes())?; | ||
| let online_blob = dpapi_protect(online_pwd.as_bytes())?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@iceweasel-oai, this looks like a legit bug.
| pub password: String, | ||
| } | ||
|
|
||
| fn load_marker(codex_home: &Path) -> Result<Option<SetupMarker>> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This "marker file" approach strikes me as overly complicated and fragile. I think we can eliminate this entirely. Can't we just run checks at startup that validate that the appropriate ACLs are in place and elevate if we need to? This seems like a much more robust and self-healing approach.
| let users = SandboxUsersFile { | ||
| version: SETUP_VERSION, | ||
| offline: SandboxUserRecord { | ||
| username: offline_user.to_string(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like the usernames for the two accounts are constants. Is there a reason we're storing them to the file?
| let ret = real_main(); | ||
| if let Err(e) = &ret { | ||
| // Best-effort: log unexpected top-level errors. | ||
| if let Ok(codex_home) = std::env::var("CODEX_HOME") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How will these errors be relayed to the end user in a way that they can understand the problem and take action?
| ret | ||
| } | ||
|
|
||
| fn real_main() -> Result<()> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there perhaps a better name for this function?
dcc0ef9 to
6aa57a5
Compare