fix(permissions): validate network access flow
This commit is contained in:
@ -154,8 +154,12 @@ pub struct CodexExecSession {
|
||||
command: String,
|
||||
/// Répertoire de travail (run dir isolé §14.1).
|
||||
cwd: String,
|
||||
/// Codex CLI sandbox mode passed to `codex exec --sandbox`.
|
||||
sandbox_mode: String,
|
||||
/// Project/workspace roots that must be writable in Codex's CLI sandbox.
|
||||
writable_roots: Vec<String>,
|
||||
/// Structured policy projection of Codex workspace-write sandbox network access.
|
||||
network_access: Option<bool>,
|
||||
/// Variables d'environnement préparées au lancement (ex. `CODEX_HOME` isolé).
|
||||
env: Vec<(String, String)>,
|
||||
/// Id de conversation **du moteur** Codex, capté au premier tour, `None` avant.
|
||||
@ -183,12 +187,44 @@ impl CodexExecSession {
|
||||
env: Vec<(String, String)>,
|
||||
sandbox: Option<SandboxPlan>,
|
||||
sandbox_enforcer: Option<Arc<dyn SandboxEnforcer>>,
|
||||
) -> Self {
|
||||
Self::new_with_policy(
|
||||
id,
|
||||
command,
|
||||
cwd,
|
||||
seed_conversation_id,
|
||||
"workspace-write",
|
||||
writable_roots,
|
||||
None,
|
||||
env,
|
||||
sandbox,
|
||||
sandbox_enforcer,
|
||||
)
|
||||
}
|
||||
|
||||
/// Construit l'adapter avec la politique compatible `codex exec` résolue par
|
||||
/// `LaunchAgent`.
|
||||
#[must_use]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new_with_policy(
|
||||
id: SessionId,
|
||||
command: impl Into<String>,
|
||||
cwd: impl Into<String>,
|
||||
seed_conversation_id: Option<String>,
|
||||
sandbox_mode: impl Into<String>,
|
||||
writable_roots: Vec<String>,
|
||||
network_access: Option<bool>,
|
||||
env: Vec<(String, String)>,
|
||||
sandbox: Option<SandboxPlan>,
|
||||
sandbox_enforcer: Option<Arc<dyn SandboxEnforcer>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
id,
|
||||
command: command.into(),
|
||||
cwd: cwd.into(),
|
||||
sandbox_mode: sandbox_mode.into(),
|
||||
writable_roots,
|
||||
network_access,
|
||||
env,
|
||||
conversation_id: Mutex::new(seed_conversation_id),
|
||||
sandbox,
|
||||
@ -217,28 +253,54 @@ impl CodexExecSession {
|
||||
let conversation_id = self.conversation_id.lock().expect("mutex sain").clone();
|
||||
args.push("--json".to_owned());
|
||||
args.push("--skip-git-repo-check".to_owned());
|
||||
args.push("--sandbox".to_owned());
|
||||
args.push("workspace-write".to_owned());
|
||||
for root in self.writable_roots.iter().filter(|root| !root.is_empty()) {
|
||||
args.push("--add-dir".to_owned());
|
||||
args.push(root.clone());
|
||||
if !self.sandbox_mode.trim().is_empty() {
|
||||
args.push("--sandbox".to_owned());
|
||||
args.push(self.sandbox_mode.clone());
|
||||
}
|
||||
if self.sandbox_mode == "workspace-write" {
|
||||
for root in self.writable_roots.iter().filter(|root| !root.is_empty()) {
|
||||
args.push("--add-dir".to_owned());
|
||||
args.push(root.clone());
|
||||
}
|
||||
}
|
||||
if let Some(network_access) = self.network_access {
|
||||
args.push("-c".to_owned());
|
||||
args.push(format!(
|
||||
"sandbox_workspace_write.network_access={network_access}"
|
||||
));
|
||||
}
|
||||
if let Some(id) = conversation_id {
|
||||
args.push("resume".to_owned());
|
||||
args.push(id);
|
||||
}
|
||||
args.push(prompt.to_owned());
|
||||
let mut env = self.env.clone();
|
||||
if let Some(network_access) = self.network_access {
|
||||
upsert_env(
|
||||
&mut env,
|
||||
"CODEX_SANDBOX_NETWORK_DISABLED",
|
||||
if network_access { "0" } else { "1" },
|
||||
);
|
||||
}
|
||||
SpawnLine {
|
||||
command: self.command.clone(),
|
||||
args,
|
||||
cwd: self.cwd.clone(),
|
||||
env: self.env.clone(),
|
||||
env,
|
||||
stdin: None,
|
||||
sandbox: self.sandbox.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn upsert_env(env: &mut Vec<(String, String)>, key: &str, value: &str) {
|
||||
if let Some((_, existing)) = env.iter_mut().find(|(k, _)| k == key) {
|
||||
*existing = value.to_owned();
|
||||
} else {
|
||||
env.push((key.to_owned(), value.to_owned()));
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl AgentSession for CodexExecSession {
|
||||
fn id(&self) -> SessionId {
|
||||
|
||||
Reference in New Issue
Block a user