
Semaphore UI 2.19 es la versión más grande de la línea 2.x. Introduce Flujos de trabajo con un editor gráfico, permite a los runners ejecutar tareas en contenedores Docker y pods de Kubernetes, enseña a Semaphore a emitir tokens de identidad JWT de corta duración a las tareas en ejecución, añade rotación de claves de cifrado, corrige definitivamente la fiabilidad de los runners e incluye una larga lista de cambios de refuerzo de la seguridad.
La línea abarca las versiones v2.19.0 a v2.19.14. Las versiones de parche se enumeran al final.
Aspectos destacados
- Flujos de trabajo (Beta) — encadena plantillas de tarea en un pipeline con puertas de aprobación, dibujado en un editor gráfico y observado en vivo en el mismo lienzo.
- Ejecutores Docker y Kubernetes — los runners pueden ejecutar cada tarea en un contenedor o pod nuevo (Pro / Enterprise).
- Tokens de identidad JWT para tareas — autenticación sin claves desde los playbooks hacia Vault, AWS, GCP, Azure y cualquier otro servicio que acepte tokens OIDC.
- Rotación de claves de cifrado — un llavero etiquetado con recarga en caliente y un comando
vaults check. - Variables de encuesta como variables de entorno, además de los tipos
int,textyenumcon nuevo estilo. - Paginación real del lado del servidor del historial de tareas — los proyectos con millones de tareas siguen siendo rápidos.
- Fiabilidad de los runners — estado en línea/desconectado, tokens de registro de un solo uso con hash y recuperación automática de tareas atascadas en un runner caído.
- Registro de depuración selectivo con
SEMAPHORE_DEBUG_FILTER. - Refuerzo de la seguridad: comprobación de la contraseña actual, validación del origen CSRF, cookies seguras, validación más estricta de entradas en toda la API.
- BoltDB eliminado — solo SQLite, MySQL y PostgreSQL.
Flujos de trabajo (Beta)
Un flujo de trabajo es un grafo de plantillas de tarea que se ejecuta como una sola unidad. Cada nodo es una tarea (ejecuta una plantilla), una aprobación (pausa la ejecución hasta que un usuario aprueba o rechaza) o una nota (anotación libre que nunca se ejecuta). Las aristas llevan una condición: en caso de éxito, en caso de fallo o siempre.
Los flujos de trabajo aparecen como un nuevo elemento Flujos de trabajo en la barra lateral del proyecto, marcado con una etiqueta Beta. Están disponibles en la edición Pro; durante la beta están habilitados independientemente del plan.
Editor gráfico

El editor es un lienzo a página completa construido sobre Drawflow:
- arrastra nodos desde la paleta y conéctalos arrastrando desde el conector de un nodo;
- haz clic en una arista para cambiar su condición; las aristas tienen códigos de color y hay una leyenda en la esquina;
- haz clic en un nodo para editar sus propiedades en el panel lateral: plantilla, modo de convergencia (todos los padres / cualquier padre), tiempo de espera y mensaje de aprobación, texto de la nota;
- las aristas hacia el propio nodo y los ciclos se rechazan mientras los dibujas, y un panel Problemas refleja la validación del lado del servidor para que un grafo roto no pueda guardarse;
- las posiciones de los nodos se conservan; los flujos de trabajo creados mediante la API sin posiciones reciben una disposición topológica automática;
- haz zoom con la barra de herramientas o
Ctrl+ rueda del ratón, arrastra el lienzo para desplazarte, contrae la paleta para ganar espacio; - Versión inicial inicializa el versionado de las ejecuciones (
1.4.0,1.4.1, …); la versión se propaga a cada tarea que lanza la ejecución.

Vista de ejecución en vivo
La vista de ejecución reutiliza el mismo lienzo. Cada nodo muestra el estado de su tarea, el nodo activo se resalta,
y las aprobaciones pendientes muestran botones Aprobar / Rechazar directamente en el lienzo. Un botón Detener
fuerza la detención de todas las tareas de la ejecución, rechaza las aprobaciones pendientes y marca la ejecución como stopped.

