
Semaphore UI 2.19 ist das größte Release der 2.x-Linie. Es führt Workflows mit einem grafischen Editor ein, lässt Runner Aufgaben in Docker-Containern und Kubernetes-Pods ausführen, bringt Semaphore bei, laufenden Aufgaben kurzlebige JWT-Identitätstoken auszustellen, ergänzt die Rotation von Verschlüsselungsschlüsseln, behebt die Runner-Zuverlässigkeit endgültig und liefert eine lange Liste an Sicherheitshärtungen.
Die Linie umfasst die Releases v2.19.0 bis v2.19.14. Die Patch-Releases sind am Ende aufgeführt.
Highlights
- Workflows (Beta) — Aufgabenvorlagen zu einer Pipeline mit Freigabestufen verketten, in einem grafischen Editor gezeichnet und live auf derselben Arbeitsfläche beobachtet.
- Docker- und Kubernetes-Executoren — Runner können jede Aufgabe in einem frischen Container oder Pod ausführen (Pro / Enterprise).
- JWT-Identitätstoken für Aufgaben — schlüssellose Authentifizierung aus Playbooks gegenüber Vault, AWS, GCP, Azure und allem anderen, das OIDC-Token akzeptiert.
- Rotation von Verschlüsselungsschlüsseln — ein benannter Schlüsselbund mit Hot Reload und einem
vaults check-Befehl. - Survey-Variablen als Umgebungsvariablen, plus die Typen
int,textund ein neu gestaltetesenum. - Echte serverseitige Paginierung der Aufgabenhistorie — Projekte mit Millionen von Aufgaben bleiben schnell.
- Runner-Zuverlässigkeit — Online-/Offline-Status, einmalige gehashte Registrierungstoken und automatische Wiederherstellung von Aufgaben, die auf einem toten Runner hängen.
- Selektives Debug-Logging mit
SEMAPHORE_DEBUG_FILTER. - Sicherheitshärtung: Prüfung des aktuellen Passworts, CSRF-Origin-Validierung, sichere Cookies, strengere Eingabevalidierung in der gesamten API.
- BoltDB entfernt — nur noch SQLite, MySQL und PostgreSQL.
Workflows (Beta)
Ein Workflow ist ein Graph aus Aufgabenvorlagen, der als eine Einheit läuft. Jeder Knoten ist entweder eine Aufgabe (führt eine Vorlage aus), eine Freigabe (pausiert den Lauf, bis ein Benutzer genehmigt oder ablehnt) oder eine Notiz (freie Anmerkung, die nie ausgeführt wird). Kanten tragen eine Bedingung: bei Erfolg, bei Fehler oder immer.
Workflows erscheinen als neuer Eintrag Workflows in der Projekt-Seitenleiste, gekennzeichnet mit einem Beta-Chip. Sie sind in der Pro-Edition verfügbar; während der Beta sind sie unabhängig vom Plan aktiviert.
Grafischer Editor

Der Editor ist eine ganzseitige Arbeitsfläche auf Basis von Drawflow:
- Knoten aus der Palette ziehen und durch Ziehen von einem Knoten-Anschluss verbinden;
- auf eine Kante klicken, um ihre Bedingung zu ändern; Kanten sind farblich kodiert und eine Legende sitzt in der Ecke;
- auf einen Knoten klicken, um seine Eigenschaften im Seitenpanel zu bearbeiten: Vorlage, Konvergenzmodus (alle Eltern / ein beliebiger Elternknoten), Freigabe-Timeout und -Nachricht, Notiztext;
- Selbstkanten und Zyklen werden bereits beim Zeichnen abgewiesen, und ein Probleme-Panel spiegelt die serverseitige Validierung, sodass ein defekter Graph nicht gespeichert werden kann;
- Knotenpositionen werden gespeichert; über die API ohne Positionen erstellte Workflows erhalten automatisch ein topologisches Layout;
- Zoomen über die Symbolleiste oder
Ctrl+ Mausrad, Arbeitsfläche zum Verschieben ziehen, Palette einklappen, um Platz zu gewinnen; - Startversion initialisiert die Versionierung der Läufe (
1.4.0,1.4.1, …); die Version wird an jede vom Lauf gestartete Aufgabe weitergegeben.

