Las CLI de IA no deberían instalar daemons por defecto
Las CLI de IA instalan daemons persistentes que se actualizan solos. Por qué rompe el modelo de confianza y cómo hacerlo mejor.

Un desarrollador ejecuta npm install -g @openai/codex para probar un asistente de programación con IA y termina con un daemon persistente y auto-actualizable en segundo plano que nunca pidió. Eso es lo que estalló hace poco, cuando usuarios de Codex CLI de OpenAI descubrieron que la herramienta arranca un proceso en segundo plano, escribe archivos pid y lock en ~/.codex, conserva versiones antiguas de binarios en disco (un usuario reportó unos 12 GB) y se actualiza sola sin avisar. No es la historia de un error de una sola empresa. Es la historia de un modelo de confianza en el que las herramientas para desarrolladores se han apoyado durante décadas, y de cómo se está abandonando en silencio.
Llevo años trabajando en infraestructura y respuesta a incidentes, y este patrón me suena de antes: en adware, en agentes de compilación comprometidos y en servicios de actualización «útiles» que los fabricantes de hardware incluyen de serie. Así que vamos a poner a prueba las defensas habituales de este diseño, una por una, porque la mayoría no sobrevive al contacto con cómo funcionan de verdad los entornos de producción.
Mito 1: «Es solo un actualizador, los navegadores hacen lo mismo»
Es la defensa más común y suena razonable. Chrome y Firefox se actualizan constantemente. Lo mismo hacen VS Code y Slack. ¿Por qué no iba a hacerlo una herramienta de línea de comandos?
Porque el contexto de confianza es completamente distinto. Un navegador es una aplicación gráfica con una experiencia de primer arranque, una página de ajustes visible, un instalador firmado y, sobre todo, un canal de actualización que lleva más de una década reforzado y auditado. El actualizador de Chrome es una de las piezas de software más atacadas del planeta, y Google tiene equipos dedicados a mantenerlo seguro. Cuando instalas Chrome, la actualización forma parte del trato, y lo aceptaste de forma visible.
Una CLI instalada con npm implica otro contrato implícito. Los desarrolladores esperan que se ejecute cuando la invocan y que se detenga al terminar. Esa expectativa no es nostalgia: sostiene todo lo demás. Los pipelines de CI, los contenedores, los servidores de compilación compartidos y las revisiones de seguridad asumen que npm i -g some-tool te da un binario que se ejecuta bajo demanda. Un daemon en segundo plano que sobrevive al cierre de sesión, se vuelve a lanzar solo y cambia su propio binario viola cada una de esas suposiciones. Yo mismo he estado en llamadas de incidentes en las que la pregunta «¿por qué hay un proceso que no podemos explicar?» convirtió una alerta rutinaria en tres horas de análisis forense. La persistencia sin justificar es indistinguible de un compromiso hasta que demuestras lo contrario.
Además, la diferencia práctica está en el radio de impacto. Tu navegador renderiza páginas web dentro de un sandbox. Un arnés de programación con IA ejecuta comandos de shell, lee tu código fuente y, a menudo, tiene claves de API y credenciales de la nube en su entorno. Darle a eso un componente que se modifica a sí mismo y está siempre activo es un riesgo categóricamente mayor que una actualización del navegador.
Mito 2: «Los usuarios pueden desactivarlo con un flag de configuración»
Técnicamente es cierto, y en la práctica no significa nada. Sí, existe un flag de funcionalidad:
# ~/.codex/config.toml
[features]
daemon_auto_start = false
El problema es que no estaba documentado cuando los usuarios lo buscaron. Una opción de exclusión que nadie conoce no es consentimiento, es una trampa. Y fíjate en el plan B que propuso la comunidad: borrar los archivos pid y lock, enlazarlos simbólicamente a /dev/null y marcarlos como inmutables con chattr +i, de modo que el daemon falle al arrancar si el flag desaparece algún día. Cuando los usuarios tienen que poner trampas en sus propios directorios personales para defenderse de tu software, no has construido un sistema de configuración. Has construido una relación adversarial.
Ya he escrito sobre esta dinámica en el contexto de las fugas de datos de ubicación en apps de fitness: el patrón es siempre el mismo. La funcionalidad se activa por defecto, el interruptor queda enterrado o sin documentar y la carga de la vigilancia recae en el usuario. Los valores por defecto son política. Un valor por defecto que instala persistencia dice mucho sobre a quién sirve realmente el software.
La solución es trivialmente fácil y siempre lo ha sido: preguntar una vez, en la primera ejecución. Codex runs a background service to keep itself updated. Enable it? [y/N]. Herramientas como apt, Homebrew y la mayoría de los daemons de Linux funcionan con activación explícita desde hace décadas. systemctl enable existe precisamente porque arrancar algo en el inicio se supone que es un acto deliberado.
Mito 3: «Avanzar rápido exige actualizarse en silencio»
Este argumento tiene algo de razón y quiero defenderlo en su mejor versión. Los arneses de IA avanzan de verdad a gran velocidad. Una CLI que lleva tres semanas sin actualizar puede fallar frente a una API que ha cambiado, y un cliente con errores en producción es una carga real para soporte. Un equipo que construye un IDE para legaltech contó que consideró un daemon y, en su lugar, eligió comprobar si hay actualizaciones en cada inicio: si la app está desactualizada, te lo dice y se actualiza al arrancar, y si no te gusta, dejas de usarla. Es un diseño legítimo.
Pero «necesitamos actualizaciones» no implica «necesitamos un daemon persistente que se actualice mientras no miras». Hay un término medio amplio:
- Comprobar al invocar. Compara versiones cuando arranca la CLI, muestra un aviso y actualiza en la siguiente ejecución. Homebrew, gh y otras muchas herramientas lo hacen así.
- Actualizar a través del gestor de paquetes. Se instaló con npm, así que se actualiza con npm. El usuario ya tiene un mecanismo que entiende y que puede fijar, auditar y bloquear.
- Daemon opcional, desactivado por defecto. Para quien quiera frescura sin fricción, ofrece el daemon como una opción documentada.
- Limpiar versiones antiguas. Conservar cada binario anterior hasta comerte 12 GB del disco de alguien no es una estrategia de actualización, es una fuga.
La verdadera razón por la que los equipos recurren a actualizadores silenciosos no es la velocidad, sino el control. Una actualización por gestor de paquetes respeta el lockfile, los mirrors y el flujo de aprobación del usuario. Un autoactualizador se salta todo eso. Cuando un proveedor insiste en la ruta de autoactualización, te está diciendo que valora su pipeline de despliegue por encima de tu gestión de cambios. En una empresa que ya tiene puntos ciegos en el logging, así es como acabas con código no revisado ejecutándose con las credenciales de los desarrolladores.

