add elevated flag to shell and callPromotedTool; thread through to executeElevated

This commit is contained in:
ollie 2026-07-29 00:41:40 +02:00
parent 9ea56242c3
commit d5c591ad26
2 changed files with 32 additions and 11 deletions

View File

@ -139,9 +139,10 @@ func (lw *limitedWriter) Write(p []byte) (n int, err error) {
// dispatchShell handles the shell tool: a single bash command.
func dispatchShell(ctx context.Context, e *Server, args json.RawMessage) (string, error) {
var a struct {
Cmd string `json:"cmd"`
Timeout int `json:"timeout"`
Sandbox string `json:"sandbox"`
Cmd string `json:"cmd"`
Timeout int `json:"timeout"`
Sandbox string `json:"sandbox"`
Elevated bool `json:"elevated"`
}
if err := json.Unmarshal(args, &a); err != nil {
return "", fmt.Errorf("shell: bad args: %w", err)
@ -153,6 +154,12 @@ func dispatchShell(ctx context.Context, e *Server, args json.RawMessage) (string
if timeout <= 0 {
timeout = 30
}
if a.Elevated {
e.wdMu.RLock()
workDir := e.cwd
e.wdMu.RUnlock()
return e.executeElevated(ctx, a.Cmd, workDir, timeout)
}
sandboxName := a.Sandbox
if sandboxName == "" {
sandboxName = "default"

View File

@ -149,9 +149,10 @@ timeout applies to each call (default: 30s). A non-zero exit is an error.`,
"type": "object",
"required": ["cmd"],
"properties": {
"cmd": {"type": "string", "description": "Bash command to execute."},
"timeout": {"type": "integer", "description": "Timeout in seconds (default: 30). Use 0 for no timeout."},
"sandbox": {"type": "string", "description": "Sandbox profile name (default: default)."}
"cmd": {"type": "string", "description": "Bash command to execute."},
"timeout": {"type": "integer", "description": "Timeout in seconds (default: 30). Use 0 for no timeout."},
"sandbox": {"type": "string", "description": "Sandbox profile name (default: default)."},
"elevated": {"type": "boolean", "description": "Run outside the sandbox via elevation broker."}
}
}`),
},
@ -273,7 +274,7 @@ func (e *Server) SetToolRegistry(r *Registry, sessionID string) {
}
// callPromotedTool executes a tool promoted via the registry by running the
// script file directly inside the sandbox.
// script file inside the sandbox, or elevated if the args request it.
func (e *Server) callPromotedTool(ctx context.Context, tool string, args json.RawMessage) (json.RawMessage, error) {
// Resolve script path.
if strings.Contains(tool, "/") || strings.Contains(tool, "..") {
@ -281,8 +282,9 @@ func (e *Server) callPromotedTool(ctx context.Context, tool string, args json.Ra
}
path := filepath.Join(ToolsPath(), tool)
// Parse positional args into a shell command string.
// Parse args — extract positional args and optional elevated flag.
var positional []string
elevated := false
var argMap map[string]interface{}
if err := json.Unmarshal(args, &argMap); err == nil {
if argsArr, ok := argMap["args"]; ok {
@ -292,10 +294,14 @@ func (e *Server) callPromotedTool(ctx context.Context, tool string, args json.Ra
}
}
}
if e, ok := argMap["elevated"]; ok {
if b, ok := e.(bool); ok {
elevated = b
}
}
}
// Build a shell command that runs the tool script with its args.
// Quote each arg for safe shell passing.
quoted := make([]string, 0, len(positional)+1)
quoted = append(quoted, path)
for _, a := range positional {
@ -303,8 +309,16 @@ func (e *Server) callPromotedTool(ctx context.Context, tool string, args json.Ra
}
code := strings.Join(quoted, " ")
// Execute through the sandbox via executeWithStdin.
result, err := e.executeWithStdin(ctx, code, "bash", 30, "default", false, "")
var result string
var err error
if elevated {
e.wdMu.RLock()
workDir := e.cwd
e.wdMu.RUnlock()
result, err = e.executeElevated(ctx, code, workDir, 30)
} else {
result, err = e.executeWithStdin(ctx, code, "bash", 30, "default", false, "")
}
if err != nil {
return json.Marshal(map[string]interface{}{
"isError": true,