Los estados de ejecución son running, approval, success, failed y stopped. La progresión del flujo de trabajo la
dirige el servidor: cuando cualquier tarea del flujo termina, se programan los siguientes nodos, de modo que una plantilla
sin hijos con ejecución automática ya no bloquea la ejecución.

Parámetros de tarea por nodo
Cada nodo de tarea puede sobrescribir los parámetros que pasa a su plantilla (variables, inventario, rama, argumentos, versión, mensaje), del mismo modo que una ejecución manual.
API
GET/POST /api/project/{id}/workflows
GET/PUT/DELETE /api/project/{id}/workflows/{workflow_id}
POST /api/project/{id}/workflows/{workflow_id}/run
GET /api/project/{id}/workflows/{workflow_id}/runs
GET /api/project/{id}/workflows/{workflow_id}/runs/{run_id}
POST /api/project/{id}/workflows/{workflow_id}/runs/{run_id}/stop
GET /api/project/{id}/workflows/{workflow_id}/runs/{run_id}/artifacts
GET /api/project/{id}/workflows/{workflow_id}/runs/{run_id}/approvals
POST /api/project/{id}/workflows/{workflow_id}/runs/{run_id}/approvals/{node_id}
Limitaciones conocidas de la beta: sin minimapa, deshacer/rehacer ni selección múltiple; los artefactos del flujo de trabajo
(valores de set_stats) todavía no fluyen entre tareas ejecutadas en runners remotos.
Ejecutores Docker y Kubernetes (Pro / Enterprise)
Los runners pueden ejecutar cada tarea en un entorno aislado en lugar de directamente en el host del runner.
El ejecutor se selecciona una vez por proceso del runner con runner.executor.type (local, docker,
k8s).
Docker (runner.executor.docker, Pro):
| Opción | Variable de entorno | Valor predeterminado |
|---|---|---|
host |
SEMAPHORE_RUNNER_DOCKER_HOST |
socket local |
tls_verify, cert_path |
SEMAPHORE_RUNNER_DOCKER_TLS_VERIFY, …_CERT_PATH |
|
image |
SEMAPHORE_RUNNER_DOCKER_IMAGE |
semaphoreui/job:latest |
helper_image |
SEMAPHORE_RUNNER_DOCKER_HELPER_IMAGE |
semaphoreui/helper:latest |
network |
SEMAPHORE_RUNNER_DOCKER_NETWORK |
bridge |
pull_policy |
SEMAPHORE_RUNNER_DOCKER_PULL_POLICY |
if-not-present |
cpu_limit, memory_limit |
SEMAPHORE_RUNNER_DOCKER_CPU_LIMIT, …_MEMORY_LIMIT |
|
privileged |
SEMAPHORE_RUNNER_DOCKER_PRIVILEGED |
false |
poll_interval_seconds, cleanup_grace_seconds |
…_POLL_INTERVAL_SECONDS, …_CLEANUP_GRACE_SECONDS |
2, 30 |
Kubernetes (runner.executor.k8s, Enterprise):
| Opción | Variable de entorno | Valor predeterminado |
|---|---|---|
kubeconfig |
SEMAPHORE_RUNNER_K8S_KUBECONFIG |
dentro del clúster |
namespace |
SEMAPHORE_RUNNER_K8S_NAMESPACE |
semaphore |
image |
SEMAPHORE_RUNNER_K8S_IMAGE |
semaphoreui/job:latest |
helper_image |
SEMAPHORE_RUNNER_K8S_HELPER_IMAGE |
semaphoreui/helper:latest |
service_account |
SEMAPHORE_RUNNER_K8S_SERVICE_ACCOUNT |
default |
pull_secrets |
SEMAPHORE_RUNNER_K8S_PULL_SECRETS |
|
poll_interval_seconds, cleanup_grace_seconds |
…_POLL_INTERVAL_SECONDS, …_CLEANUP_GRACE_SECONDS |
3, 30 |
CI publica dos imágenes nuevas: semaphoreui/job (Ansible, Terraform, OpenTofu, Terragrunt,
paramiko) y semaphoreui/helper. Una plantilla puede sobrescribir la imagen para sus propias tareas con el nuevo
campo Imagen del ejecutor en el formulario de plantilla (se muestra con una insignia Actualizar a PRO cuando la función
de ejecutor no está licenciada).
La conexión del runner también incorpora runner.connection.server_ca_cert_file y
runner.connection.skip_tls_verify.
Tokens de identidad JWT para tareas
Semaphore puede actuar como un proveedor de identidad de tipo OIDC para las tareas en ejecución, de modo que un playbook pueda autenticarse ante Vault, endpoints STS en la nube o servicios internos sin credenciales de larga duración.

