File zeroclaw-git-ops-security-policy.patch of Package zeroclaw

commit 162050dafa9dac5cd0b607cf8766b2f39f32362c
Author: Oleksandr Ostrenko <openbuildservice@ostrenko.dev>
Date:   Sat Mar 28 16:13:05 2026 +0100

    Use security policy when evaluating git paths

diff --git a/src/tools/git_operations.rs b/src/tools/git_operations.rs
index 75d3d2b3b..20f74952f 100644
--- a/src/tools/git_operations.rs
+++ b/src/tools/git_operations.rs
@@ -67,7 +67,7 @@ impl GitOperationsTool {
 
     /// Resolve a user-provided path to an absolute path within the workspace.
     /// Returns the workspace_dir if no path is provided.
-    /// Rejects paths that escape the workspace via traversal.
+    /// Rejects paths that based on the security policy (`is_resolved_path_allowed`).
     fn resolve_working_dir(&self, path: Option<&str>) -> anyhow::Result<std::path::PathBuf> {
         let base = match path {
             Some(p) if !p.is_empty() => {
@@ -76,16 +76,26 @@ impl GitOperationsTool {
                 } else {
                     self.workspace_dir.join(p)
                 };
+
                 let resolved = candidate
                     .canonicalize()
                     .map_err(|e| anyhow::anyhow!("Cannot resolve path '{}': {}", p, e))?;
-                let workspace_canonical = self
-                    .workspace_dir
-                    .canonicalize()
-                    .unwrap_or_else(|_| self.workspace_dir.clone());
-                if !resolved.starts_with(&workspace_canonical) {
-                    anyhow::bail!("Path '{}' resolves outside the workspace directory", p);
+
+                if !resolved.is_dir() {
+                    anyhow::bail!("project_path must be a directory: {}", resolved.display());
                 }
+
+                // Security policy check using the string representation.
+                if !self
+                    .security
+                    .is_resolved_path_allowed(resolved.as_ref())
+                {
+                    anyhow::bail!(
+                        "project_path is outside the allowed roots: {}",
+                        resolved.display()
+                    );
+                }
+
                 resolved
             }
             _ => self.workspace_dir.clone(),
openSUSE Build Service is sponsored by