Mito 4: «Es de código abierto, puedes leer el código»
El código abierto ayuda, pero no resuelve el problema real, que es la divergencia entre lo que revisaste y lo que se está ejecutando. La gracia de un daemon que se autoactualiza es que el binario de tu máquina hoy no es el que instalaste. Leer el código de la versión 0.157.0 no te dice nada sobre la compilación que se descargará el próximo martes. A menos que verifiques firmas y builds reproducibles en cada actualización silenciosa, y nadie lo hace, «es de código abierto» es una manta de consuelo.
Hay un segundo problema, más sutil: el enredo entre estado y configuración. Usuarios que intentaron gestionar Codex de forma declarativa (uno contó que no lo consiguió con nix-darwin) descubrieron que la herramienta mezcla la configuración con el estado de ejecución mutable en el mismo directorio. Eso hace imposible fijar, comparar o auditar qué cambió. Las buenas herramientas Unix lo saben desde siempre: configuración en ~/.config, estado en ~/.local/state, caché en ~/.cache, y nunca dejar que la herramienta modifique su propia configuración. Si quieres entender por qué importa el camino auditable, la brecha entre especificación e implementación es justo donde viven estas sorpresas.
Si quieres comprobar qué se está ejecutando realmente en tu máquina ahora mismo, te lleva treinta segundos:
# What AI-tool daemons are alive right now?
ps auxww | grep -Ei 'codex|claude' | grep -v grep
# What's been accumulating on disk?
du -sh ~/.codex ~/.local/share/claude 2>/dev/null
# What launchd/systemd units did tools register?
ls ~/Library/LaunchAgents 2>/dev/null # macOS
systemctl --user list-units --type=service | grep -Ei 'codex|claude' # Linux
Ejecuta eso en unos cuantos portátiles de desarrolladores de tu organización. Te garantizo que al menos una persona se llevará una sorpresa con el resultado.
Mito 5: «Todo el mundo lo hace, así que debe estar bien»
Claude Code también conserva versiones binarias anteriores y ejecuta tareas en segundo plano; los usuarios de la misma discusión lo confirmaron. Así que sí, es un patrón de la industria, no un descuido de un solo proveedor. Pero «todo el mundo lo hace» nunca ha sido un argumento de seguridad; es la forma en que las malas costumbres se consolidan. Los incidentes en la cadena de suministro de los últimos años deberían habernos enseñado que las máquinas de los desarrolladores son el objetivo más fácil y valioso en la mayoría de las organizaciones: guardan credenciales de la nube, claves de firma y acceso de escritura, y ejecutan una cantidad asombrosa de código no auditado con esos privilegios.
Cada componente persistente, conectado a la red y que se modifica a sí mismo que añades a esa máquina es superficie de ataque con acceso a tus credenciales más sensibles. Un canal de actualización comprometido de una herramienta popular para desarrolladores es una pesadilla precisamente porque se confía en él de forma implícita. Cuanto más proveedores normalicen los daemons silenciosos, más valioso se vuelve cada uno como objetivo.
Y el nivel de calidad importa. Los usuarios reportaron que el daemon de Codex corrompía los permisos durante la autoactualización: dejaba directorios .git de solo lectura y bloqueaba repositorios de trabajo. Un daemon con errores no se queda quieto; rompe cosas activamente, con privilegios que nunca concediste de forma consciente. «Todo el mundo lo hace» más «tiene errores» no es tranquilizador. Es un pronóstico.
Cómo es un mecanismo de actualización que respeta el consentimiento
Es un problema resuelto. No necesitamos tecnología nueva; necesitamos que los proveedores elijan la respuesta aburrida. Si yo escribiera el documento de requisitos de cualquier CLI de IA que se publique hoy, tendría este aspecto:
- Sin persistencia por defecto. La herramienta se ejecuta al invocarla y sale al terminar. Cualquier componente en segundo plano es opcional y se pide explícitamente en la primera ejecución.
- Interruptores de desactivación documentados y estables. Un flag de configuración y una variable de entorno (por ejemplo
CODEX_NO_DAEMON=1) que estén documentados, probados y que no desaparezcan en silencio. - Actualizaciones a través del canal de instalación. Las herramientas instaladas con npm se actualizan con npm. Avisa al invocar; nunca cambies tu propio binario por debajo del usuario.
- Versiones firmadas y con changelog. Si envías un actualizador, firma los artefactos y deja que los usuarios fijen versiones y auditen qué cambió.
- Disco acotado y estado bien separado. Conserva como máximo una versión anterior, separa la configuración del estado y respeta las convenciones XDG.
- Respeta el modelo de distribuciones. Como dijo un comentarista, los paquetes de distribución existen para que los mantenedores prueben el software y eliminen las tonterías antes de que llegue a los usuarios. No luches contra eso: publica a través de ellos.
Nada de esto frena de forma significativa a un equipo que avanza rápido. Solo mueve el consentimiento al principio de la interacción, que es donde debe estar.
La conclusión
La verdad incómoda es que las herramientas de programación con IA piden más confianza que cualquier herramienta para desarrolladores de la historia (acceso a la shell, tus credenciales, todo tu código fuente), y al mismo tiempo adoptan la higiene de actualización del adware de 2008. Esos dos hechos no pueden coexistir de forma segura. Una CLI que instala por defecto un daemon persistente y auto-actualizable ha tomado una decisión en tu nombre, y la decisión es que la comodidad del proveedor está por encima de tu control sobre tu propia máquina.
Plántale cara. Configura los flags, audita tus máquinas, abre issues y prefiere herramientas cuyos valores por defecto te respeten. El mismo instinto que lleva a la gente a buscar la libertad del sideloading frente a plataformas cerradas se aplica aquí. Las herramientas que dejamos ejecutarse sin supervisión en los portátiles de los desarrolladores hoy serán los informes de incidentes en la cadena de suministro de mañana. El consentimiento no es un extra en el diseño de actualizaciones. Es todo el mecanismo.