- Actívalo por plantilla con Emitir JWT al ejecutor de la tarea; define una o más audiencias y un
TTL (limitado por
jwt.max_ttl). - La tarea recibe el token en la variable de entorno
SEMAPHORE_JWT. - Los tokens se firman con ES256 (ECDSA P‑256) y solo contienen IDs:
task_id,project_id,template_id,user_idmás los claims estándariss,sub,aud,exp,nbf,iat,jti. - Las claves públicas se publican en
GET /.well-known/jwks.json.
Configuración del servidor:
"jwt": {
"enabled": true,
"issuer": "https://semaphore.example.com",
"default_ttl": "1h",
"max_ttl": "24h"
}
Variables de entorno: SEMAPHORE_JWT_ENABLED, SEMAPHORE_JWT_ISSUER, SEMAPHORE_JWT_DEFAULT_TTL,
SEMAPHORE_JWT_MAX_TTL.
Variables de encuesta
Entregar una variable como variable de entorno
Una variable de encuesta ahora tiene un ajuste Pasar variable como: la forma propia de la CLI de cada aplicación (--extra-vars para
Ansible, -var para Terraform/OpenTofu, un argumento de CLI para scripts de shell) o una variable de entorno del
proceso. El nombre de la variable se usa tal cual, así que un usuario de Terraform simplemente la llama TF_VAR_region.
Las variables de entorno no aparecen en los listados de procesos, lo que las convierte en la opción más segura para
secretos.

Nuevos tipos
int— entrada numérica con validación;text— texto multilínea;enum— editor con nuevo estilo, pares nombre/valor y un valor predeterminado.

El diálogo de tarea muestra cada tipo según corresponde:

Se almacenan en el JSON survey_vars existente — no se requiere migración.
Plantillas y tareas
-
Selector dinámico de playbooks. El campo Ruta al archivo del playbook enumera los playbooks encontrados en el repositorio (
GET /api/project/{id}/repositories/{repository_id}/playbooks). La lista sigue la rama seleccionada y vuelve a texto libre cuando el repositorio no puede leerse. -
Omitir la instalación de Ansible Galaxy — opción por plantilla, opcionalmente sobrescribible por tarea, para omitir la instalación de roles y colecciones desde
requirements.yml. -
Variables tipadas en los grupos de variables, incluidos números:

-
Paginación del historial de tareas. La página Historial antes obtenía las 200 tareas más recientes y las paginaba en el cliente, por lo que todo lo anterior era inaccesible. El backend ahora devuelve una página cada vez usando un cursor keyset (
?count=20&before=<task_id>, cabecera de respuestaX-Has-Next) sinCOUNT(*)niOFFSET. El pie de página ofrece Filas por página y controles de anterior/siguiente. La misma paginación se aplica a la lista de tareas por plantilla y al panel de control.
-
Las listas de tareas se recargan como máximo una vez cada 5 segundos; se eliminaron varias peticiones redundantes.
-
Las programaciones se validan con el analizador cron del lado del servidor, así que cliente y servidor ya no discrepan.
-
La sobrescritura de rama en una tarea solo se acepta cuando la plantilla lo permite.
-
Las operaciones Git se serializan por directorio de repositorio. Las plantillas con Permitir tareas paralelas comparten una única copia de trabajo, y
git pull/git checkoutconcurrentes podían corromperla. La actualización y el checkout ahora forman una única sección crítica, tanto para la ejecución local como en runners, incluidos los repositorios de inventario.
Runners

