Seguridad del servidor de OpenCode: cómo ejecutar opencode serve y opencode web de forma segura

opencode serve expone una API HTTP que puede leer archivos y ejecutar comandos de shell. Cómo mantenerlo en localhost, poner contraseña, añadir TLS y acceder en remoto.

Basado en
CLI
0.2.17
Ref de preview
a2c45c8

En resumen

opencode serve y opencode web ejecutan un servidor HTTP cuya API puede leer archivos, ejecutar comandos de shell, cambiar la configuración y definir credenciales de proveedores. Trata el acceso a él como acceso de shell a la máquina.

Una configuración segura, por orden de importancia:

  1. Mantén el hostname por defecto, 127.0.0.1. Usa 0.0.0.0 o --mdns solo en una red que controles.
  2. Define OPENCODE_SERVER_PASSWORD siempre que el servidor sea accesible desde algo que no sea tu propia máquina. La documentación de OpenCode dice que sin ella el servidor no tiene protección.
  3. Pon TLS delante si el tráfico cruza una red. La autenticación básica sobre HTTP sin cifrar envía la contraseña de forma que cualquiera en el camino puede leerla.
  4. Accede a través de una red privada o un túnel, como SSH o Tailscale, en lugar de un puerto público.
  5. Mantén --cors acotado. Añade solo orígenes que gestiones tú.

El problema

El diseño cliente-servidor de OpenCode es uno de sus puntos fuertes. La TUI habla con un servidor local, así que también puedes manejarlo desde un navegador, un plugin del IDE, un script u otro ordenador. La documentación muestra cómo hacerlo con una sola opción:

opencode web --port 4096 --hostname 0.0.0.0

Esa línea está bien en un portátil en casa. En la red de una cafetería, la LAN de una oficina compartida o una máquina virtual en la nube con el grupo de seguridad abierto, publica la API de control de un agente de programación para cualquiera que llegue al puerto. La solución son unos pocos ajustes, y es fácil saltárselos cuando lo único que quieres es conectar el móvil.

Qué expone el servidor de OpenCode

Según la documentación del servidor de OpenCode, consultada el 26 de octubre de 2026, la API incluye:

EndpointQué hace
POST /session/:id/shellEjecuta un comando de shell
POST /session/:id/messageEnvía un prompt al agente
GET /file/content?path=Lee un archivo
GET /find?pattern=Busca en el contenido de los archivos
PATCH /configActualiza la configuración
PUT /auth/:idDefine credenciales de proveedores
POST /mcpAñade un servidor MCP
POST /session/:id/permissions/:permissionIDResponde a una solicitud de permiso
GET /docLa especificación OpenAPI 3.1

Quien pueda llamar a estos endpoints puede hacer lo mismo que tú en una terminal de esa máquina, y responder por ti a los prompts de permisos del agente. Ese es el modelo de amenaza de todo lo que sigue.

Los valores por defecto del servidor de OpenCode

Según la documentación del servidor:

OpciónPor defectoNotas
--port4096
--hostname127.0.0.1Solo loopback
--mdnsfalseAl activarlo, el hostname pasa a 0.0.0.0 y anuncia opencode.local
--corsningunoOrígenes de navegador adicionales permitidos

Los valores por defecto son seguros por sí solos. Ejecutar opencode sin argumentos inicia la TUI y un servidor en un puerto y hostname aleatorios, que la TUI usa como backend. El riesgo aparece al cambiar el hostname o activar mDNS.

Paso 1: mantén OpenCode en localhost salvo que necesites más

Si el único cliente está en la misma máquina, no pases --hostname:

opencode serve

Comprueba qué está escuchando:

# Linux
ss -ltnp | grep 4096
# macOS
lsof -nP -iTCP:4096 -sTCP:LISTEN

Lo que quieres ver es 127.0.0.1:4096, no 0.0.0.0:4096 ni *:4096.

Paso 2: pon una contraseña al servidor de OpenCode

El servidor admite autenticación HTTP básica mediante variables de entorno. Se aplica tanto a opencode serve como a opencode web:

export OPENCODE_SERVER_PASSWORD="$(openssl rand -base64 32)"
opencode serve

El usuario por defecto es opencode. Define OPENCODE_SERVER_USERNAME para cambiarlo. La documentación web incluye una advertencia: si OPENCODE_SERVER_PASSWORD no está definida, el servidor no tiene protección, algo que describe como aceptable en uso local pero que conviene definir para el acceso por red.

Para conectar una TUI a un servidor protegido con contraseña:

opencode attach http://10.20.30.40:4096 --password "$OPENCODE_SERVER_PASSWORD"

--password toma por defecto OPENCODE_SERVER_PASSWORD, así que si la variable está definida en esa shell puedes omitir la opción.

No dejes la contraseña en el historial de la shell ni en dotfiles de repositorios compartidos. Sirve un gestor de contraseñas o un archivo que solo tú puedas leer y que se cargue al arrancar.

Paso 3: añade TLS delante del servidor de OpenCode

La autenticación básica envía las credenciales con cada petición, codificadas pero sin cifrar. Sobre HTTP sin cifrar en una red de la que no te fías del todo, equivale a no tener contraseña. Opciones:

  • Un proxy inverso como Caddy o nginx, que termina HTTPS y reenvía a 127.0.0.1:4096. El servidor de OpenCode se queda en loopback.

  • Un túnel SSH, que cifra la conexión sin abrir puertos nuevos:

    ssh -N -L 4096:127.0.0.1:4096 you@server

    Después apunta el cliente a http://127.0.0.1:4096 en tu propia máquina.

  • Una red privada como Tailscale o WireGuard, que cifra el tráfico entre tus dispositivos. Úsala igualmente con contraseña, porque cualquier otro equipo de esa red puede llegar al puerto.

