Más allá de los contenedores: reforzando mi entorno de desarrollo local
Reducir el alcance de los daños con contenedores, un proxy de salida, secretos efímeros y permisos limitados para las herramientas de IA.

Imagen generada con ChatGPT.
Los contenedores han sido mi opción predeterminada durante más de una década. Lo que no había hecho era aplicar la misma disciplina a todo lo demás en mi máquina anfitriona. La reciente ola de ataques a la cadena de suministro hizo imposible seguir ignorando esa carencia. Se acabó el «solo esta vez» al ejecutar npm install en el portátil.
Últimamente he ido reforzando mi entorno de desarrollo local alrededor de una idea sencilla: asumir que algo acabará comportándose de una manera inesperada. Una dependencia. Un paquete. Una herramienta. Un agente de IA. Mi objetivo no es la seguridad perfecta, sino reducir el alcance de los daños cuando eso ocurra.
Cuatro cambios hicieron la mayor parte del trabajo.
1. Cada proyecto se ejecuta en su propio contenedor, incluido el frontend
La mayoría de los equipos ya usan contenedores para las bases de datos, los servicios backend y quizá un proxy inverso. Fui más allá: incluí el frontend y eliminé las dependencias globales. Mi máquina anfitriona ejecuta Docker, Git, un editor y una terminal. Poco más.
Cada proyecto tiene su propio Dockerfile y su configuración de Compose. Si algo sale mal, descarto el contenedor. Si una dependencia resulta maliciosa, queda confinada en un entorno desechable en lugar de ejecutarse directamente en mi máquina anfitriona.
Como efecto secundario, incorporar a nuevas personas y sustituir equipos se volvió mucho más sencillo.
2. Un proxy de salida delante de cada proyecto
Este es el cambio que conservaría si solo pudiera quedarme con uno.
La mayoría de los desarrolladores se pregunta a qué puede acceder su código. Yo empecé a preguntarme con qué destinos puede comunicarse.
Ejecuto Squid como un servicio auxiliar en una red Docker local del proyecto y dirijo el tráfico saliente a través de él. Es un proxy de salida, no un proxy inverso delante de los servicios. Cada proyecto tiene una lista estricta de destinos permitidos: registros de paquetes, las API necesarias y poco más.
¿Por qué me gusta? A una dependencia comprometida le resulta mucho más difícil extraer datos silenciosamente. Un agente de programación con IA dentro del contenedor queda limitado a los destinos que he aprobado explícitamente. Además, puedo ver a qué destinos intentan acceder las aplicaciones y los agentes. En esencia, es control del tráfico saliente a nivel de aplicación para el desarrollo local.
Una advertencia importante: Squid no hace magia. Solo controla el tráfico que se dirige intencionadamente a través de él. No impide que un código malicioso borre archivos, modifique el código fuente o abuse de permisos que ya tiene. Su función principal es reducir el acceso innecesario a la red y dificultar la extracción de datos.
3. Se acabaron los archivos .env permanentes
Antes tenía archivos .env repartidos por las carpetas de los proyectos. Secretos en texto plano guardados en disco, que sobrevivían a los reinicios y que a veces copiaba en la ventana de terminal equivocada. El archivo .env.tpl contiene referencias op://vault/item/field para los secretos, mientras que los ajustes no secretos siguen siendo configuración normal.
Inicio los proyectos con:
op run --env-file=.env.tpl -- docker compose up --build -d
1Password resuelve las referencias e inyecta los valores durante la ejecución. No quedan secretos resueltos en disco ni archivos de credenciales generados después de detener el proyecto.
Mucho menos miedo a «¿habré incluido eso accidentalmente en un commit?».
4. Limitar lo que mis herramientas de IA pueden hacer
Uso mucho OpenCode y otras herramientas de programación con agentes. Antes mi enfoque era sencillo: darle todo al modelo. Todo el sistema de archivos, toda la red y cada herramienta disponible. Tardé más de lo que me gustaría admitir en cuestionar esa suposición.
Ahora empiezo desde el extremo opuesto: limito las herramientas disponibles, los recursos accesibles y qué modelos pueden realizar cada acción. Combinado con la lista de destinos permitidos del proxy, el alcance del agente queda deliberadamente reducido.
Nada de magia. Simplemente menos puertas.
El modelo mental
- Los contenedores me dan aislamiento.
- El proxy de salida me da control de la red.
- La CLI de 1Password me da secretos efímeros.
- Los permisos de las herramientas de IA me permiten limitar sus capacidades.
Ninguna de estas ideas es nueva por separado. Juntas cambian la opción predeterminada de permitir a denegar. Tengo que abrir accesos conscientemente cuando los necesito, en lugar de descubrir más tarde que los dejé abiertos.
Lo interesante de muchos ataques a la cadena de suministro es que no empiezan con técnicas sofisticadas. Empiezan con desarrolladores haciendo cosas normales: instalar un paquete, ejecutar un comando o dar permiso a una herramienta.
Por eso me interesa cada vez menos predecir todas las amenazas posibles y más reducir su impacto cuando algo inevitablemente salga mal. Sigo migrando los proyectos uno por uno: así está mi entorno de desarrollo local hoy.
¿Quieres un punto de partida? Los archivos opencode.jsonc y squid.conf que utilizo están en el primer comentario.
#DevEx #Security #Containers #AISecurity #DeveloperProductivity