-
Estado en línea / desconectado en la página Runners, derivado de la actividad del heartbeat.
-
Tokens de registro de un solo uso. Un runner puede crearse primero en la interfaz y registrarse después con un token
smrs_…que se muestra una sola vez, se almacena únicamente como hash SHA‑256 y caduca al cabo de una hora. El diálogo muestra comandos listos para copiar para variables de entorno, archivo de configuración y Docker. Regenerar el token restablece un runner ya registrado para que pueda volver a registrarse.
SEMAPHORE_WEB_ROOT=https://semaphore.example.com \ SEMAPHORE_RUNNER_REGISTRATION_TOKEN=smrs_… \ semaphore runner register --config ./config.runner.json semaphore runner start --config ./config.runner.json -
Recuperación de tareas colgadas. Los runners envían la hora de inicio de su proceso (
X-Runner-Started-At). Un runner que deja de sondear se marca como desconectado trasrunners.offline_timeout_sec(120 s): no recibe nuevas tareas y sus tareas en estadostartingse reasignan. Trasrunners.task_fail_timeout_sec(420 s) sus tareasrunningse marcan como fallidas con un mensaje claro. Un runner que se reinició y perdió su pool de trabajos en memoria se detecta de inmediato. La reconciliación se ejecuta cadarunners.reconcile_interval_sec(30 s). -
Las tareas reasignadas desde un runner se terminan en el runner antiguo.
-
El mecanismo de respaldo de runners obsoletos ha desaparecido: cuando todos los runners están desconectados, las tareas esperan en la cola en lugar de enviarse a un runner que no ha sondeado durante hasta 30 minutos.
-
Claves de cifrado RSA por runner eliminadas. El tráfico runner‑servidor se apoya en TLS; esto elimina el paso de intercambio de claves del registro y de
setup. -
Corregida una fuga de conexiones TCP en el cliente del runner; los tokens de registro no válidos devuelven
400.
Secretos y cifrado
- Rotación de claves de cifrado. El nuevo bloque
encryptiondescribe un llavero etiquetado:keysen línea (valor o archivo), o unkeys_folderdonde cada archivo es una clave con el nombre del archivo, además de punterosactivepara la clave de secretos y la clave de opciones. El texto cifrado ahora lleva un ID de clave, de modo que las claves pueden rotarse sin un recifrado masivo.encryption.keys_fileconkeys_poll_interval(por defecto15s) recarga el llavero en caliente. Nueva CLI:semaphore vaults check;semaphore vaults rekeyse reescribió en torno al llavero. El antiguoaccess_key_encryptionplano sigue funcionando. option_encryption— una clave independiente para las opciones almacenadas en la base de datos.- Tipo de almacenamiento de secretos OpenBao (enrutado a través del proveedor de Vault) con su propio icono.
- AWS Secrets Manager sin credenciales estáticas — una casilla Usar rol IAM.
- Opción para omitir la verificación TLS en los almacenamientos Vault/OpenBao.
- Los campos de secretos sincronizados y de solo lectura ya no se borran al actualizar.
Observabilidad
- Registro de depuración por espacios de nombres.
--debug-filter/SEMAPHORE_DEBUG_FILTERselecciona qué subsistemas emiten salida de depuración, al estilo dedebugde Node.js:runner,runner,task_pool,task_*,*,*,-db. Espacios de nombres disponibles:runner,task_pool,task_runner,task_logger,git,terraform,session,ldap,schedule,db,ha. El filtro solo se aplica cuando el nivel de registro esDEBUG; nunca eleva el nivel. Los hooks de syslog respetan el mismo filtro. - Muchas nuevas sentencias de depuración contextuales en runners, tareas y autenticación; el espacio de trabajo seleccionado se imprime al arrancar.
Seguridad

- Cambiar la contraseña ahora requiere la contraseña actual (CWE‑620).
- Validación de Origin / Referer en las peticiones que cambian el estado (refuerzo contra CSRF).
- Las cookies de sesión se marcan como
Securecuando se sirven por HTTPS. - Los tokens de registro de runners se almacenan con hash y caducan; se eliminaron las claves de cifrado por runner.
- La creación de roles personalizados comprueba los permisos de quien la solicita (corrección de escalada de privilegios).
- Validación de URLs de Git; se pasa
--end-of-optionsa git para que una referencia manipulada no pueda leerse como una opción; se comprueba el formato de los hashes de commit; las ramas se validan antes de explorar el repositorio; las rutas de playbook se validan. - Se validan las cargas útiles de las claves de acceso y el campo
appde la plantilla. - Los claims JWT solo llevan IDs — no se filtran nombres ni correos electrónicos a sistemas externos.
- Los tokens de runner ya no se escriben en las copias de seguridad del proyecto.
- La API retorna tras un error de escritura en lugar de continuar con una respuesta parcialmente escrita.
- SLA de seguridad publicado en
SECURITY.md; los artefactos de las versiones se firman con la clave GPG[email protected].
Interfaz y localización

