Exec-Freigaben

Exec-Freigaben sind die Companion-App / Node-Host-Sicherheitsschranke, die einem Agent in der Sandbox erlaubt, Befehle auf einem echten Host (gateway oder node) auszuführen. Stell dir das wie eine Sicherheitsverriegelung vor: Befehle werden nur ausgeführt, wenn Policy + Allowlist + (optional) Benutzerfreigabe alle zustimmen.

Exec-Freigaben kommen zusätzlich zur Tool-Policy und Elevated-Gating (außer wenn elevated auf full gesetzt ist, dann werden Freigaben übersprungen).

Die effektive Policy ist die strengere von tools.exec.* und den Freigabe-Defaults. Wenn ein Freigabe-Feld fehlt, wird der tools.exec-Wert verwendet.

Wenn die Companion-App-UI nicht verfügbar ist, wird jede Anfrage, die einen Prompt erfordert, durch den Ask-Fallback aufgelöst (Standard: deny).

Wo es gilt

Exec-Freigaben werden lokal auf dem Ausführungs-Host durchgesetzt:

  • Gateway-Hostopenclaw-Prozess auf der Gateway-Maschine
  • Node-Host → Node-Runner (macOS Companion-App oder Headless-Node-Host)

macOS-Aufteilung:

  • Node-Host-Service leitet system.run über lokales IPC an die macOS-App weiter.
  • macOS-App setzt Freigaben durch + führt den Befehl im UI-Kontext aus.

Einstellungen und Speicherung

Freigaben liegen in einer lokalen JSON-Datei auf dem Ausführungs-Host:

~/.openclaw/exec-approvals.json

Beispiel-Schema:

{
  "version": 1,
  "socket": {
    "path": "~/.openclaw/exec-approvals.sock",
    "token": "base64url-token"
  },
  "defaults": {
    "security": "deny",
    "ask": "on-miss",
    "askFallback": "deny",
    "autoAllowSkills": false
  },
  "agents": {
    "main": {
      "security": "allowlist",
      "ask": "on-miss",
      "askFallback": "deny",
      "autoAllowSkills": true,
      "allowlist": [
        {
          "id": "B0C8C0B3-2C2D-4F8A-9A3C-5A4B3C2D1E0F",
          "pattern": "~/Projects/**/bin/rg",
          "lastUsedAt": 1737150000000,
          "lastUsedCommand": "rg -n TODO",
          "lastResolvedPath": "/Users/user/Projects/.../bin/rg"
        }
      ]
    }
  }
}

Policy-Einstellungen

Security (exec.security)

  • deny: Blockiert alle Host-Exec-Anfragen.
  • allowlist: Erlaubt nur Befehle auf der Allowlist.
  • full: Erlaubt alles (entspricht elevated).

Ask (exec.ask)

  • off: Nie nachfragen.
  • on-miss: Nur nachfragen, wenn die Allowlist nicht passt.
  • always: Bei jedem Befehl nachfragen.

Ask-Fallback (askFallback)

Wenn ein Prompt erforderlich ist, aber keine UI erreichbar ist, entscheidet der Fallback:

  • deny: Blockieren.
  • allowlist: Nur erlauben, wenn die Allowlist passt.
  • full: Erlauben.

Allowlist (pro Agent)

Allowlists sind pro Agent. Wenn mehrere Agents existieren, wechsle in der macOS-App, welchen Agent du bearbeitest. Patterns sind case-insensitive Glob-Matches.

Patterns sollten zu Binary-Pfaden auflösen (Einträge nur mit Basename werden ignoriert).

Legacy-Einträge agents.default werden beim Laden zu agents.main migriert.

Beispiele:

  • ~/Projects/**/bin/bird
  • ~/.local/bin/*
  • /opt/homebrew/bin/rg

Jeder Allowlist-Eintrag speichert:

  • id – stabile UUID für UI-Identität (optional)
  • last used – Zeitstempel
  • last used command – zuletzt verwendeter Befehl
  • last resolved path – zuletzt aufgelöster Pfad

Auto-Allow für Skill-CLIs

Wenn Auto-allow skill CLIs aktiviert ist, werden ausführbare Dateien, die von bekannten Skills referenziert werden, auf Nodes (macOS-Node oder Headless-Node-Host) als allowlisted behandelt. Das nutzt skills.bins über Gateway-RPC, um die Skill-Bin-Liste abzurufen. Deaktiviere das, wenn du strikte manuelle Allowlists willst.

Safe Bins (nur stdin)

tools.exec.safeBins definiert eine kleine Liste von stdin-only Binaries (z. B. jq), die im Allowlist-Modus ohne explizite Allowlist-Einträge laufen können. Safe Bins lehnen positionelle Datei-Args und pfadähnliche Tokens ab, sodass sie nur auf dem eingehenden Stream arbeiten können.

Shell-Chaining und Redirections werden im Allowlist-Modus nicht automatisch erlaubt.

Shell-Chaining (&&, ||, ;) ist erlaubt, wenn jedes Top-Level-Segment die Allowlist erfüllt (einschließlich Safe Bins oder Skill-Auto-Allow). Redirections bleiben im Allowlist-Modus nicht unterstützt.

Standard-Safe-Bins: jq, grep, cut, sort, uniq, head, tail, tr, wc.

Bearbeiten in der Control-UI

Nutze die Control UI → Nodes → Exec approvals-Karte, um Defaults, Agent-spezifische Overrides und Allowlists zu bearbeiten. Wähle einen Scope (Defaults oder einen Agent), passe die Policy an, füge Allowlist-Patterns hinzu/entferne sie und klicke dann auf Save. Die UI zeigt last used-Metadaten pro Pattern, damit du die Liste aufgeräumt halten kannst.

Der Target-Selector wählt Gateway (lokale Freigaben) oder einen Node. Nodes müssen system.execApprovals.get/set anbieten (macOS-App oder Headless-Node-Host).

Wenn ein Node noch keine Exec-Freigaben anbietet, bearbeite seine lokale ~/.openclaw/exec-approvals.json direkt.

CLI: openclaw approvals unterstützt Gateway- oder Node-Bearbeitung (siehe Approvals CLI).

Freigabe-Ablauf

Wenn ein Prompt erforderlich ist, sendet das Gateway exec.approval.requested an Operator-Clients. Die Control-UI und macOS-App lösen das über exec.approval.resolve auf, dann leitet das Gateway die freigegebene Anfrage an den Node-Host weiter.

Wenn Freigaben erforderlich sind, gibt das Exec-Tool sofort eine Approval-ID zurück. Nutze diese ID, um spätere System-Events zu korrelieren (Exec finished / Exec denied). Wenn vor dem Timeout keine Entscheidung eintrifft, wird die Anfrage als Approval-Timeout behandelt und als Ablehnungsgrund angezeigt.

Der Bestätigungsdialog enthält:

  • Befehl + Args
  • cwd
  • Agent-ID
  • aufgelöster ausführbarer Pfad
  • Host + Policy-Metadaten

Aktionen:

  • Allow once → jetzt ausführen
  • Always allow → zur Allowlist hinzufügen + ausführen
  • Deny → blockieren

Freigabe-Weiterleitung an Chat-Channels

Du kannst Exec-Freigabe-Prompts an jeden Chat-Channel (einschließlich Plugin-Channels) weiterleiten und sie mit /approve freigeben. Das nutzt die normale Outbound-Delivery-Pipeline.

Config:

{
  approvals: {
    exec: {
      enabled: true,
      mode: "session", // "session" | "targets" | "both"
      agentFilter: ["main"],
      sessionFilter: ["discord"], // substring oder regex
      targets: [
        { channel: "slack", to: "U12345678" },
        { channel: "telegram", to: "123456789" },
      ],
    },
  },
}

Antwort im Chat:

/approve <id> allow-once
/approve <id> allow-always
/approve <id> deny

macOS-IPC-Flow

Gateway -> Node Service (WS)
                 |  IPC (UDS + token + HMAC + TTL)
                 v
             Mac App (UI + approvals + system.run)

Sicherheitshinweise:

  • Unix-Socket-Modus 0600, Token gespeichert in exec-approvals.json.
  • Same-UID-Peer-Check.
  • Challenge/Response (Nonce + HMAC-Token + Request-Hash) + kurze TTL.

System-Events

Der Exec-Lifecycle wird als System-Messages angezeigt:

  • Exec running (nur wenn der Befehl den Running-Notice-Threshold überschreitet)
  • Exec finished
  • Exec denied

Diese werden in der Session des Agents gepostet, nachdem der Node das Event meldet.

Gateway-Host-Exec-Freigaben senden dieselben Lifecycle-Events, wenn der Befehl fertig ist (und optional, wenn er länger als der Threshold läuft).

Approval-gated Execs verwenden die Approval-ID als runId in diesen Messages zur einfachen Korrelation.

Auswirkungen

  • full ist mächtig – bevorzuge Allowlists, wenn möglich.
  • ask hält dich auf dem Laufenden und erlaubt trotzdem schnelle Freigaben.
  • Agent-spezifische Allowlists verhindern, dass die Freigaben eines Agents auf andere überlaufen.
  • Freigaben gelten nur für Host-Exec-Anfragen von autorisierten Sendern. Nicht autorisierte Sender können kein /exec ausführen.
  • /exec security=full ist eine Session-Level-Convenience für autorisierte Operatoren und überspringt Freigaben by Design. Um Host-Exec komplett zu blockieren, setze die Freigabe-Security auf deny oder verweigere das exec-Tool über die Tool-Policy.

Verwandte Themen: