Qué es Vellum
Vellum es un servidor SMTP de pruebas con interfaz web diseñado para equipos de ingeniería que necesitan interceptar, inspeccionar y analizar correos en entornos de desarrollo y staging sin que ningún mensaje salga a la red pública. El servidor recibe, retiene y clasifica cada correo según el proyecto al que pertenece. El punto diferencial no está solo en la intercepción, sino en el sistema de aislamiento por proyecto y en los dos modelos de verificación —Vellum Verified y Sentinel Verified— que evalúan la calidad técnica y el riesgo de spam de cada mensaje antes de que llegue a producción.
SMTP testing server for modern teams
El problema con los entornos compartidos
Herramientas como Mailhog —abandonada desde 2020— o Mailpit funcionan bien para desarrollo estrictamente local: cualquier correo que envíe la aplicación aparece en la bandeja. El problema surge cuando se trasladan a servidores de desarrollo compartidos donde conviven varios proyectos.
Un servidor compartido donde todos los proyectos dirigen sus correos a la misma instancia genera dos fricciones reales. Primera: los correos de todos los proyectos se mezclan en una sola bandeja sin ninguna separación. Segunda: cada reinicio de la herramienta borra el historial completo. El primer problema viola un principio elemental de zero-trust aplicado a datos de desarrollo: si un desarrollador no tiene acceso al proyecto A, tampoco debería ver sus correos, aunque sean datos ficticios de staging. El segundo convierte la herramienta en algo inconsistente para flujos de prueba que requieren auditar secuencias de correos completas.
La alternativa de crear un subdominio separado por proyecto —mail-proyecto1.example.com, mail-proyecto2.example.com— distribuye el problema pero lo multiplica: una instancia por proyecto, cada una con su propio puerto, su propia configuración y su propio mantenimiento. No escala con equipos que manejan más de dos o tres proyectos simultáneamente.
Para desarrollo estrictamente local en máquina personal, Mailpit sigue siendo una opción directa y sin fricción. Su limitación aparece cuando se mueve a un servidor compartido donde conviven varios proyectos y varios desarrolladores.
Vellum vs MailHog vs Mailpit
Las tres herramientas comparten el mismo propósito base: interceptar correos SMTP en desarrollo para que no lleguen a la red pública. Las diferencias empiezan ahí mismo.
MailHog fue la opción estándar durante años. Su problema más grande hoy es que el proyecto no tiene mantenimiento activo desde 2020. Sin parches de seguridad, sin actualizaciones de dependencias, sin nuevas versiones. Usarlo en 2026 implica desplegar software que nadie está corrigiendo.
Mailpit es el reemplazo directo de MailHog para uso individual. Tiene mantenimiento activo, es ligero y se instala en segundos. Incluye HTML check —un análisis de compatibilidad CSS/HTML contra más de 175 reglas basadas en los datos de caniemail.com— y análisis de spam opcional mediante integración con SpamAssassin, que requiere un servidor SpamAssassin configurado y corriendo de forma independiente; sin él, el análisis de spam no está disponible. Su límite en contextos de equipo es el mismo que el de MailHog: fue diseñado para un solo desarrollador. Moverlo a un servidor compartido revela lo que no tiene — sin separación por proyecto, sin control de acceso por usuario y sin persistencia entre reinicios por defecto.
Vellum parte de la premisa de que el servidor de desarrollo es compartido. El aislamiento por proyecto, el control de acceso por roles y el almacenamiento persistente no son funciones añadidas encima — son la base. El resultado es una herramienta que funciona igual para un equipo de dos que para uno de quince, con la misma instancia.
| MailHog | Mailpit | Vellum | |
|---|---|---|---|
| Mantenimiento activo | ✗ abandonado 2020 | ✓ | ✓ |
| Aislamiento por proyecto | ✗ | ✗ | ✓ |
| Control de acceso por usuario | ✗ | ✗ | ✓ (OAuth2 + invitación) |
| Almacenamiento persistente | ✗ | parcial | ✓ (BBolt) |
| Análisis de spam | ✗ | ⚠ SpamAssassin (servicio externo) | ✓ (Sentinel Verified, embebido) |
| Verificación de calidad de correo | ✗ | ⚠ HTML check (solo CSS/HTML) | ✓ (Vellum Verified) |
| Renderizado modo oscuro forzado | ✗ | limitado | ✓ |
| Listo para servidor compartido | ✗ | ✗ | ✓ |
Si trabajas solo en máquina local, Mailpit es la elección correcta — es rápido y sin fricción. Si tu equipo comparte un servidor de desarrollo, o si necesitas saber si una plantilla de correo pasaría un filtro de spam real antes de desplegarla, Vellum es la opción que cubre esos huecos.
Vellum funciona perfectamente en máquina personal también. El uso local no requiere configuración adicional más allá del docker-compose.yml base. Las funciones de equipo están disponibles si se necesitan, pero no interfieren si no.
Aislamiento por proyecto y enrutamiento por sender
Vellum resuelve el aislamiento en el nivel del protocolo SMTP. Cada proyecto define sus senders autorizados: las direcciones From que le pertenecen. Cuando llega un correo al servidor, Vellum verifica si el remitente del mensaje corresponde a un sender registrado en algún proyecto. Si el sender no existe, el correo se descarta y la operación devuelve un error de sender no reconocido. Si existe, el correo se enruta a la bandeja exclusiva de ese proyecto.
El acceso a esa bandeja está restringido a los usuarios asociados al proyecto. Un desarrollador que solo pertenece al proyecto A no puede ver los correos del proyecto B, aunque ambos proyectos compartan la misma instancia de Vellum. El aislamiento es estructural: no depende de la disciplina del equipo sino de los permisos del sistema.
El administrador de cada proyecto puede configurar un límite de almacenamiento en megabytes. Una vez alcanzado, los correos más antiguos se eliminan para dar espacio a los nuevos. Esto evita que un proyecto con alto volumen de correos de prueba sature el almacenamiento del servidor compartido.
Autenticación y acceso
Vellum soporta múltiples proveedores de autenticación configurables desde el panel de administración: Google, GitHub, Discord y cualquier proveedor OIDC genérico. También admite autenticación local mediante usuario y contraseña, con acceso por invitación exclusivamente. No hay registro abierto: un usuario nuevo solo puede entrar si un administrador lo invita al sistema.
Toda la configuración de proveedores externos —client ID, client secret, URLs de callback— se gestiona desde la interfaz de Vellum una vez que el servidor está en funcionamiento. No se requiere editar archivos de configuración ni reiniciar el contenedor.
La seguridad de sesión incluye Token Family, un mecanismo que invalida toda la familia de tokens de refresco si detecta un intento de reutilización, y cookies HTTP-only que eliminan el acceso a las credenciales de sesión desde JavaScript.
Desplegar Vellum en un servidor compartido también cambia la dinámica con los equipos de calidad. Un QA puede ser invitado a los proyectos que le correspondan y acceder directamente a los flujos de correo generados en el entorno de desarrollo — sin pedir a ningún desarrollador que reenvíe mensajes, sin disparar entregas reales a direcciones activas y sin acumular bloqueos de servicio por envíos repetidos. La estructura por proyectos y la autenticación por usuario definen exactamente qué puede ver cada persona: el equipo de QA accede solo a lo que le corresponde, con los resultados de Vellum Verified y Sentinel Verified ya adjuntos a cada mensaje. La revisión de flujos de correo deja de ser un proceso de ida y vuelta entre disciplinas y se convierte en una inspección autoservicio que QA puede ejecutar a su ritmo antes de promover a staging o beta.
Vellum Verified: salud técnica del correo
Vellum Verified es el modelo de análisis que evalúa la integridad técnica de cada correo recibido. Comprueba cabeceras, estándares HTML, métricas de entregabilidad y estructura del mensaje. El objetivo no es bloquear ningún correo: es identificar qué tiene que podría provocar que un servidor de producción lo rechace o lo clasifique como no deseado.
El resultado es un conjunto de checks por correo, con detalle de lo que pasó y lo que falló. Si el correo tiene una cabecera From malformada, HTML con atributos obsoletos o carece de versión en texto plano, Vellum Verified lo señala con la descripción del problema. El desarrollador ve exactamente qué generó su aplicación y por qué podría fallar en un entorno real.
El puntaje que produce Vellum Verified es el objetivo de calidad por el que vale la pena trabajar. Un correo que obtiene esa certificación está construido respetando los estándares que los proveedores de correo reales utilizan para evaluar mensajes entrantes.
Sentinel Verified: análisis probabilístico de spam
Sentinel Verified analiza el contenido del correo —asunto y cuerpo en texto plano— y calcula la probabilidad de que un filtro de spam real lo clasifique como no deseado. No usa reglas heurísticas fijas: usa un clasificador estadístico entrenado con ejemplos reales de spam y ham que produce una puntuación entre 0 y 1.
Cuando la puntuación supera el umbral de decisión, Sentinel identifica los tokens del mensaje que más contribuyeron a esa clasificación y los expone como disparadores. El desarrollador ve cuáles palabras o frases concretas de su plantilla están activando señales de spam, y puede corregirlas antes de que lleguen a un entorno donde el rechazo tenga consecuencias reales.
El modelo vive embebido en el binario de Vellum y opera en milisegundos con impacto mínimo en CPU y RAM. La lógica exacta del clasificador —Naive Bayes multinomial con suavizado de Laplace y conversión softmax— está documentada en detalle en el segundo artículo de esta serie.
Vellum incluye una sección de documentación accesible desde la propia interfaz web. Una vez que el servidor está en marcha, la guía detallada de cada módulo está disponible sin necesidad de consultar fuentes externas.
Modo oscuro forzado y viewports
Los clientes de correo aplican su propio tratamiento al HTML de los mensajes. Outlook en Windows y otros clientes con modo oscuro activo fuerzan una inversión de colores que puede romper el diseño de plantillas construidas solo para el modo claro. Vellum renderiza los correos simulando ese comportamiento: modo claro estándar, modo oscuro nativo y modo oscuro forzado con el algoritmo de inversión que aplican clientes como Outlook en Windows.
El mismo correo se puede revisar en múltiples viewports —escritorio, tablet, móvil— desde la misma interfaz. Esto elimina la necesidad de herramientas externas o clientes de correo reales para verificar cómo se verá el mensaje bajo condiciones distintas.
Desplegar Vellum con Docker
Vellum se distribuye como imagen Docker disponible en Docker Hub (docker.io/gerbo67/vellum:latest) y en GitHub Container Registry (ghcr.io/gerbo67/vellum:latest). El despliegue mínimo funcional requiere exponer dos puertos: el 8025 para la interfaz web y el 2525 para el servidor SMTP.
services:
vellum:
image: docker.io/gerbo67/vellum:latest
container_name: vellum
restart: unless-stopped
ports:
- "8025:8025"
- "2525:2525"
volumes:
- vellum_data:/data
environment:
VELLUM_PORT: 8025
VELLUM_SMTP_PORT: 2525
VELLUM_DB_PATH: /data/vellum.db
VELLUM_BASE_URL: http://localhost:8025
VELLUM_MAX_EMAIL_SIZE: 26214400
VELLUM_JWT_SECRET: ""
LOG_LEVEL: info
LOG_FORMAT: text
volumes:
vellum_data:
driver: local La base de datos que usa Vellum es BBolt: un único archivo portable que contiene todos los proyectos, usuarios, correos y configuración del sistema. Los respaldos son una copia del volumen. Sin PostgreSQL, sin Redis, sin dependencias externas.
Con VELLUM_JWT_SECRET vacío el servidor genera un secreto automáticamente en cada inicio. Para entornos donde los contenedores se reinician con frecuencia conviene asignar un valor estático para que las sesiones existentes sobrevivan al reinicio.
En local, Vellum funciona perfectamente con VELLUM_BASE_URL: http://localhost:8025. En un servidor compartido accesible desde red, esa variable debe apuntar al dominio o IP real desde donde los desarrolladores acceden a la interfaz. Los proveedores OAuth2 necesitan esa URL para construir correctamente sus URLs de callback.
Por qué Go y React con SSE
Vellum está construido con Go en el backend y React en el frontend. Go produce un binario compacto con baja huella de memoria, arranque instantáneo y despliegue sin dependencias de runtime. El contenedor resultante es pequeño y predecible.
La actualización en tiempo real de la bandeja de entrada usa Server-Sent Events (SSE). Cuando llega un correo al servidor SMTP, el evento se propaga al cliente sin polling: la bandeja del proyecto correspondiente se actualiza al instante sin necesidad de recargar la página. SSE es unidireccional —del servidor al cliente— y es exactamente el modelo de comunicación que necesita una bandeja de entrada reactiva: el servidor notifica, el cliente renderiza.