mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-19 17:28:37 +00:00
fix(macos): consolidate exec approval evaluation
This commit is contained in:
@@ -441,48 +441,25 @@ actor MacNodeRuntime {
|
||||
guard !command.isEmpty else {
|
||||
return Self.errorResponse(req, code: .invalidRequest, message: "INVALID_REQUEST: command required")
|
||||
}
|
||||
let displayCommand = ExecCommandFormatter.displayString(for: command, rawCommand: params.rawCommand)
|
||||
|
||||
let trimmedAgent = params.agentId?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
|
||||
let agentId = trimmedAgent.isEmpty ? nil : trimmedAgent
|
||||
let approvals = ExecApprovalsStore.resolve(agentId: agentId)
|
||||
let security = approvals.agent.security
|
||||
let ask = approvals.agent.ask
|
||||
let autoAllowSkills = approvals.agent.autoAllowSkills
|
||||
let sessionKey = (params.sessionKey?.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty == false)
|
||||
? params.sessionKey!.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
: self.mainSessionKey
|
||||
let runId = UUID().uuidString
|
||||
let env = Self.sanitizedEnv(params.env)
|
||||
let allowlistResolutions = ExecCommandResolution.resolveForAllowlist(
|
||||
let evaluation = await ExecApprovalEvaluator.evaluate(
|
||||
command: command,
|
||||
rawCommand: params.rawCommand,
|
||||
cwd: params.cwd,
|
||||
env: env)
|
||||
let resolution = allowlistResolutions.first
|
||||
let allowlistMatches = security == .allowlist
|
||||
? ExecAllowlistMatcher.matchAll(entries: approvals.allowlist, resolutions: allowlistResolutions)
|
||||
: []
|
||||
let allowlistSatisfied = security == .allowlist &&
|
||||
!allowlistResolutions.isEmpty &&
|
||||
allowlistMatches.count == allowlistResolutions.count
|
||||
let allowlistMatch = allowlistSatisfied ? allowlistMatches.first : nil
|
||||
let skillAllow: Bool
|
||||
if autoAllowSkills, !allowlistResolutions.isEmpty {
|
||||
let bins = await SkillBinsCache.shared.currentBins()
|
||||
skillAllow = allowlistResolutions.allSatisfy { bins.contains($0.executableName) }
|
||||
} else {
|
||||
skillAllow = false
|
||||
}
|
||||
envOverrides: params.env,
|
||||
agentId: params.agentId)
|
||||
|
||||
if security == .deny {
|
||||
if evaluation.security == .deny {
|
||||
await self.emitExecEvent(
|
||||
"exec.denied",
|
||||
payload: ExecEventPayload(
|
||||
sessionKey: sessionKey,
|
||||
runId: runId,
|
||||
host: "node",
|
||||
command: displayCommand,
|
||||
command: evaluation.displayCommand,
|
||||
reason: "security=deny"))
|
||||
return Self.errorResponse(
|
||||
req,
|
||||
@@ -494,13 +471,13 @@ actor MacNodeRuntime {
|
||||
req: req,
|
||||
params: params,
|
||||
context: ExecRunContext(
|
||||
displayCommand: displayCommand,
|
||||
security: security,
|
||||
ask: ask,
|
||||
agentId: agentId,
|
||||
resolution: resolution,
|
||||
allowlistMatch: allowlistMatch,
|
||||
skillAllow: skillAllow,
|
||||
displayCommand: evaluation.displayCommand,
|
||||
security: evaluation.security,
|
||||
ask: evaluation.ask,
|
||||
agentId: evaluation.agentId,
|
||||
resolution: evaluation.resolution,
|
||||
allowlistMatch: evaluation.allowlistMatch,
|
||||
skillAllow: evaluation.skillAllow,
|
||||
sessionKey: sessionKey,
|
||||
runId: runId))
|
||||
if let response = approval.response { return response }
|
||||
@@ -508,19 +485,19 @@ actor MacNodeRuntime {
|
||||
let persistAllowlist = approval.persistAllowlist
|
||||
self.persistAllowlistPatterns(
|
||||
persistAllowlist: persistAllowlist,
|
||||
security: security,
|
||||
agentId: agentId,
|
||||
security: evaluation.security,
|
||||
agentId: evaluation.agentId,
|
||||
command: command,
|
||||
allowlistResolutions: allowlistResolutions)
|
||||
allowlistResolutions: evaluation.allowlistResolutions)
|
||||
|
||||
if security == .allowlist, !allowlistSatisfied, !skillAllow, !approvedByAsk {
|
||||
if evaluation.security == .allowlist, !evaluation.allowlistSatisfied, !evaluation.skillAllow, !approvedByAsk {
|
||||
await self.emitExecEvent(
|
||||
"exec.denied",
|
||||
payload: ExecEventPayload(
|
||||
sessionKey: sessionKey,
|
||||
runId: runId,
|
||||
host: "node",
|
||||
command: displayCommand,
|
||||
command: evaluation.displayCommand,
|
||||
reason: "allowlist-miss"))
|
||||
return Self.errorResponse(
|
||||
req,
|
||||
@@ -529,19 +506,19 @@ actor MacNodeRuntime {
|
||||
}
|
||||
|
||||
self.recordAllowlistMatches(
|
||||
security: security,
|
||||
allowlistSatisfied: allowlistSatisfied,
|
||||
agentId: agentId,
|
||||
allowlistMatches: allowlistMatches,
|
||||
allowlistResolutions: allowlistResolutions,
|
||||
displayCommand: displayCommand)
|
||||
security: evaluation.security,
|
||||
allowlistSatisfied: evaluation.allowlistSatisfied,
|
||||
agentId: evaluation.agentId,
|
||||
allowlistMatches: evaluation.allowlistMatches,
|
||||
allowlistResolutions: evaluation.allowlistResolutions,
|
||||
displayCommand: evaluation.displayCommand)
|
||||
|
||||
if let permissionResponse = await self.validateScreenRecordingIfNeeded(
|
||||
req: req,
|
||||
needsScreenRecording: params.needsScreenRecording,
|
||||
sessionKey: sessionKey,
|
||||
runId: runId,
|
||||
displayCommand: displayCommand)
|
||||
displayCommand: evaluation.displayCommand)
|
||||
{
|
||||
return permissionResponse
|
||||
}
|
||||
@@ -550,10 +527,10 @@ actor MacNodeRuntime {
|
||||
req: req,
|
||||
params: params,
|
||||
command: command,
|
||||
env: env,
|
||||
env: evaluation.env,
|
||||
sessionKey: sessionKey,
|
||||
runId: runId,
|
||||
displayCommand: displayCommand)
|
||||
displayCommand: evaluation.displayCommand)
|
||||
}
|
||||
|
||||
private func handleSystemWhich(_ req: BridgeInvokeRequest) async throws -> BridgeInvokeResponse {
|
||||
@@ -947,10 +924,6 @@ extension MacNodeRuntime {
|
||||
UserDefaults.standard.object(forKey: cameraEnabledKey) as? Bool ?? false
|
||||
}
|
||||
|
||||
private static func sanitizedEnv(_ overrides: [String: String]?) -> [String: String] {
|
||||
HostEnvSanitizer.sanitize(overrides: overrides)
|
||||
}
|
||||
|
||||
private nonisolated static func locationMode() -> OpenClawLocationMode {
|
||||
let raw = UserDefaults.standard.string(forKey: locationModeKey) ?? "off"
|
||||
return OpenClawLocationMode(rawValue: raw) ?? .off
|
||||
|
||||
Reference in New Issue
Block a user