Puente
Una app de escritorio remoto self-hosted, al estilo AnyDesk, que corre en servidores propios para el soporte de SinBuque.

El equipo necesitaba entrar a máquinas de oficina que están prendidas todo el día, sin pagar una herramienta comercial ni pasar las sesiones por servidores ajenos. El servidor que conecta las dos máquinas tenía que tratarse como no confiable. Y la persona del otro lado muchas veces no es técnica, así que los controles de seguridad tenían que entenderse en pantalla.
Tres decisiones que lo definieron.
- 01
Un contrato escrito antes que el código
Por qué. PROTOCOL.md define cada mensaje, el modelo de amenaza y el orden real de una conexión. Los schemas y los ejemplos se generan desde ahí, y el CI verifica que no se desincronicen. El visor, el host y el servidor se construyeron en paralelo contra el mismo documento. Lo nuevo entra como capacidad, así que nada viejo se rompe.
El costo. El núcleo está congelado, así que un cambio de verdad ahí exige un pase coordinado en las tres partes. Los pedidos esperan anotados en un archivo hasta entonces.
- 02
El visor dibuja la confianza, no la decide
Por qué. El ID del equipo lo asigna el servidor, así que no prueba nada. La verificación del fingerprint es la única defensa real, y la pantalla la trata así: 16 celdas numeradas para leer en voz alta por teléfono, y un estado rojo cuando un equipo conocido aparece con otra clave. La decisión de confianza la toma el core en Rust. React sólo la dibuja, porque el código de un webview se puede editar en caliente.
El costo. Cada pantalla depende de un comando de Tauri. Un test lee los dos lados y falla si el front invoca un comando que el core en Rust nunca registró, algo que si no aparecería recién como un botón que no hace nada.
- 03
Honesto sobre qué va cifrado
Por qué. El input, la terminal, los archivos y el portapapeles van cifrados de punta a punta. El video usa el cifrado propio de WebRTC, que un servidor hostil en teoría podría interceptar. Por eso los fingerprints DTLS entran en el handshake firmado: si el servidor manipula la conexión, la sesión se corta antes del primer cuadro. La pantalla de conexión lo dice con palabras simples cuando la sesión pasa por el relay.
El costo. El video no va cifrado de punta a punta, y el producto nunca dice que sí. Hacerlo necesita insertable streams en los dos lados, y es un proyecto aparte.




Puente
Una app de escritorio remoto self-hosted, al estilo AnyDesk, que corre en servidores propios para el soporte de SinBuque.
- Rol
- Diseño y desarrollo completo
- Stack
- Tauri v2, React, TypeScript, Rust, WebRTC, Go, coturn

El equipo necesitaba entrar a máquinas de oficina que están prendidas todo el día, sin pagar una herramienta comercial ni pasar las sesiones por servidores ajenos. El servidor que conecta las dos máquinas tenía que tratarse como no confiable. Y la persona del otro lado muchas veces no es técnica, así que los controles de seguridad tenían que entenderse en pantalla.
Tres decisiones que lo definieron.
Un contrato escrito antes que el código
Por qué. PROTOCOL.md define cada mensaje, el modelo de amenaza y el orden real de una conexión. Los schemas y los ejemplos se generan desde ahí, y el CI verifica que no se desincronicen. El visor, el host y el servidor se construyeron en paralelo contra el mismo documento. Lo nuevo entra como capacidad, así que nada viejo se rompe.
El costo. El núcleo está congelado, así que un cambio de verdad ahí exige un pase coordinado en las tres partes. Los pedidos esperan anotados en un archivo hasta entonces.
El visor dibuja la confianza, no la decide
Por qué. El ID del equipo lo asigna el servidor, así que no prueba nada. La verificación del fingerprint es la única defensa real, y la pantalla la trata así: 16 celdas numeradas para leer en voz alta por teléfono, y un estado rojo cuando un equipo conocido aparece con otra clave. La decisión de confianza la toma el core en Rust. React sólo la dibuja, porque el código de un webview se puede editar en caliente.
El costo. Cada pantalla depende de un comando de Tauri. Un test lee los dos lados y falla si el front invoca un comando que el core en Rust nunca registró, algo que si no aparecería recién como un botón que no hace nada.
Honesto sobre qué va cifrado
Por qué. El input, la terminal, los archivos y el portapapeles van cifrados de punta a punta. El video usa el cifrado propio de WebRTC, que un servidor hostil en teoría podría interceptar. Por eso los fingerprints DTLS entran en el handshake firmado: si el servidor manipula la conexión, la sesión se corta antes del primer cuadro. La pantalla de conexión lo dice con palabras simples cuando la sesión pasa por el relay.
El costo. El video no va cifrado de punta a punta, y el producto nunca dice que sí. Hacerlo necesita insertable streams en los dos lados, y es un proyecto aparte.



