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
openclawen 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.runa 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: falsey 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,-rjq:--argfile,--from-file,--library-path,--rawfile,--slurpfile,-L,-fsort:--compress-program,--files0-from,--output,--random-source,--temporary-directory,-T,-owc:--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
| Tema | tools.exec.safeBins | Lista permitida (exec-approvals.json) |
|---|---|---|
| Objetivo | Auto-permitir filtros estrechos de stdin | Confiar explícitamente en ejecutables específicos |
| Tipo de coincidencia | Nombre del ejecutable + política de argv de binario seguro | Patrón glob de ruta de ejecutable resuelta |
| Alcance de argumentos | Restringido por perfil de binario seguro y reglas de token literal | Solo coincidencia de ruta; los argumentos son tu responsabilidad |
| Ejemplos típicos | jq, head, tail, wc | python3, node, ffmpeg, CLIs personalizados |
| Mejor uso | Transformaciones de texto de bajo riesgo en pipelines | Cualquier herramienta con comportamiento más amplio o efectos secundarios |
Ubicación de la configuración:
safeBinsviene de la configuración (tools.exec.safeBinso por agenteagents.list[].tools.exec.safeBins).safeBinTrustedDirsviene de la configuración (tools.exec.safeBinTrustedDirso por agenteagents.list[].tools.exec.safeBinTrustedDirs).safeBinProfilesviene de la configuración (tools.exec.safeBinProfileso por agenteagents.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.jsonlocal del host bajoagents.<id>.allowlist(o vía la UI de Control /openclaw approvals allowlist ...). openclaw security auditadvierte contools.exec.safe_bins_interpreter_unprofiledcuando binarios de intérprete/runtime aparecen ensafeBinssin perfiles explícitos.openclaw doctor --fixpuede generar plantillas de entradassafeBinProfiles.<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 enexec-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 finishedExec 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=fulles 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 adenyo deniega la herramientaexecvía la política de herramientas.
Relacionado: