Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help

Cómo funcionan los complementos

Esta página explica el sistema de plugins desde el punto de vista de un operador: cómo se descubre un plugin, qué se le अनुमति hacer y cómo el host mantiene contenido a un plugin no confiable. Para el contrato en disco que implementa el autor de un plugin (campos del manifiesto, exportaciones del puente, funciones del host), consulta Protocolo de plugin.

La forma del sistema

Un plugin es un módulo de WebAssembly aislado más un manifiesto. El host lo carga, lee las capacidades y permisos que declara, y expone sus herramientas al agente solo cuando el operador ha activado el sistema de plugins. Nada de un plugin es implícito: un plugin obtiene exactamente las capacidades que su manifiesto declara y la política del operador permite, y nada más. Para crear uno tú mismo, empieza con las guías de plugins.

Tres propiedades se mantienen en cada capa:

  • Deshabilitado de forma predeterminada. El sistema de complementos no carga nada a menos que [plugins] enabled = true. Una compilación predeterminada sin configuración de complementos no ejecuta ningún código de complementos.
  • Denegar por defecto. Un plugin accede a una capacidad del host (egreso HTTP, configuración, memoria) solo al declarar el permiso correspondiente en su manifiesto. Una capacidad no declarada es inaccesible, no simplemente no utilizada.
  • Verificado por política. Si un plugin sin firmar o no confiable se carga o no, es decisión del operador, establecida una vez en la configuración y aplicada de forma uniforme en el descubrimiento.

Ciclo de vida de la carga de un complemento

Cuando el runtime construye su conjunto de herramientas, el cargador de plugins pasa por estas etapas en orden. Un plugin que falla en una etapa anterior nunca llega a una posterior.

  1. Gate. Si [plugins] enabled es false, el cargador no hace nada. Este es la primera y más barata comprobación.
  2. Descubre. El cargador examina el directorio de plugins resuelto ([plugins] plugins_dir, predeterminado ~/.zeroclaw/plugins/) en busca de subdirectorios que contengan un manifest.toml.
  3. Valida la forma. Cada manifiesto debe declarar al menos una capability, y un plugin que no sea de skill debe indicar un wasm_path que exista. Un manifiesto mal formado se omite con una advertencia, nunca se carga.
  4. Aplicar la política de firmas. Cada plugin se comprueba frente a [plugins.security] signature_mode y trusted_publisher_keys configurados. Un plugin que no supera la política se descarta del conjunto cargado y no se expone como una herramienta.
  5. Registra herramientas. Los complementos de herramientas restantes se envuelven como herramientas del agente y se añaden después de las integradas. El envío de herramientas resuelve los nombres usando la primera coincidencia, por lo que una herramienta de complemento cuyo nombre entre en conflicto con el de una integrada nunca se selecciona; asigna nombres únicos a las herramientas de los complementos. Los complementos de herramientas y habilidades se descubren automáticamente, por lo que esta enumeración solo tiene lugar cuando [plugins] auto_discover = true (valor predeterminado false, con comportamiento de fallo cerrado): con enabled = true pero auto_discover = false, no se cargan herramientas ni habilidades de complementos, aunque los canales que declares en [channels.plugin.<alias>] siguen activándose. El cargador de habilidades aplica la misma condición de auto_discover.

La etapa de firma es la que se configura con mayor facilidad de forma incorrecta, por lo que vale la pena entenderla por sí sola.

Política de firma

Cada manifiesto de plugin puede llevar una firma Ed25519 y la clave pública codificada en hexadecimal del publicador que lo firmó. El operador decide con qué rigor se aplica esa firma mediante [plugins.security] signature_mode:

ModoQué cargaUsar cuando
disabledTodo plugin bien formado, firmado o noDesarrollo local con plugins que has creado tú mismo
permissiveTodo plugin bien formado; las firmas no firmadas, no confiables e inválidas se cargan con una advertenciaMigración hacia la firma sin romper las instalaciones existentes
strictSolo los complementos con una firma válida de un editor de confianza se cargan¿Algún host compartido o de producción?

En modo strict, publisher_key del manifiesto debe aparecer en [plugins.security] trusted_publisher_keys, y la firma debe verificarse contra los bytes canónicos del manifiesto. Un plugin sin firmar, firmado por una clave no confiable o cuya firma no se verifique se descarta en el descubrimiento y nunca se convierte en una herramienta. El valor predeterminado es disabled, de modo que una nueva copia local funciona sin gestión de claves, pero un host que cargue plugins desde cualquier lugar que no controles debe ejecutar strict.

