Aprobaciones de ejecución

Las aprobaciones de ejecución son la salvaguarda de la app complementaria / node host para permitir que un agente en sandbox ejecute comandos en un host real (gateway o node). Piénsalo como un interbloqueo de seguridad: los comandos se permiten solo cuando la política + lista permitida + (opcional) aprobación del usuario todos coinciden. Las aprobaciones de ejecución son adicionales a la política de herramientas y al control de elevación (a menos que elevated esté establecido en full, que omite las aprobaciones). La política efectiva es la más estricta entre tools.exec.* y los valores por defecto de aprobaciones; si se omite un campo de aprobaciones, se usa el valor de tools.exec.

Si la UI de la app complementaria no está disponible, cualquier solicitud que requiera un prompt se resuelve por el respaldo de ask (por defecto: deny).

Dónde aplica

Las aprobaciones de ejecución se aplican localmente en el host de ejecución:

  • host del gateway -> proceso openclaw en la máquina del gateway
  • node host -> ejecutor del nodo (app complementaria de macOS o node host headless)

Nota sobre el modelo de confianza:

  • Los llamadores autenticados del Gateway son operadores de confianza para ese Gateway.
  • Los nodos emparejados extienden esa capacidad de operador de confianza al node host.
  • Las aprobaciones de ejecución reducen el riesgo de ejecución accidental, pero no son un límite de autenticación por usuario.
  • Las ejecuciones respaldadas por aprobación vinculan contexto de ejecución canónico: cwd canónico, argv exacto, vinculación de env cuando está presente, y ruta ejecutable fijada cuando aplica.
  • Para scripts de shell e invocaciones directas de archivos de intérprete/runtime, OpenClaw también intenta vincular un operando de archivo local concreto. Si ese archivo vinculado cambia después de la aprobación pero antes de la ejecución, la ejecución se deniega en lugar de ejecutar contenido divergente.
  • Esta vinculación de archivo es intencionalmente de mejor esfuerzo, no un modelo semántico completo de cada ruta de cargador de intérprete/runtime. Si el modo de aprobación no puede identificar exactamente un archivo local concreto para vincular, se niega a emitir una ejecución respaldada por aprobación en lugar de pretender cobertura completa.

Separación en macOS:

  • servicio node host reenvía system.run a la app macOS por IPC local.
  • app macOS aplica aprobaciones + ejecuta el comando en contexto de UI.

Configuración y almacenamiento

Las aprobaciones viven en un archivo JSON local en el host de ejecución:

~/.openclaw/exec-approvals.json

Esquema de ejemplo:

{
  "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"
        }
      ]
    }
  }
}

Controles de política

Seguridad (exec.security)

  • deny: bloquear todas las solicitudes de ejecución en host.
  • allowlist: permitir solo comandos en la lista permitida.
  • full: permitir todo (equivalente a elevated).

Ask (exec.ask)

  • off: nunca preguntar.
  • on-miss: preguntar solo cuando la lista permitida no coincide.
  • always: preguntar en cada comando.

Respaldo de ask (askFallback)

Si se requiere un prompt pero no hay UI accesible, el respaldo decide:

  • deny: bloquear.
  • allowlist: permitir solo si la lista permitida coincide.
  • full: permitir.

Lista permitida (por agente)

Las listas permitidas son por agente. Si existen múltiples agentes, cambia el agente que estás editando en la app de macOS. Los patrones son coincidencias glob insensibles a mayúsculas. Los patrones deben resolver a rutas de binarios (las entradas con solo nombre base se ignoran). Las entradas legacy agents.default se migran a agents.main al cargar.

Ejemplos:

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

Cada entrada de la lista permitida rastrea:

  • id UUID estable usado para identidad en la UI (opcional)
  • last used marca de tiempo
  • last used command
  • last resolved path

Auto-permitir CLIs de skills

Cuando Auto-permitir CLIs de skills está habilitado, los ejecutables referenciados por skills conocidos se tratan como permitidos en nodos (nodo macOS o node host headless). Esto usa skills.bins sobre el RPC del Gateway para obtener la lista de binarios de skills. Deshabilita esto si quieres listas permitidas manuales estrictas.

Notas importantes de confianza:

  • Esta es una lista permitida implícita de conveniencia, separada de las entradas manuales de la lista permitida de rutas.
  • Está destinada para entornos de operador de confianza donde el Gateway y el nodo están en el mismo límite de confianza.
  • Si requieres confianza explícita estricta, mantén autoAllowSkills: false y usa solo entradas manuales de la lista permitida de rutas.