Live-Laufansicht
Die Laufansicht verwendet dieselbe Arbeitsfläche. Jeder Knoten zeigt seinen Aufgabenstatus, der aktive
Knoten ist hervorgehoben, und ausstehende Freigaben zeigen die Schaltflächen Genehmigen / Ablehnen
direkt auf der Arbeitsfläche. Eine Stopp-Schaltfläche stoppt jede Aufgabe des Laufs erzwungen,
lehnt ausstehende Freigaben ab und markiert den Lauf als stopped.

Die Laufstatus sind running, approval, success, failed und stopped. Der Fortschritt eines
Workflows wird vom Server gesteuert: Sobald eine Workflow-Aufgabe endet, werden die nächsten Knoten
eingeplant, sodass eine Vorlage ohne Autorun-Kinder den Lauf nicht mehr zum Stillstand bringt.

Aufgabenparameter pro Knoten
Jeder Aufgabenknoten kann die Parameter überschreiben, die er an seine Vorlage übergibt (Variablen, Inventar, Branch, Argumente, Version, Nachricht), genau wie ein manueller Lauf.
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}
Bekannte Einschränkungen der Beta: keine Minimap, kein Undo/Redo und keine Mehrfachauswahl;
Workflow-Artefakte (set_stats-Werte) fließen noch nicht zwischen Aufgaben, die auf entfernten Runnern
ausgeführt werden.
Docker- und Kubernetes-Executoren (Pro / Enterprise)
Runner können jede Aufgabe in einer isolierten Umgebung ausführen statt direkt auf dem Runner-Host.
Der Executor wird einmal pro Runner-Prozess mit runner.executor.type ausgewählt (local, docker,
k8s).
Docker (runner.executor.docker, Pro):
| Option | Umgebungsvariable | Standard |
|---|---|---|
host |
SEMAPHORE_RUNNER_DOCKER_HOST |
lokaler Socket |
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):
| Option | Umgebungsvariable | Standard |
|---|---|---|
kubeconfig |
SEMAPHORE_RUNNER_K8S_KUBECONFIG |
In-Cluster |
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 |
Zwei neue Images werden von der CI veröffentlicht: semaphoreui/job (Ansible, Terraform, OpenTofu,
Terragrunt, paramiko) und semaphoreui/helper. Eine Vorlage kann das Image für ihre eigenen Aufgaben
mit dem neuen Feld Executor-Image im Vorlagenformular überschreiben (mit einem Upgrade to PRO-Badge
angezeigt, wenn die Executor-Funktion nicht lizenziert ist).
Die Runner-Verbindung erhielt außerdem runner.connection.server_ca_cert_file und
runner.connection.skip_tls_verify.
JWT-Identitätstoken für Aufgaben
Semaphore kann für laufende Aufgaben als Identitätsanbieter im OIDC-Stil auftreten, sodass sich ein Playbook ohne langlebige Zugangsdaten bei Vault, Cloud-STS-Endpunkten oder internen Diensten authentifizieren kann.

- Pro Vorlage mit JWT an Task-Runner ausstellen aktivieren; eine oder mehrere Audiences und
eine TTL festlegen (begrenzt durch
jwt.max_ttl). - Die Aufgabe erhält das Token in der Umgebungsvariable
SEMAPHORE_JWT. - Token sind ES256-signiert (ECDSA P-256) und tragen nur IDs:
task_id,project_id,template_id,user_idplus die Standard-Claimsiss,sub,aud,exp,nbf,iat,jti. - Öffentliche Schlüssel werden unter
GET /.well-known/jwks.jsonveröffentlicht.
Serverkonfiguration:
"jwt": {
"enabled": true,
"issuer": "https://semaphore.example.com",
"default_ttl": "1h",
"max_ttl": "24h"
}
Umgebungsvariablen: SEMAPHORE_JWT_ENABLED, SEMAPHORE_JWT_ISSUER, SEMAPHORE_JWT_DEFAULT_TTL,
SEMAPHORE_JWT_MAX_TTL.
Survey-Variablen
Eine Variable als Umgebungsvariable übergeben
Eine Survey-Variable hat jetzt die Einstellung Variable übergeben als: der app-spezifische CLI-Weg
(--extra-vars für Ansible, -var für Terraform/OpenTofu, ein CLI-Argument für Shell-Skripte) oder
eine Prozess-Umgebungsvariable. Der Variablenname wird unverändert verwendet, ein Terraform-Nutzer
nennt sie also einfach TF_VAR_region. Umgebungsvariablen erscheinen nicht in Prozesslisten, was sie
zur sichereren Wahl für Secrets macht.

Neue Typen
int— numerische Eingabe mit Validierung;text— mehrzeiliger Text;enum— neu gestalteter Editor mit Name/Wert-Paaren und einem Standardwert.

Der Aufgabendialog stellt jeden Typ entsprechend dar:

Gespeichert im bestehenden survey_vars-JSON — keine Migration erforderlich.
Vorlagen und Aufgaben
-
Dynamische Playbook-Auswahl. Das Feld Pfad zur Playbook-Datei listet die im Repository gefundenen Playbooks auf (
GET /api/project/{id}/repositories/{repository_id}/playbooks). Die Liste folgt dem gewählten Branch und fällt auf Freitext zurück, wenn das Repository nicht gelesen werden kann. -
Ansible-Galaxy-Installation überspringen — Option pro Vorlage, optional pro Aufgabe überschreibbar, um die Installation von Rollen und Collections aus
requirements.ymlzu überspringen. -
Typisierte Variablen in Variablengruppen, einschließlich Zahlen:

-
Paginierung der Aufgabenhistorie. Die Historie-Seite lud bisher die neuesten 200 Aufgaben und blätterte clientseitig durch sie, sodass alles Ältere unerreichbar war. Das Backend liefert jetzt jeweils eine Seite über einen Keyset-Cursor (
?count=20&before=<task_id>, Antwort-HeaderX-Has-Next) ohneCOUNT(*)und ohneOFFSET. Die Fußzeile bietet Zeilen pro Seite sowie Zurück-/Weiter-Steuerung. Dieselbe Paginierung gilt für die Aufgabenliste pro Vorlage und das Dashboard.
-
Aufgabenlisten werden höchstens alle 5 Sekunden neu geladen; mehrere redundante Anfragen wurden entfernt.
-
Zeitpläne werden mit dem serverseitigen Cron-Parser validiert, sodass Client und Server nicht mehr voneinander abweichen.
-
Das Überschreiben des Branch in einer Aufgabe wird nur akzeptiert, wenn die Vorlage es erlaubt.
-
Git-Operationen werden pro Repository-Verzeichnis serialisiert. Vorlagen mit Parallele Aufgaben erlauben teilen sich eine Arbeitskopie, und gleichzeitige
git pull/git checkoutkonnten sie beschädigen. Update und Checkout bilden jetzt einen einzigen kritischen Abschnitt, sowohl bei lokaler als auch bei Runner-Ausführung, einschließlich Inventar-Repositories.
Runner

-
Online-/Offline-Status auf der Runner-Seite, abgeleitet aus der Heartbeat-Erreichbarkeit.
-
Einmalige Registrierungstoken. Ein Runner kann zuerst in der UI angelegt und später mit einem
smrs_…-Token registriert werden, das einmal angezeigt wird, nur als SHA-256-Hash gespeichert ist und nach einer Stunde abläuft. Der Dialog zeigt fertige Befehle zum Kopieren für Umgebungsvariablen, Konfigurationsdatei und Docker. Das Neugenerieren des Tokens setzt einen bereits registrierten Runner zurück, sodass er erneut registriert werden kann.
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 -
Wiederherstellung hängender Aufgaben. Runner senden ihre Prozess-Startzeit (
X-Runner-Started-At). Ein Runner, der nicht mehr abfragt, wird nachrunners.offline_timeout_sec(120 s) als offline markiert: Er erhält keine neuen Aufgaben, und seinestarting-Aufgaben werden neu zugewiesen. Nachrunners.task_fail_timeout_sec(420 s) werden seinerunning-Aufgaben mit einer klaren Meldung als fehlgeschlagen markiert. Ein Runner, der neu gestartet wurde und seinen In-Memory-Job-Pool verloren hat, wird sofort erkannt. Der Abgleich läuft allerunners.reconcile_interval_sec(30 s). -
Aufgaben, die einem Runner entzogen und neu zugewiesen werden, werden auf dem alten Runner beendet.
-
Der Fallback auf veraltete Runner ist weg: Sind alle Runner offline, warten Aufgaben in der Warteschlange, statt an einen Runner verteilt zu werden, der bis zu 30 Minuten nicht abgefragt hat.
-
RSA-Verschlüsselungsschlüssel pro Runner entfernt. Der Runner-Server-Verkehr stützt sich auf TLS; damit entfällt der Schlüsselaustausch-Schritt bei Registrierung und
setup. -
Ein TCP-Verbindungsleck im Runner-Client wurde behoben; ungültige Registrierungstoken liefern
400.
Secrets und Verschlüsselung
- Rotation von Verschlüsselungsschlüsseln. Der neue
encryption-Block beschreibt einen benannten Schlüsselbund: Inline-keys(Wert oder Datei) oder einkeys_folder, in dem jede Datei ein Schlüssel mit dem Dateinamen als Name ist, plusactive-Zeiger für den Secret-Schlüssel und den Options-Schlüssel. Chiffretext trägt jetzt eine Schlüssel-ID, sodass Schlüssel ohne eine Big-Bang-Neuverschlüsselung rotiert werden können.encryption.keys_filemitkeys_poll_interval(Standard15s) lädt den Schlüsselbund im laufenden Betrieb neu. Neue CLI:semaphore vaults check;semaphore vaults rekeywurde rund um den Schlüsselbund neu geschrieben. Das alte flacheaccess_key_encryptionfunktioniert weiterhin. option_encryption— ein separater Schlüssel für in der Datenbank gespeicherte Optionen.- OpenBao-Secret-Speichertyp (über den Vault-Provider geleitet) mit eigenem Symbol.
- AWS Secrets Manager ohne statische Zugangsdaten — ein Kontrollkästchen IAM-Rolle verwenden.
- TLS-Skip-Verify-Option für Vault-/OpenBao-Speicher.
- Synchronisierte und schreibgeschützte Secret-Felder werden beim Aktualisieren nicht mehr gelöscht.
Observability
- Debug-Logging mit Namensräumen.
--debug-filter/SEMAPHORE_DEBUG_FILTERwählt aus, welche Subsysteme Debug-Ausgaben erzeugen, im Stil von Node.jsdebug:runner,runner,task_pool,task_*,*,*,-db. Verfügbare Namensräume:runner,task_pool,task_runner,task_logger,git,terraform,session,ldap,schedule,db,ha. Der Filter greift nur, wenn der Log-LevelDEBUGist; er hebt den Level nie an. Syslog-Hooks beachten denselben Filter. - Viele neue kontextbezogene Debug-Ausgaben in Runnern, Aufgaben und Auth; der gewählte Workspace wird beim Start ausgegeben.
Sicherheit

- Das Ändern eines Passworts erfordert jetzt das aktuelle Passwort (CWE-620).
- Origin-/Referer-Validierung bei zustandsändernden Anfragen (CSRF-Härtung).
- Session-Cookies werden bei Auslieferung über HTTPS als
Securemarkiert. - Runner-Registrierungstoken werden gehasht gespeichert und laufen ab; Verschlüsselungsschlüssel pro Runner wurden entfernt.
- Das Anlegen eigener Rollen prüft die Berechtigungen des Aufrufers (Fix einer Rechteausweitung).
- Git-URL-Validierung;
--end-of-optionswird an Git übergeben, damit eine manipulierte Ref nicht als Flag gelesen werden kann; Commit-Hashes werden auf ihr Format geprüft; Branches werden vor dem Durchsuchen des Repositorys validiert; Playbook-Pfade werden validiert. - Access-Key-Payloads und das
app-Feld der Vorlage werden validiert. - JWT-Claims tragen nur IDs — keine Namen oder E-Mail-Adressen gelangen an externe Systeme.
- Runner-Token werden nicht mehr in Projekt-Backups geschrieben.
- Die API bricht nach einem Schreibfehler ab, statt mit einer teilweise geschriebenen Antwort fortzufahren.
- Sicherheits-SLA in
SECURITY.mdveröffentlicht; Release-Artefakte werden mit dem GPG-Schlüssel[email protected]signiert.
UI und Lokalisierung

- Tschechische Übersetzung.
- Dropdown-Karten für die JWT- und Zeitplan-Abschnitte des Vorlagenformulars.
- Das Symbol zum Kopieren in die Zwischenablage ist im hellen Modus sichtbar; Spinner laufender Aufgaben behoben; Innenabstand des Vorlagenformulars behoben; Workflow-Beta-Label.
- Die Extraktion von Integrationsvariablen bewahrt JSON-Objekte und -Arrays, statt sie in Strings umzuwandeln.
Hinweise zum Upgrade
Breaking Changes und Verhaltensänderungen
- BoltDB ist weg.
boltist kein gültiger Dialekt mehr; der Server verweigert den Start mit “Bolt is not supported starting from version 2.19”. Migrieren Sie zuerst zu SQLite, MySQL oder PostgreSQL. - Runner-Verschlüsselungsschlüssel entfernt. Server und Runner müssen beide auf 2.19 sein. Stellen Sie sicher, dass der Runner-Server-Verkehr per TLS geschützt ist. Skriptgesteuerte Runner-Bereitstellung, die den Schlüssel erwartete, muss angepasst werden.
- Aufgabenlisten-APIs sind paginiert.
GET /api/project/{id}/tasks/lastnimmtcountundbeforeentgegen;limitwird weiterhin akzeptiert, aber Clients, die sich auf die neuesten 200 Aufgaben in einer Antwort verlassen haben, müssen blättern. - Kein Fallback auf veraltete Runner. Sind alle Runner offline, bleiben Aufgaben in der Warteschlange.
- Runner-Flag
activeentfernt aus der Registrierung. - Projekt-Backups enthalten keine Runner-Token mehr.
- SQLite:
v2.19.14baut die Tabellensessionundtaskneu auf, um korrekte Fremdschlüssel hinzuzufügen (behebt das Löschen von Benutzern). Verwaiste Sessions werden entfernt. Sichern Sie die Datenbank vor dem Upgrade.
Neue Konfiguration
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. Alle sind optional; bestehende Konfigurationen
funktionieren weiterhin. config.schema.yaml und die Konfigurationsreferenz-Dokumentation wurden neu
generiert.
Datenbankmigrationen
v2.18.6 (Vorlage jwt_params), v2.18.15 (Workflow-Tabellen), 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 (SQLite-Neuaufbau von session/task). Kompatibilität der Migration mit MariaDB 12.1 behoben.
Patch-Releases
| Version | Änderungen |
|---|---|
| 2.19.8 | SQLite-Migration behoben; Löschen von Benutzern behoben (Fremdschlüssel session/task); Groß-/Kleinschreibung ignorierender Stringvergleich in DB-Abfragen |
| 2.19.9 | Umgebungsvariable SEMAPHORE_RUNNER_EXECUTOR_TYPE; Bereinigung von omitempty in der Konfiguration |
| 2.19.10 | Fix der Executor-Konfiguration; Fix der Docker-Build-Option |
| 2.19.11 | Gewählter Workspace wird in den Logs ausgegeben; latest-Tag für das Helper-Image; Tests für DB-Migrationen |
| 2.19.12 | Nil-Pointer in den Runner-Konfigurationsoptionen behoben; Fix der Fehlerweitergabe |
| 2.19.14 | Behandlung des alten secrets_path in der Konfiguration behoben |
Abhängigkeiten
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. Docs als Git-Submodul hinzugefügt; THIRD-PARTY-LICENSES.md neu generiert.