Cloudflare Tunnel vs Tailscale Funnel vs ngrok compara las opciones de túnel. Ten cuidado con todo lo que publique el puerto en internet. Una URL pública con autenticación básica es una shell protegida solo por contraseña.

Paso 4: limita quién puede llegar al puerto de OpenCode

  • En una máquina virtual en la nube, no abras el 4096 en el grupo de seguridad. Accede por SSH o por una red privada.
  • En un servidor doméstico, no lo incluyas en la redirección de puertos del router.
  • Con mDNS, recuerda que --mdns escucha en 0.0.0.0. Es cómodo en una red doméstica y poco adecuado para una Wi-Fi compartida.
  • Con un cortafuegos en el equipo, permite el puerto solo desde las direcciones que lo necesiten.

Paso 5: mantén CORS acotado

--cors añade orígenes de navegador que pueden llamar al servidor. Cada origen que añades es un sitio web cuyos scripts pueden hablar con tu agente desde un navegador que llegue a él. Añade solo frontends que gestiones tú, con el origen exacto:

opencode serve --cors https://app.example.com

Paso 6: reduce el alcance de un error en la máquina

Aun con un buen control de acceso, el servidor se ejecuta con tu usuario. Algunos hábitos limitan lo que puede hacer un error:

  • En un servidor compartido, ejecuta OpenCode con un usuario aparte, con acceso a los repositorios que necesita y sin credenciales de producción.
  • Mantén estrictas las reglas de permisos para los comandos de shell. Un cliente remoto que responde "permitir" sigue siendo tú permitiéndolo.
  • Detén el servidor cuando termines. Un opencode serve en marcha durante semanas es una exposición permanente.

Acceder a OpenCode desde el móvil sin abrir un puerto

El motivo habitual para escuchar en 0.0.0.0 es usar OpenCode desde otro dispositivo. Eso también se puede hacer sin que el servidor de OpenCode escuche en nada más que loopback.

Si quieres manejar OpenCode desde el móvil sin exponer su servidor, Happier es una app de código abierto para ejecutar y orquestar Claude Code, Codex, OpenCode y otros agentes entre dispositivos, desde el móvil, el escritorio o la web.

Cómo trata el servidor de OpenCode que gestiona:

  • Solo loopback. Happier inicia su servidor de OpenCode gestionado con --hostname=127.0.0.1 y un puerto local libre, y solo reutiliza un servidor gestionado cuya dirección sea loopback.
  • Una contraseña por cada servidor gestionado. Si defines OPENCODE_PASSWORD u OPENCODE_SERVER_PASSWORD, Happier usa la tuya. Si no, genera una para ese servidor y la guarda en un archivo de estado legible solo por el propietario en ~/.happier/opencode/managed-servers/.
  • La contraseña no sale de tu máquina. La documentación de Happier dice que se pasa al servidor mediante el entorno, nunca se escribe en los registros del servidor de OpenCode de Happier y nunca se envía a un endpoint remoto.
  • El acceso remoto pasa por Happier, no por el puerto de OpenCode. La app del móvil, de escritorio o web habla con el daemon de Happier en tu ordenador a través del relay. El contenido de las sesiones va cifrado de extremo a extremo por defecto. Los metadatos como los ids de sesión y las marcas de tiempo no. También puedes autoalojar el relay.

Los prompts de permisos de OpenCode llegan al móvil y los respondes allí. happier attach <session-id> vuelve a abrir la TUI de OpenCode de la sesión en la misma máquina. La configuración está en Cómo usar Happier desde el móvil. Happier está en GitHub, puedes descargarlo aquí y hay un Discord.

Solución de problemas

Todas las peticiones devuelven 401

El cliente no envía la contraseña que espera el servidor. Comprueba que el OPENCODE_SERVER_PASSWORD del cliente coincide con el del servidor, y que el usuario coincide si cambiaste OPENCODE_SERVER_USERNAME. Algunas versiones recientes de OpenCode leen otro nombre de variable, así que compara opencode --version con la documentación de tu versión.

El servidor es accesible desde otras máquinas y no debería

Comprueba la dirección de escucha con ss -ltnp o lsof. Si pone 0.0.0.0 o *, busca --hostname 0.0.0.0 o --mdns en el comando o en un archivo de servicio.

El navegador bloquea las peticiones de un frontend propio

Añade el origen exacto del frontend con --cors. No uses un comodín.

opencode attach no conecta por SSH

Comprueba que el túnel está activo y apunta a 127.0.0.1:4096 en el lado remoto. Conéctate a http://127.0.0.1:4096 en local, no a la IP remota.

Preguntas frecuentes

¿opencode serve es seguro por defecto?

Escucha en 127.0.0.1, así que otras máquinas no pueden llegar a él. Cualquier proceso de la misma máquina sí puede. Sin OPENCODE_SERVER_PASSWORD no hay autenticación.

¿opencode web usa la misma contraseña?

Sí. La documentación de OpenCode dice que OPENCODE_SERVER_PASSWORD se aplica tanto a opencode serve como a opencode web.

¿Se puede exponer OpenCode a internet?

Se puede, pero la API ejecuta comandos de shell. Si no te queda otra, usa TLS, una contraseña robusta e idealmente una capa de acceso delante, como una VPN o un proxy con verificación de identidad.

¿El endpoint de la especificación OpenAPI es un riesgo?

/doc describe la API. No da acceso por sí mismo, pero facilita explorar la superficie. Está detrás de la misma contraseña que el resto.

Guías relacionadas

opencodesecurityself-hostingremote-access
Última actualización: 2026-10-26