Esta política se aplica de forma uniforme: la misma comprobación que realiza el host cuando enumeras los plugins es la comprobación que el runtime del agente aplica cuando construye el conjunto de herramientas, así que un plugin que no puedes ver en modo strict también es un plugin que el agente no puede invocar.

Capacidades y permisos

Un manifest declara dos cosas separadas, y la distinción importa.

  • Las capacidades son el tipo de extensión que es el plugin: tool, channel, memory, observer o skill. Un plugin tool aporta herramientas que el LLM puede invocar.
  • Permisos son los servicios del host a los que el código del plugin puede acceder en tiempo de ejecución: salida HTTP, configuración, memoria. Un permiso que el manifiesto no declara es una función del host a la que el plugin no puede acceder.

El host concede permisos de forma restringida: un permiso que el manifiesto no declara corresponde a una función del host a la que el complemento no puede acceder. La configuración se resuelve a partir de una identidad de instancia emitida por el host, por lo que un complemento no puede seleccionar otro paquete o enlace y nunca lee el entorno sin procesar del proceso. http_client controla la superficie saliente de wasi:http; la política compartida de salida protegida contra SSRF sigue siendo trabajo complementario de refuerzo de complementos. Esta página cubre el límite de la política de firmas.

Referencia de configuración

Todas las configuraciones residen bajo las rutas de configuración plugins.* y se establecen a través de cualquier superficie de configuración (zerocode, el gateway o la CLI):

# Interruptor maestro. Nada se carga mientras esto sea falso.
zeroclaw config set plugins.enabled true

# Cargar complementos de herramientas y habilidades detectados automáticamente durante la ejecución (predeterminado: false).
# Without this, `enabled = true` activates only explicitly-declared channels.
zeroclaw config set plugins.auto_discover true

# Dónde se descubren los plugins (predeterminado: ~/.zeroclaw/plugins).
zeroclaw config set plugins.plugins_dir ~/.zeroclaw/plugins

# deshabilitado | permisivo | estricto
zeroclaw config set plugins.security.signature_mode strict

Claves públicas Ed25519 codificadas en hexadecimal permitidas para publicar plugins en modo estricto.
zeroclaw config set plugins.security.trusted_publisher_keys '["a1b2c3d4e5f6..."]'

Un host destinado a cargar plugins de terceros debe establecer enabled = true, signature_mode = "strict" y enumerar únicamente las claves de los editores en los que confíes. Para cargar también plugins de herramientas y habilidades detectados automáticamente, establece además auto_discover = true; su valor predeterminado es false, por lo que enabled = true por sí solo activa únicamente los canales que declares en [channels.plugin.<alias>] y no las herramientas ni habilidades de los plugins. Un host que ejecute únicamente los plugins que construyas tú mismo puede dejar signature_mode con su valor predeterminado disabled durante el desarrollo y endurecerlo antes de compartir el host.

Lo que un plugin todavía no puede hacer

Incluso con todos los permisos concedidos, el sandbox delimita un plugin:

  • Se ejecuta como un módulo WebAssembly sin acceso implícito al proceso anfitrión ni al sistema de archivos fuera de su espacio de trabajo raíz. La salida de red está controlada por el permiso HTTP; el propio límite de salida protegido contra SSRF se entrega mediante el trabajo complementario de hardening de plugins.
  • Una herramienta de confianza o un complemento de canal puede leer el texto sin formato de un secreto designado por el esquema mediante su importación secrets.get con ámbito restringido durante una llamada de servicio autorizada. Las herramientas obtienen acceso durante execute. Los canales reciben acceso a config.get y secrets.get durante configure y las llamadas operativas; las lecturas realizadas dentro de una misma llamada usan una única revisión canónica, por lo que una rotación de los valores público y secreto de una misma vinculación estará disponible en la siguiente operación. La instanciación y el descubrimiento de metadatos estáticos no pueden usar ninguna de las dos importaciones. El host impide la inyección de configuración pública y la selección entre instancias, pero una importación que devuelve texto sin formato no puede impedir que un invitado malicioso conserve lo que lee. Los complementos de canal conformes deben resolver la configuración y las credenciales en cada punto de uso.
  • No puede reemplazar una herramienta integrada: las integradas se registran primero y el despacho de herramientas resuelve los nombres por la primera coincidencia, así que una herramienta de plugin que colisiona simplemente nunca se selecciona.

Los límites del entorno aislado y del espacio de nombres se mantienen independientemente de lo que intente el código del plugin. La regla de no retención forma parte, en cambio, del contrato de confianza entre el canal y el plugin, por lo que la revisión del editor y la política de firmas siguen siendo importantes.