Binarios seguros (solo stdin)

tools.exec.safeBins define una pequeña lista de binarios solo stdin (por ejemplo jq) que pueden ejecutarse en modo lista permitida sin entradas explícitas de la lista permitida. Los binarios seguros rechazan argumentos de archivo posicionales y tokens tipo ruta, así que solo pueden operar sobre el flujo entrante. Trata esto como una vía rápida estrecha para filtros de flujo, no una lista de confianza general. No agregues binarios de intérprete o runtime (por ejemplo python3, node, ruby, bash, sh, zsh) a safeBins. Si un comando puede evaluar código, ejecutar subcomandos o leer archivos por diseño, prefiere entradas explícitas de la lista permitida y mantén los prompts de aprobación habilitados. Los binarios seguros personalizados deben definir un perfil explícito en tools.exec.safeBinProfiles.<bin>. La validación es determinística solo desde la forma de argv (sin verificaciones de existencia del filesystem del host), lo que previene comportamiento de oráculo de existencia de archivo por diferencias de allow/deny. Las opciones orientadas a archivos se deniegan para binarios seguros por defecto (por ejemplo sort -o, sort --output, sort --files0-from, sort --compress-program, sort --random-source, sort --temporary-directory/-T, wc --files0-from, jq -f/--from-file, grep -f/--file). Los binarios seguros también aplican política explícita de flags por binario para opciones que rompen el comportamiento de solo stdin (por ejemplo sort -o/--output/--compress-program y flags recursivos de grep). Las opciones largas se validan en modo fail-closed para binarios seguros: flags desconocidos y abreviaciones ambiguas se rechazan. Flags denegados por perfil de binario seguro:

  • grep: --dereference-recursive, --directories, --exclude-from, --file, --recursive, -R, -d, -f, -r
  • jq: --argfile, --from-file, --library-path, --rawfile, --slurpfile, -L, -f
  • sort: --compress-program, --files0-from, --output, --random-source, --temporary-directory, -T, -o
  • wc: --files0-from

Los binarios seguros también fuerzan que los tokens de argv se traten como texto literal en tiempo de ejecución (sin globbing y sin expansión de $VARS) para segmentos de solo stdin, así que patrones como * o $HOME/... no pueden usarse para contrabandear lecturas de archivos. Los binarios seguros también deben resolver desde directorios de binarios de confianza (valores por defecto del sistema más tools.exec.safeBinTrustedDirs opcionales). Las entradas de PATH nunca se confían automáticamente. Los directorios de confianza por defecto para binarios seguros son intencionalmente mínimos: /bin, /usr/bin. Si tu ejecutable de binario seguro vive en rutas de gestor de paquetes/usuario (por ejemplo /opt/homebrew/bin, /usr/local/bin, /opt/local/bin, /snap/bin), agrégalos explícitamente a tools.exec.safeBinTrustedDirs. El encadenamiento de shell y las redirecciones no se auto-permiten en modo lista permitida.