- Traducción al checo.
- Tarjetas desplegables para las secciones JWT y programación del formulario de plantilla.
- El icono de copiar al portapapeles es visible en el modo claro; corregidos los indicadores giratorios de tareas en ejecución; corregido el relleno del formulario de plantilla; etiqueta Beta en los flujos de trabajo.
- La extracción de variables de integración conserva los objetos y arrays JSON en lugar de convertirlos en cadenas.
Notas de actualización
Cambios incompatibles y de comportamiento
- BoltDB ha desaparecido.
boltya no es un dialecto válido; el servidor se niega a arrancar con “Bolt is not supported starting from version 2.19”. Migra primero a SQLite, MySQL o PostgreSQL. - Claves de cifrado de runners eliminadas. El servidor y los runners deben estar ambos en 2.19. Asegúrate de que el tráfico runner‑servidor esté protegido con TLS. El aprovisionamiento de runners mediante scripts que esperaba la clave debe actualizarse.
- Las API de listas de tareas están paginadas.
GET /api/project/{id}/tasks/lastaceptacountybefore;limitsigue aceptándose, pero los clientes que dependían de recibir las 200 tareas más recientes en una sola respuesta deben paginar. - Sin respaldo de runners obsoletos. Con todos los runners desconectados, las tareas permanecen en cola.
- Indicador
activedel runner eliminado del registro. - Las copias de seguridad del proyecto ya no contienen tokens de runner.
- SQLite:
v2.19.14reconstruye las tablassessionytaskpara añadir claves foráneas correctas (corrige la eliminación de usuarios). Se eliminan las sesiones huérfanas. Haz una copia de seguridad de la base de datos antes de actualizar.
Nueva configuración
jwt, runners, encryption, option_encryption, secrets_path, db.dialect,
runner.executor.{type,docker,k8s}, runner.connection.{server_ca_cert_file,skip_tls_verify},
runner.registration_token_file, runner.token_file. Todas son opcionales; las configuraciones existentes siguen
funcionando. Se regeneraron config.schema.yaml y la documentación de referencia de la configuración.
Migraciones de base de datos
v2.18.6 (jwt_params de plantilla), v2.18.15 (tablas de flujos de trabajo), v2.19.2 (runner.started_at),
v2.19.11 (project__workflow_node.task_params_id), v2.19.12 (project__template.executor_image),
v2.19.14 (reconstrucción de session/task en SQLite). Corregida la compatibilidad de migraciones con MariaDB 12.1.
Versiones de parche
| Versión | Cambios |
|---|---|
| 2.19.8 | Corregida la migración de SQLite; corregida la eliminación de usuarios (claves foráneas de session/task); comparación de cadenas sin distinguir mayúsculas en las consultas a la BD |
| 2.19.9 | Variable de entorno SEMAPHORE_RUNNER_EXECUTOR_TYPE; limpieza de omitempty en la configuración |
| 2.19.10 | Corrección de la configuración del ejecutor; corrección de la opción de build de Docker |
| 2.19.11 | El espacio de trabajo seleccionado se imprime en los logs; etiqueta latest para la imagen helper; pruebas de migración de BD |
| 2.19.12 | Corregido puntero nulo en las opciones de configuración del runner; corrección de la propagación de errores |
| 2.19.14 | Corregido el manejo del secrets_path heredado en la configuración |
Dependencias
Go 1.26; go-git 5.19, go-oidc 3.19, golang.org/x/crypto 0.53, go-ldap 3.4.13,
modernc.org/sqlite 1.52. Documentación añadida como submódulo de git; THIRD-PARTY-LICENSES.md regenerado.
