self review

Signed-off-by: Matthew Grossman <mgrossman@nvidia.com>
This commit is contained in:
Matthew Grossman
2026-07-23 14:27:59 -07:00
parent 5cc88bfce3
commit 0b74fdcc17
2 changed files with 17 additions and 8 deletions
+3 -2
View File
@@ -25,8 +25,9 @@ The compute runtime selects the agent's numeric UID and GID; sandbox creators
do not control it. Docker and Podman start the supervisor as root, inject the
driver-resolved identity, and the supervisor drops only the agent child to that
identity. A container image therefore need not contain a matching passwd or
group entry. Agent children receive a stable `HOME=/sandbox`; numeric identities
use the UID as their `USER` and `LOGNAME` presentation value.
group entry. The managed workspace remains mounted at `/sandbox` and serves as
the agent's home regardless of its identity; numeric identities use the UID as
their `USER` and `LOGNAME` presentation value.
## Startup Flow
@@ -80,6 +80,8 @@ const SUPERVISOR_ONLY_ENV_VARS: &[&str] = &[
openshell_core::sandbox_env::PROVIDER_SPIFFE_WORKLOAD_API_SOCKET,
];
const SANDBOX_HOME: &str = "/sandbox";
pub fn is_supervisor_only_env_var(key: &str) -> bool {
SUPERVISOR_ONLY_ENV_VARS.contains(&key)
}
@@ -861,11 +863,12 @@ impl ProcessHandle {
/// Derive the presentation identity and home directory for an agent child.
///
/// Numeric identities intentionally do not require an NSS entry, so they use
/// `/sandbox` as their stable home while retaining the numeric UID as USER.
/// the managed workspace as their stable home while retaining the numeric UID
/// as USER.
pub(crate) fn child_user_and_home(policy: &SandboxPolicy) -> (String, String) {
match policy.process.run_as_user.as_deref() {
Some(user) if !user.is_empty() && user.parse::<u32>().is_ok() => {
(user.to_string(), "/sandbox".to_string())
(user.to_string(), SANDBOX_HOME.to_string())
}
Some(user) if !user.is_empty() => {
let home = User::from_name(user).ok().flatten().map_or_else(
@@ -874,7 +877,7 @@ pub(crate) fn child_user_and_home(policy: &SandboxPolicy) -> (String, String) {
);
(user.to_string(), home)
}
_ => ("sandbox".to_string(), "/sandbox".to_string()),
_ => ("sandbox".to_string(), SANDBOX_HOME.to_string()),
}
}
@@ -1146,7 +1149,7 @@ fn rewrite_passwd_at(path: &Path, uid: &str, gid: &str) -> Result<()> {
.collect();
if !found {
lines.push(format!("sandbox:x:{uid}:{gid}::/sandbox:/bin/sh"));
lines.push(format!("sandbox:x:{uid}:{gid}::{SANDBOX_HOME}:/bin/sh"));
}
let mut output = lines.join("\n");
@@ -1340,9 +1343,14 @@ pub fn prepare_filesystem(policy: &SandboxPolicy) -> Result<()> {
// Recursively chown /sandbox so the sandbox process can use its home
// directory.
if std::env::var(openshell_core::sandbox_env::SANDBOX_UID).is_ok() {
let sandbox_home = Path::new("/sandbox");
let sandbox_home = Path::new(SANDBOX_HOME);
if sandbox_home.exists() {
info!(?uid, ?gid, "Chowning /sandbox for driver-injected UID/GID");
info!(
path = SANDBOX_HOME,
?uid,
?gid,
"Chowning sandbox home for driver-injected UID/GID"
);
chown_sandbox_home(sandbox_home, uid, gid)?;
}
}