El encadenamiento de shell (&&, ||, ;) se permite cuando cada segmento de nivel superior satisface la lista permitida (incluyendo binarios seguros o auto-permitir skills). Las redirecciones no están soportadas en modo lista permitida. La sustitución de comandos ($() / backticks) se rechaza durante el análisis de la lista permitida, incluyendo dentro de comillas dobles; usa comillas simples si necesitas texto literal $(). En aprobaciones de la app complementaria de macOS, el texto de shell crudo que contiene sintaxis de control o expansión de shell (&&, ||, ;, |, `, $, <, >, (, )) se trata como un fallo de lista permitida a menos que el binario del shell mismo esté en la lista permitida. Para envoltorios de shell (bash|sh|zsh ... -c/-lc), las sobrecargas de env con alcance de solicitud se reducen a una pequeña lista explícita permitida (TERM, LANG, LC_*, COLORTERM, NO_COLOR, FORCE_COLOR). Para decisiones de permitir-siempre en modo lista permitida, los envoltorios de despacho conocidos (env, nice, nohup, stdbuf, timeout) persisten rutas de ejecutable interno en lugar de rutas de envoltorio. Los multiplexores de shell (busybox, toybox) también se desenvuelven para applets de shell (sh, ash, etc.) así que los ejecutables internos se persisten en lugar de binarios multiplexores. Si un envoltorio o multiplexor no puede desenvolverse de forma segura, no se persiste entrada de lista permitida automáticamente.

Binarios seguros por defecto: jq, cut, uniq, head, tail, tr, wc.

grep y sort no están en la lista por defecto. Si optas por incluirlos, mantén entradas explícitas de la lista permitida para sus flujos de trabajo que no son de stdin. Para grep en modo binario seguro, proporciona el patrón con -e/--regexp; la forma posicional del patrón se rechaza para que los operandos de archivo no puedan ser contrabandados como posicionales ambiguos.

Binarios seguros versus lista permitida

Tematools.exec.safeBinsLista permitida (exec-approvals.json)
ObjetivoAuto-permitir filtros estrechos de stdinConfiar explícitamente en ejecutables específicos
Tipo de coincidenciaNombre del ejecutable + política de argv de binario seguroPatrón glob de ruta de ejecutable resuelta
Alcance de argumentosRestringido por perfil de binario seguro y reglas de token literalSolo coincidencia de ruta; los argumentos son tu responsabilidad
Ejemplos típicosjq, head, tail, wcpython3, node, ffmpeg, CLIs personalizados
Mejor usoTransformaciones de texto de bajo riesgo en pipelinesCualquier herramienta con comportamiento más amplio o efectos secundarios

Ubicación de la configuración:

  • safeBins viene de la configuración (tools.exec.safeBins o por agente agents.list[].tools.exec.safeBins).
  • safeBinTrustedDirs viene de la configuración (tools.exec.safeBinTrustedDirs o por agente agents.list[].tools.exec.safeBinTrustedDirs).
  • safeBinProfiles viene de la configuración (tools.exec.safeBinProfiles o por agente agents.list[].tools.exec.safeBinProfiles). Las claves de perfil por agente sobrecargan las claves globales.
  • Las entradas de la lista permitida viven en el ~/.openclaw/exec-approvals.json local del host bajo agents.<id>.allowlist (o vía la UI de Control / openclaw approvals allowlist ...).
  • openclaw security audit advierte con tools.exec.safe_bins_interpreter_unprofiled cuando binarios de intérprete/runtime aparecen en safeBins sin perfiles explícitos.
  • openclaw doctor --fix puede generar plantillas de entradas safeBinProfiles.<bin> personalizadas faltantes como {} (revisa y ajusta después). Los binarios de intérprete/runtime no se generan automáticamente.

Ejemplo de perfil personalizado:

{
  tools: {
    exec: {
      safeBins: ["jq", "myfilter"],
      safeBinProfiles: {
        myfilter: {
          minPositional: 0,
          maxPositional: 0,
          allowedValueFlags: ["-n", "--limit"],
          deniedFlags: ["-f", "--file", "-c", "--command"],
        },
      },
    },
  },
}

Edición en la UI de Control

Usa la tarjeta UI de Control -> Nodos -> Aprobaciones de ejecución para editar valores por defecto, sobrecargas por agente y listas permitidas. Elige un alcance (Valores por defecto o un agente), ajusta la política, agrega/elimina patrones de la lista permitida, luego Guardar. La UI muestra metadatos de last used por patrón para que puedas mantener la lista ordenada.

El selector de objetivo elige Gateway (aprobaciones locales) o un Nodo. Los nodos deben anunciar system.execApprovals.get/set (app de macOS o node host headless). Si un nodo aún no anuncia aprobaciones de ejecución, edita su ~/.openclaw/exec-approvals.json local directamente.

CLI: openclaw approvals soporta edición de gateway o nodo (consulta CLI de Aprobaciones).

Flujo de aprobación

Cuando se requiere un prompt, el gateway emite exec.approval.requested a los clientes operadores. La UI de Control y la app de macOS lo resuelven vía exec.approval.resolve, luego el gateway reenvía la solicitud aprobada al node host.

Para host=node, las solicitudes de aprobación incluyen una carga útil canónica systemRunPlan. El gateway usa ese plan como el comando/cwd/contexto de sesión autoritativo al reenviar solicitudes system.run aprobadas.

Comandos de intérprete/runtime

Las ejecuciones de intérprete/runtime respaldadas por aprobación son intencionalmente conservadoras:

  • El contexto exacto de argv/cwd/env siempre se vincula.
  • Las formas de script de shell directo y archivo de runtime directo se vinculan con mejor esfuerzo a un snapshot de archivo local concreto.
  • Las formas comunes de envoltorio de gestor de paquetes que aún resuelven a un archivo local directo (por ejemplo pnpm exec, pnpm node, npm exec, npx) se desenvuelven antes de vincular.
  • Si OpenClaw no puede identificar exactamente un archivo local concreto para un comando de intérprete/runtime (por ejemplo scripts de paquete, formas eval, cadenas de cargador específicas del runtime o formas ambiguas de múltiples archivos), la ejecución respaldada por aprobación se deniega en lugar de pretender cobertura semántica que no tiene.
  • Para esos flujos de trabajo, prefiere sandboxing, un límite de host separado o un flujo de trabajo explícito de lista permitida de confianza/full donde el operador acepta la semántica más amplia del runtime.

Cuando se requieren aprobaciones, la herramienta exec devuelve inmediatamente con un id de aprobación. Usa ese id para correlacionar eventos posteriores del sistema (Exec finished / Exec denied). Si no llega ninguna decisión antes del timeout, la solicitud se trata como un timeout de aprobación y se presenta como una razón de denegación.

El diálogo de confirmación incluye:

  • comando + argumentos
  • cwd
  • id del agente
  • ruta ejecutable resuelta
  • metadatos de host + política

Acciones:

  • Permitir una vez -> ejecutar ahora
  • Permitir siempre -> agregar a la lista permitida + ejecutar
  • Denegar -> bloquear

Reenvío de aprobaciones a canales de chat

Puedes reenviar prompts de aprobación de ejecución a cualquier canal de chat (incluyendo canales de plugin) y aprobarlos con /approve. Esto usa el pipeline normal de entrega de salida.

Configuración:

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

Responde en el chat:

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

Clientes de aprobación integrados en chat

Discord y Telegram también pueden actuar como clientes explícitos de aprobación de ejecución con configuración específica del canal.

  • Discord: channels.discord.execApprovals.*
  • Telegram: channels.telegram.execApprovals.*

Estos clientes son opt-in. Si un canal no tiene aprobaciones de ejecución habilitadas, OpenClaw no trata ese canal como una superficie de aprobación solo porque la conversación ocurrió allí.

Comportamiento compartido:

  • solo los aprobadores configurados pueden aprobar o denegar
  • el solicitante no necesita ser un aprobador
  • cuando la entrega al canal está habilitada, los prompts de aprobación incluyen el texto del comando
  • si ninguna UI de operador o cliente de aprobación configurado puede aceptar la solicitud, el prompt recurre a askFallback

Telegram usa por defecto DMs del aprobador (target: "dm"). Puedes cambiar a channel o both cuando quieras que los prompts de aprobación aparezcan también en el chat/tema de Telegram originario. Para temas de foro de Telegram, OpenClaw preserva el tema para el prompt de aprobación y el seguimiento post-aprobación.

Consulta:

Flujo IPC en macOS

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

Notas de seguridad:

  • Socket Unix modo 0600, token almacenado en exec-approvals.json.
  • Verificación de peer con mismo UID.
  • Challenge/response (nonce + HMAC token + hash de solicitud) + TTL corto.

Eventos del sistema

El ciclo de vida de exec se presenta como mensajes del sistema:

  • Exec running (solo si el comando excede el umbral de aviso de ejecución)
  • Exec finished
  • Exec denied

Estos se publican en la sesión del agente después de que el nodo reporta el evento. Las aprobaciones de ejecución del host del gateway emiten los mismos eventos de ciclo de vida cuando el comando termina (y opcionalmente cuando se ejecuta más tiempo del umbral). Las ejecuciones controladas por aprobación reutilizan el id de aprobación como el runId en estos mensajes para fácil correlación.

Implicaciones

  • full es poderoso; prefiere listas permitidas cuando sea posible.
  • ask te mantiene informado mientras permite aprobaciones rápidas.
  • Las listas permitidas por agente evitan que las aprobaciones de un agente se filtren a otros.
  • Las aprobaciones solo aplican a solicitudes de ejecución en host de remitentes autorizados. Los remitentes no autorizados no pueden emitir /exec.
  • /exec security=full es una conveniencia a nivel de sesión para operadores autorizados y omite las aprobaciones por diseño. Para bloquear completamente la ejecución en host, establece la seguridad de aprobaciones a deny o deniega la herramienta exec vía la política de herramientas.

Relacionado: