
Semaphore UI 2.20 ergänzt ein Audit-Log mit SIEM-Export, baut Workflows zu einer echten Pipeline-Engine mit Delay-Knoten, Revisionen, zwischen Aufgaben übergebenen Outputs und Workflow-Variablen aus, überarbeitet Rollen so, dass ein Mitglied mehrere davon halten kann und Administratoren instanzweite Rollen sowie IdP-Gruppen-Mappings erhalten, führt die Host-Konfiguration für SSH- und Git-Zugangsdaten pro Host ein, verlagert jede zusätzliche Ansible-Variable in Vault-verschlüsselte Dateien und stellt Prometheus-Metriken bereit.
Die Linie beginnt mit v2.20.0. Patch-Releases werden am Ende dieser Seite aufgeführt, sobald sie
erscheinen.
Highlights
- Audit-Log — wer hat was, von wo und mit welchem Ergebnis getan; ein Admin-Bildschirm, Aufbewahrungsfristen und Export per Syslog / Splunk HEC an SIEMs (Export und Filter in Pro).
- Workflows — Delay-Knoten, unveränderliche Revisionen, die an Läufe gebunden sind, Outputs, die als Inputs der nächsten Aufgabe geliefert werden, Workflow-Variablen, die in einem Run-Dialog abgefragt werden, ein neu gestalteter Editor mit Hotkeys und Undo sowie Webhooks, die Workflows starten.
- Mehrere Rollen pro Mitglied, Rollen mit IDs und Slugs, globale Rollen mit instanzweiten Berechtigungen (Pro) und IdP-Gruppen → Rollen-Mappings, die bei der Anmeldung angewendet werden (Enterprise).
- Externe Identitäten — LDAP- und OIDC-Anmeldungen werden über die stabile ID des Anbieters an Konten gebunden, nicht über die E-Mail-Adresse; mehrere LDAP-Verzeichnisse auf einer Anmeldeseite.
- Host-Konfiguration — SSH-Hosts und Git-URLs auf Projekt-Zugangsdaten abbilden, angewendet auf Clones, Galaxy, Terraform-Module und Ansible.
- Zusätzliche Ansible-Variablen stehen nie mehr auf der Kommandozeile; Secrets werden in einer mit Ansible Vault verschlüsselten Datei übertragen, und Jinja2 in Werten wird nicht mehr ausgewertet.
- Vorlagen: Ansible-Arbeitsverzeichnis, eindeutige Namen und
template_namein der Task-API, unterdrückte Fehlerbenachrichtigungen, ausgeblendetes Dry Run / Diff, Galaxy-Installationsoptionen, Survey-Variablen mit Mehrfachauswahl, Survey-Secrets auf entfernten Runnern. - Monorepo-Repositories teilen einen Checkout zwischen Vorlagen; Git-Wiederholungsversuche, paralleles Abrufen von Submodulen, Prüfung von SSH-Host-Keys.
- Prometheus-Metriken unter
/api/metrics. - SSH-Schlüsselpaare auf dem Server erzeugen und den öffentlichen Schlüssel aus dem Key Store kopieren.
Audit-Log

Semaphore zeichnet sicherheitsrelevante Ereignisse jetzt in einem dedizierten Log auf, das nur angefügt wird. Aktivieren mit:
"audit": {
"enabled": true,
"instance_id": "semaphore-prod"
}
(SEMAPHORE_AUDIT_ENABLED, SEMAPHORE_AUDIT_INSTANCE_ID; instance_id ist erforderlich und
benennt die Installation in jedem Ereignis.)
Was aufgezeichnet wird. 116 Ereignisarten in acht Kategorien: auth (Anmeldungen, Abmeldungen,
MFA, abgewiesene API-Token, abgelehnte Anfragen, CSRF-Blockaden), iam (Benutzer, Passwörter,
API-Token, Identitäten, Mitgliedschaften, Rollen, Vorlagenberechtigungen), resource (Projekte,
Backups, Inventare, Repositories, Vorlagen, Zeitpläne, Integrationen, Host-Konfigurationen,
Workflows, Variablengruppen), secret (Zugangsdaten und Secret-Speicher), task (Start mit
Auslöser, Abschluss mit Ergebnis und Dauer, Freigaben, Stopps, Löschen der Historie), runner
(Registrierung, Änderungen, abgewiesene Meldungen), system (Einstellungen, Lizenz) und audit
selbst (Start, Aufbewahrung, Export). Passwörter, Token, Secret-Werte, Aufgabenausgaben und
Variablen werden niemals geschrieben.
Ereignis-Envelope. Jedes Ereignis trägt eine UUID, eine lückenlose Sequenznummer, einen
UTC-Zeitstempel mit Mikrosekunden, den Akteur (Benutzer / anonym / System / Runner / Integration,
mit Session- oder API-Token-Authentifizierung und einem Token-Fingerprint), die Quell-IP und den
User-Agent, das Ziel, das Projekt, eine Request-ID (die auch im Antwort-Header X-Request-ID
zurückgegeben wird), die Instanz-ID und die HA-Knoten-ID. Die Ergebnisse sind success oder
failure mit einer abgeschlossenen Liste von Gründen; eine Aktion, die das Objekt gespeichert hat,
aber bei einem späteren Schritt gescheitert ist, gilt als Erfolg mit partial = true. Hinter einem
Reverse-Proxy wird X-Forwarded-For nur aus audit.trusted_proxy_cidrs als vertrauenswürdig
behandelt.

Admin-Bildschirm. Audit-Log im Benutzermenü (/audit-log) listet Ereignisse mit den neuesten
zuerst auf, 50 pro Seite, mit Älter / Neuer zum Blättern; eine Zeile öffnet eine Karte mit den
Abschnitten Wer, Objekt, Wo, Wann, Details und Technisch sowie einer Schaltfläche, die
das Ereignis als das JSON kopiert, das an ein SIEM gesendet wird. Der Zugriff erfordert die neue
globale Berechtigung Audit-Log lesen.
Aufbewahrung. audit.retention_days löscht ältere Ereignisse in Stapeln, stündlich mit Jitter,
damit HA-Knoten nicht kollidieren; jeder Durchlauf, der etwas löscht, wird selbst aufgezeichnet.
Pro: Filter und Export. Nach Zeitraum, Benutzer, Projekt, Ereignisart, Ergebnis und IP filtern; von jedem Kartenwert aus weiterfiltern; die aktuelle Auswahl als CSV oder JSON Lines exportieren.
Pro: SIEM-Export. Zwei Ziele, jedes mit eigenem Cursor, sodass nichts übersprungen wird, wenn
ein Empfänger ausfällt: Syslog über TLS (RFC 5424, das Ereignis-JSON als Body) über
audit.syslog und Splunk HTTP Event Collector über audit.splunk_hec (url, token, index,
source, sourcetype, ca_file, …). Die Zustellung erfolgt mindestens einmal, geordnet nach
Sequenz; in einer HA-Umgebung exportiert nur ein Knoten pro Ziel, koordiniert über ein
Redis-Lease. Drei Prometheus-Serien beschreiben den Exporter:
semaphore_audit_export_pending_events, semaphore_audit_export_oldest_pending_seconds und
semaphore_audit_export_errors_total.
Speicherung: Tabellen audit_event, audit_event_sequence, audit_export_state (Migrationen
v2.20.9 bis v2.20.11). API: GET /api/audit/events und GET /api/audit/events/export.
Workflows
Workflows sind eine Pro-Funktion; das Beta-Label ist entfallen.
Delay-Knoten
Eine vierte Knotenart neben Aufgabe, Freigabe und Notiz: Delay pausiert den Lauf für eine
Anzahl von Sekunden und gibt dann seine Kanten frei. Die Laufansicht zeigt einen laufenden
Countdown auf der Karte; ein gestoppter Lauf bricht das Delay ab. Feld delay_seconds, Migration
v2.20.2.
Revisionen
Jedes Speichern eines Workflows erzeugt eine neue Revision des Graphen; ein Lauf fixiert die
Revision, mit der er gestartet ist, sodass das Bearbeiten eines Workflows einen laufenden Lauf nie
verändert und die Knoten vergangener Läufe nie verwaisen lässt. Der Editor zeigt einen
rev. N-Chip und wie viele Läufe noch eine ältere Revision ausführen; die Laufansicht zeigt,
welche Revision sie ausführt. Revisionen, auf die kein Lauf verweist, werden gelöscht, sobald eine
neuere gespeichert wird. API: GET …/workflows/{id}/revisions und …/revisions/{revision_id}.
Outputs und Inputs

Eine Aufgabe kann strukturierte Daten an die ihr nachfolgenden Knoten übergeben. Jede von einem
Workflow gestartete Aufgabe erhält SEMAPHORE_OUTPUTS_FILE; was sie dort als JSON-Objekt schreibt,
wird zu ihren Outputs:
cat > "$SEMAPHORE_OUTPUTS_FILE" <<EOF
{"image_tag": "1.4.2", "replicas": 3, "subnet_ids": ["subnet-1", "subnet-2"]}
EOF
Ansible erzeugt Outputs mit ansible.builtin.set_stats über ein mitgeliefertes Callback-Plugin;
Outputs von Terraform, OpenTofu und Terragrunt werden automatisch aus output -json erfasst
(sensitive-Werte werden übersprungen und als Not captured aufgeführt). Outputs werden nur
gelesen, wenn die Aufgabe erfolgreich ist; die Grenzen liegen bei 100 Outputs, je 32 KB und 256 KB
pro Datei.
Eine Verbindung in einen Aufgabenknoten liefert Inputs — sie füllt die Survey-Variablen der Zielvorlage aus den Outputs des Quellknotens:
- Nach Name (Standard): jeder Output, dessen Name einer Survey-Variablen entspricht, füllt diese.
- Inputs explizit zuordnen: die zu liefernden Paare
variable ← output keyauflisten; sobald der Workflow einen abgeschlossenen Lauf hat, schlägt das Panel die Keys vor, die dieser Lauf erzeugt hat.

Werte werden auf den Variablentyp konvertiert, Freigabe- und Delay-Knoten geben Outputs weiter, ein
explizites Mapping gewinnt gegenüber einer Lieferung nach Name, und eine erforderliche Variable
ohne Wert lässt die Aufgabe des Knotens schon vor dem Start fehlschlagen, sodass der Lauf seinen
Bei Fehler-Kanten folgt. Die Laufansicht zeigt pro Knoten ein N outputs-Badge, der
Aufgabendialog hat eine Outputs-Tabelle, und das Aufgabenlog beginnt mit einer Zeile
Input "x" <- output "y" of node N pro geliefertem Wert. Outputs werden im Klartext gespeichert und
füllen nie eine secret-Variable; ein secret kann nicht über Outputs weitergegeben werden.
Aufgaben auf entfernten Runnern erzeugen und empfangen Outputs; die Docker- und
Kubernetes-Executoren erfassen sie noch nicht.

Workflow-Variablen und der Run-Dialog
Ein Workflow hat eigene Survey-Variablen, die beim Start eines Laufs einmal in einem
Run “…”-Dialog abgefragt werden (ein Workflow ohne Variablen startet wie bisher sofort). Die
Antworten werden am Lauf gespeichert, als Chips in einer Variablen-Leiste über der
Lauf-Arbeitsfläche angezeigt und erreichen eine Aufgabe nur über eine explizite Bindung im
Knotenpanel — eine Workflow-Variable gelangt nie über ihren Namen in eine Vorlage. Secrets sind als
Workflow-Variablen nicht erlaubt. POST …/workflows/{id}/runs akzeptiert
{"environment": {"image_tag": "1.4.3"}}; eine Antwort, die nicht zu ihrem Typ passt, oder ein
fehlender erforderlicher Wert verhindert den Start.
Umgebung einer Workflow-Aufgabe
Jede von einem Workflow gestartete Aufgabe erhält SEMAPHORE_WORKFLOW_ID,
SEMAPHORE_WORKFLOW_RUN_ID, SEMAPHORE_WORKFLOW_URL (benötigt web_host) und
SEMAPHORE_OUTPUTS_FILE, für jede App und auch auf entfernten Runnern.
Neu gestalteter Editor

- Neue Knotenkarten mit Art-Kachel, Status, Dauer, Outputs-Badge und integriertem Genehmigen / Ablehnen; Kantenbeschriftungen mit einem Dropdown für die Bedingung direkt an der Kante und einer Löschschaltfläche; eine Arbeitsfläche mit Punktraster.
- Schnell-Hinzufügen-Menü über den
+-Anschluss eines Knotens, einen Rechtsklick auf die Arbeitsfläche oder die Schaltfläche im Leerzustand: durchsuchbare Liste von Knotenarten und Aufgabenvorlagen, der neue Knoten wird bei Erfolg verbunden. - Undo / Redo (
Ctrl/⌘+Z,Ctrl/⌘+Shift+Z), Umbenennen des Workflows direkt an der Stelle, ein Probleme-Menü, das den betroffenen Knoten fokussiert, ein Speichern-Badge für nicht gespeicherte Änderungen und eine Warnung beim Verlassen der Seite. - Hotkeys auf der Arbeitsfläche: Pfeiltasten verschieben (
Shiftfür einen großen Schritt),+/-zoomen,0passt den Graphen ein,1setzt den Zoom zurück,Eschebt die Auswahl auf; Knotenkarten sind per Tastatur fokussierbar. - Schwebende Steuerelemente: hinein- / herauszoomen, Ansicht einpassen, Tidy up-Autolayout, Zoom-Prozentsatz.
- Ein Chevron klappt die Palette und die Hauptnavigation gemeinsam ein; der Zustand wird gemerkt.
- Überscrollen mit dem Trackpad löst unter macOS nicht mehr die Zurück-Gestur des Browsers aus.

Webhooks starten Workflows
Eine Integration kann jetzt einen Workflow statt einer Vorlage ausführen (Runs: Template /
Workflow im Integrationsformular). Jeder extrahierte Wert wird zu einer Antwort auf das Survey des
Workflows. Das Verwalten solcher Integrationen erfordert die Pro-Funktion
workflow_integrations_management. Bei Vorlagen-Integrationen setzt ein extrahierter Task
Params-Wert mit dem Namen git_branch den Branch der gestarteten Aufgabe, sofern die Vorlage das
Überschreiben erlaubt.
API-Änderungen
POST …/workflows/{id}/run wurde in POST …/workflows/{id}/runs umbenannt und akzeptiert den
environment-Body. Die Laufdetails enthalten revision_id, revision, ein delay-Objekt pro
Knoten und task.artifacts. Vom Client gelieferte Werte für workflow_run_id, workflow_node_id
und artifacts an einer Aufgabe werden ignoriert, sodass eine Aufgabe sich nicht als Knoten eines
fremden Laufs ausgeben kann.
Rollen und Zugriffskontrolle
Mehrere Rollen pro Mitglied

Ein Projektmitglied hält einen Satz von Rollen, der auf der Team-Seite als Chips bearbeitet
wird. Die API akzeptiert roles: ["manager", "release_approver"] neben dem bisherigen role; die
Antwort behält das skalare role nur für Mitglieder mit einer einzigen Rolle. Ein
Nicht-Administrator kann dem letzten Eigentümer die integrierte Rolle Owner nicht entziehen.
Rollen mit IDs, Slugs und Scopes
Rollen sind jetzt Datensätze mit einer ganzzahligen id und einem slug
(^[A-Za-z0-9_-]{1,100}$, im Formular aus dem Namen abgeleitet); auch die vier integrierten Rollen
sind Datensätze und können nicht mehr von einer eigenen Rolle überdeckt werden. Rollen haben einen
Scope: integriert, geteilt (in jedem Projekt nutzbar) oder projektbezogen. Das Löschen einer
Rolle, die in Verwendung ist, antwortet mit 409 samt ihrer Auswirkung (Mitglieder, Projekte,
Vorlagenberechtigungen, Mappings) und kann mit ?force=true wiederholt werden — Mit Zuweisungen
löschen in der UI. Die Migrationen v2.20.12 und v2.20.13 bauen die Rollentabellen neu auf;
siehe die Hinweise zum Upgrade.
Globale Rollen und Berechtigungen (Pro)

Instanzweite Rechte bestehen nicht mehr nur aus dem Admin-Flag. Eine globale Rolle gewährt eine
Maske aus vier Berechtigungen — Benutzer verwalten, Globale Rollen verwalten,
Systemeinstellungen verwalten, Audit-Log lesen — und wird Benutzern im Tab Rollen der
Benutzerseite (/users/roles) sowie im Tab Globale Rollen des Benutzerdialogs zugewiesen, der
auch die effektiven Berechtigungen und die jeweils gewährende Rolle anzeigt. Jede Admin-Route wird
durch eines der vier Bits geschützt; GET /api/user liefert global_permissions. Eine Instanz
behält immer mindestens einen Administrator, erzwungen mit einem Row-Lock, der auch über HA-Knoten
hinweg sicher ist. Ein Benutzer mit Benutzer verwalten kann keinen Administrator und niemanden
bearbeiten, der eine Berechtigung hält, die ihm selbst fehlt. API: /api/global-roles,
/api/users/{id}/global-roles, /api/users/{id}/global-permissions, Katalog unter
/api/global-roles/permissions.
Gruppen-Rollen-Mappings (Enterprise)

Auf der neuen Seite Gruppen-Mappings (/role-mappings) wird eine Gruppe des
Identitätsanbieters auf eine Projektrolle abgebildet: Anbieter, Gruppe, Projekt, Rolle. Bei jeder
OIDC-Anmeldung werden die zugeordneten Rollen des Benutzers an die Gruppen im Token angeglichen
(groups_claim des Anbieters). Zugeordnete Rollen erscheinen auf der Team-Seite als gesperrte Chips
mit einem provider: group-Tooltip und können nicht als Mitgliedsrollen entfernt werden;
zugeordnete Rollen zählen nicht als letzter Eigentümer des Projekts. Eine Anmeldung per Passwort
oder LDAP löscht zugeordnete Rollen, weil sie keine Gruppen mitbringt. API: /api/role_mappings.
Authentifizierung und Identitäten

- Externe Identitäten. LDAP- und OIDC-Anmeldungen werden über die stabile ID des Anbieters
(OIDC
sub, LDAP DN) in der neuen Tabelleuser__external_identityan Semaphore-Konten gebunden, nicht über die E-Mail-Adresse. Damit ist die Fehlerklasse geschlossen, bei der ein IdP, der jede eingegebene Adresse akzeptiert, das Konto einer anderen Person übernimmt.external_auth_email_matching(Standardauto,always,never) steuert, ob ein bestehender externer Benutzer ohne Identität einmalig noch über die E-Mail-Adresse zugeordnet werden darf; lokale Passwortkonten werden niemals übernommen. Eine OIDC-E-Mail-Adresse zählt nur beiemail_verified, wenn der Anbieterrequire_verified_emailsetzt. Benutzer verknüpfen und lösen Identitäten selbst im Kontodialog (/api/users/{id}/identities,POST /api/user/identities/ldap,/api/auth/oidc/{provider}/login?link=1). - Mehrere LDAP-Verzeichnisse.
ldap_providersist eine Map benannter Verzeichnisse, jedes mit eigenem Server, Bind, Suche, Mappings, Farbe und Reihenfolge; der bisherige flacheldap_*-Block funktioniert weiter als Anbieterldap. Die Anmeldeseite zeigt einen Umschalter, wenn es mehr als einen Tab gibt, und der interne Tab sendet nie ein Passwort an ein Verzeichnis.GET /api/auth/loginliefertldap_providersundlogin_with_password. - LDAPS-Zertifikate werden standardmäßig geprüft. Setzen Sie
ldap_tls_skip_verify(flacher Block) odertls_skip_verify(pro Anbieter) für ein selbst signiertes Zertifikat. - Absolute Session-Lebensdauer.
auth.max_session_life_hours(SEMAPHORE_AUTH_MAX_SESSION_LIFE_HOURS) lässt eine Session eine feste Zeit nach der Anmeldung ablaufen, unabhängig von ihrer Aktivität;0behält nur das Inaktivitäts-Timeout. - Ein Benutzer ohne Projekte, der keines anlegen darf, sieht eine Seite Noch keine Projekte
statt eines Formulars, das er nicht abschicken kann;
POST /api/projectsantwortet in diesem Fall mit403. - Die im Benutzermenü gewählte Sprache wird auf dem Server gespeichert und folgt dem Benutzer über
Browser hinweg (
langin/api/user/options).
Host-Konfiguration

Eine neue Projektseite, Host-Konfiguration, bildet SSH-Hosts und Git-URLs auf Projekt-Zugangsdaten ab:
- ein Host-Mapping (
bastion.example.com) hängt einen SSH-Schlüssel an, alsHost-Block einer generiertenssh_config; - ein URL-Mapping (
https://github.com/acme/, ein auf/endendes Präfix deckt eine Gruppe ab) hängt einen SSH-Schlüssel oder ein Login/Passwort an (nur HTTPS), als Git-insteadOf-Umschreibung; die spezifischste URL gewinnt.
Mappings gelten für das Vorlagen-Repository und seine Submodule, für Rollen und Collections aus
requirements.yml, für terraform init-Module, für Git-Befehle, die ein Playbook ausführt, für
Inventar-Repositories und Inventar-Hosts sowie für das Durchsuchen von Branches und Playbooks; sie
werden an entfernte Runner ausgeliefert. Private Schlüssel landen nie auf der Festplatte — ein
SSH-Agent pro Mapping, gebunden über IdentityAgent; Passwörter laufen über
GIT_CONFIG_PARAMETERS, und Repository-URLs werden in Aufgabenlogs redigiert. Ein Schlüssel, auf
den ein Mapping verweist, kann nicht gelöscht werden. Mappings sind Teil der Projekt-Backups.
Erfordert git_client: cmd_git. Tabelle project__host_config, Migration v2.20.7; API
/api/project/{id}/host_configs.
Vorlagen und Aufgaben

-
Ansible-Arbeitsverzeichnis. Abweichendes Arbeitsverzeichnis führt
ansible-playbookaus einem Unterverzeichnis des Repositorys aus; der Pfad muss innerhalb des Checkouts bleiben (working_directory, Migrationv2.20.3). -
Eindeutige Vorlagennamen pro Projekt (Migration
v2.20.4), undPOST /api/project/{id}/tasksakzeptierttemplate_nameanstelle vontemplate_id. -
Fehlerbenachrichtigungen unterdrücken pro Vorlage, neben der bestehenden Unterdrückung von Erfolgsmeldungen; E-Mail-Alerts beachten erstmals beide (
suppress_error_alerts, Migrationv2.20.5). -
Dry Run / Diff ausblenden im Aufgabendialog pro Vorlage; der Server hängt für diese Vorlage dann auch kein
--check/--diffmehr an (task_params.hide_dry_run,hide_diff). -
Galaxy-Installationsoptionen — ein einklappbarer Abschnitt mit Galaxy-Installation überspringen, separaten CLI-Argumenten für
ansible-galaxy role installundcollection install(eine Allowlist von Flags;--token,--api-keyund Pfad-Flags werden abgewiesen) sowie der Abfrage zum Überschreiben pro Aufgabe. -
Die Playbook-Auswahl listet Unterverzeichnisse schon während der Eingabe auf, gefiltert pro App (
.ymlfür Ansible, Verzeichnisse der obersten Ebene für Terraform / OpenTofu / Terragrunt / Pulumi,.sh,.py,.ps1), überspringt Ansible-Layout-Verzeichnisse und Punkt-Verzeichnisse, ist auf 30 Einträge begrenzt und durchsucht einen Shallow Clone, der auf das Repository-Wurzel beschränkt ist. -
Survey-Variablen mit Mehrfachauswahl — der neue Typ
selectakzeptiert mehrere Werte, im Aufgabendialog als Chips dargestellt;default_valuedarf ein Array sein.
-
Survey-Secrets erreichen entfernte Runner. Eine
secret-Survey-Antwort kam auf einem Runner bisher leer an. Sie wird jetzt verschlüsselt als aufgabengebundener Access Key gespeichert (access_key.task_id,expire_at, Migrationv2.20.1), von demjenigen HA-Knoten entschlüsselt, der den Runner bedient, beim Ende der Aufgabe gelöscht und stündlich aufgeräumt; im Key Store, in Backups und in der Keys-API ist er verborgen. -
Zusätzliche Variablen als YAML. Der Editor für Variablengruppen hat einen Umschalter Tabelle | JSON | YAML und einen Vollbildeditor erhalten; die Konvertierungen sind streng (Datumsangaben bleiben Strings, Nicht-Objekt-Wurzeln und nicht endliche Zahlen werden abgewiesen). Die Speicherung ist unverändert.

-
Die Aufgabenseite benennt und verlinkt den Zeitplan oder die Integration, die eine Aufgabe gestartet hat, und markiert einen gelöschten Ursprung als
#id (deleted). Log-Zeitstempel werden beim Kopieren eines Logs nicht mehr mit ausgewählt. -
Zeitpläne validieren den Ausdruck vor dem Speichern auf dem Server, sodass
@hourlyakzeptiert wird, und das Zeitzonen-Banner lässt sich schließen.
-
Das Stoppen einer lokalen Aufgabe beendet ihre gesamte Prozessgruppe:
SIGTERM, eine Gnadenfrist von 15 s, dannSIGKILL; verwaistessh- oder Provider-Prozesse überleben die Aufgabe nicht mehr. Ein gestoppter Terraform-Plan läuft nicht weiter; ein Plan, der beiSIGTERMmit0endet, wird nicht als Erfolg gelesen. -
Das
repository_ideines Inventars wird nur noch für den Typfilebeibehalten und muss zum Projekt gehören. -
Serverlogs benennen den Benutzer in den Einträgen Task added to queue / Task started.
Secrets und Ansible Vault
-
Zusätzliche Variablen werden in Dateien übertragen, nicht auf der Kommandozeile. Variablengruppen, Survey-Antworten, Workflow-Inputs und Aufgabendetails werden in eine
0600-YAML-Datei geschrieben, die als--extra-vars @fileübergeben wird. Secrets —secret-Survey-Antworten und Secrets aus Variablengruppen — landen in einer zweiten Datei, die im Format Ansible Vault 1.1 / AES-256 verschlüsselt ist, durch eine native Go-Implementierung (keinansible-vault-Binary nötig), entsperrt mit einem Einmal-Passwort, das auf--vault-id <uuid>@promptvonansible-playbookgeantwortet wird. Weder die Werte noch das Passwort erscheinen inps, und beide Dateien werden beim Ende der Aufgabe entfernt. -
Jinja2 in Werten ist Daten, nicht Code. Jeder String, der
{{,{%,{#oder einen#jinja2:-Header enthält, wird rekursiv als!unsafemarkiert, sodass eine Survey-Antwort wie{{ lookup('pipe', 'id') }}wörtlich übergeben wird. Strings ohne Delimiter bleiben absichtlich unmarkiert: ansible-core ≥ 2.19 löst!unsafe-Skalare erneut auf, was"2026.08"in eine Fließkommazahl verwandeln würde. -
Ein neuer Debug-Namensraum
extra_vars(SEMAPHORE_DEBUG_FILTER=extra_vars) protokolliert, wie Variablen aufgeteilt und geschrieben werden — nur Namen, Dateien und Größen, niemals Werte. -
Ein SSH-Schlüsselpaar auf dem Server erzeugen. SSH-Schlüssel erzeugen im Key Store erstellt einen RSA-Schlüssel; der öffentliche Schlüssel wird beim Schlüssel gespeichert, mit Anzeigen / Verbergen und einer Kopierschaltfläche dargestellt und direkt nach dem Erstellen in einem Dialog angeboten (
generate_ssh_key).
-
Eine Schlüsselaktualisierung schreibt
type,secretund den öffentlichen Teil nur, wenn Override gesetzt ist; ein Client kann die Nutzlast eines Schlüssels also nicht ändern, ohne das Secret zu ersetzen. -
Das Lesen von Zugangsdaten aus einer Umgebungsvariablen des Servers oder einer Datei unter
dirs.secretsist jetzt dokumentiert (Tabs Env / File im Formular des Key Store).
Repositories und Git
- Monorepo: ein einzelner Checkout für alle Vorlagen. Eine Repository-Option klont das
Repository einmal und teilt es zwischen den Vorlagen, anstatt eine Kopie pro Vorlage anzulegen;
der Checkout wird für Fetch und Pull gesperrt, Aufgaben laufen danach parallel. Vorlagen eines
solchen Repositorys können keinen eigenen Branch haben, und ihre Aufgaben können Branch oder
Commit nicht überschreiben (
monorepo, Migrationv2.20.11). - Git-Wiederholungsversuche.
cloneundpullwerden mit exponentieller Verzögerung wiederholt, begrenzt auf eine Minute;git_attempts(SEMAPHORE_GIT_ATTEMPTS, Standard4). - Parallele Submodule.
git_submodule_jobs(SEMAPHORE_GIT_SUBMODULE_JOBS, Standard4) wird als--jobsübergeben. - Prüfung von SSH-Host-Keys. Neuer
ssh-Abschnitt:config_path,known_hosts_file(SEMAPHORE_SSH_KNOWN_HOSTS_FILE) undstrict_host_key_checking—no(Standard),yesoderaccept-new— angewendet auf Git über SSH. - Das Durchsuchen eines Repositorys verwendet einen Shallow Clone pro Branch; Zugangsdaten werden für Bare-Metal-Clones prozentkodiert und in Logs sowie im Ereignis-Feed redigiert.
Runner und Integrationen
-
runner.check_interval_seconds(SEMAPHORE_RUNNER_CHECK_INTERVAL_SECONDS, Standard5) legt fest, wie oft ein Runner abfragt; ein Schalter Erweiterte Optionen auf der Runner-Seite übernimmt den Wert in die generierten Env-, Konfigurations- und Docker-Snippets (ausgeliefert inv2.19.17). -
runner.connection.timeout_seconds(SEMAPHORE_RUNNER_CONNECTION_TIMEOUT_SECONDS, Standard3) begrenzt Verbindungsaufbau, TLS-Handshake und Antwort-Header separat; Log-Uploads werden nicht abgeschnitten. -
runners.default_global_runners_mode(SEMAPHORE_DEFAULT_GLOBAL_RUNNERS_MODE:disable,prefer,require) ersetzt das veralteteuse_remote_runner;runners.registration_tokenersetzt dasrunner_registration_tokenauf oberster Ebene. -
Serverseitige Runner-Diagnostik unter
SEMAPHORE_DEBUG_FILTER=runner: Gründe für abgewiesene Token, Erkennung von Neustart und Online-Status, abgewiesene Fortschrittsmeldungen, Dispatch-Tracing. -
unregister-Anfragen eines Runners werden authentifiziert; der Runner-Client verweigert HTTP-Redirects. -
HMAC-SHA512 zur Webhook-Authentifizierung (
hmac-sha512) neben dem bestehenden HMAC-SHA256; der Signatur-Header ist konfigurierbar.
-
Ein Webhook, dessen Integration zu einem anderen Projekt gehört, wird abgewiesen.
Observability
-
Prometheus-Metriken.
GET /api/metricshinter HTTP Basic Auth mit statischen Dienst-Zugangsdaten:"metrics": { "enabled": true, "username": "prometheus", "password": "…" }(
SEMAPHORE_METRICS_ENABLED,SEMAPHORE_METRICS_USERNAME,SEMAPHORE_METRICS_PASSWORD.) Serien:semaphore_tasks_running,semaphore_tasks_total{status}, die Standard-Collectorsgo_*undprocess_*sowie die Audit-Export-Gauges in Pro. -
Neue Debug-Namensräume
extra_varsundrunner; das Durchsuchen von Repositories protokolliert die Git-Ausgabe auf DEBUG. -
Export und Wiederherstellung von Projekt-Backups werden protokolliert.
Sicherheit
- Identitätsverknüpfung über die Anbieter-ID statt über die E-Mail-Adresse; Prüfung von LDAPS-Zertifikaten standardmäßig aktiv.
- Zusätzliche Variablen nicht mehr auf der Kommandozeile; Secrets Vault-verschlüsselt; Jinja2 in Werten wird nicht ausgewertet.
- Gefälschte
workflow_run_id,workflow_node_idundartifactswerden aus Client-Aufgaben entfernt. - Admin-Routen werden durch explizite globale Berechtigungen statt durch das Admin-Flag geschützt; unbekannte Berechtigungsbits werden abgewiesen; Schutz vor Rechteausweitung in der Benutzerverwaltung.
- Die Playbook-Auswahl ist auf das Repository-Wurzel beschränkt (
OpenRoot), begrenzt und gefiltert. - Wurzeln von zusätzlichen Variablen und YAML-Zahlen werden validiert; Galaxy-CLI-Argumente stehen auf einer Allowlist.
- Repository-Zugangsdaten werden in Logs und im Ereignis-Feed redigiert;
=wird in Git-Konfigurationsparametern escaped. - Audit-Endpunkte verweigern Cross-Site-Lesezugriffe und fehlerhafte Cursor; Netze vertrauenswürdiger Proxys werden validiert.
- Runner-
unregisterwird authentifiziert; Redirects werden vom Runner-Client verweigert. - Projekt- und Integrations-IDs von Webhooks werden geprüft.
- Lokale Aufgaben werden mit ihrer gesamten Prozessgruppe gestoppt.
Hinweise zum Upgrade
Breaking Changes und Verhaltensänderungen
- Vorlagennamen müssen pro Projekt eindeutig sein. Migration
v2.20.4fügt einen eindeutigen Index hinzu; benennen Sie Duplikate vor dem Upgrade um. - Die Rollentabellen werden neu aufgebaut (
v2.20.12/v2.20.13). Sichern Sie vorher. Eine eigene Rolle, deren Slug ohne Beachtung der Groß-/Kleinschreibung mit einer integrierten oder einer anderen Rolle kollidiert, wird umbenannt (protokolliert); Vorlagenberechtigungen, die auf eine nicht auflösbare Rolle verweisen, werden entfernt (protokolliert). Die Mitgliedschaft ist nachproject__user_roleumgezogen; die Spalteproject__user.roleist entfallen. GET /api/project/{id}/usersliefertrolenur für Mitglieder mit einer einzigen Rolle — lesen Sieroles./roles*ist umgezogen vom Admin-Flag zur Berechtigung Globale Rollen verwalten; Administratoren sind nicht betroffen.- LDAPS-Zertifikate werden standardmäßig geprüft. Setzen Sie
ldap_tls_skip_verifyoder dastls_skip_verifyeines Anbieters für selbst signierte Zertifikate. ansible-playbookwird anders aufgerufen:--extra-vars @file, plus eine zweite Datei und ein--vault-id <uuid>@prompt, wenn die Aufgabe Secrets hat, selbst bei Vorlagen ohne Vault. Alles, was die Kommandozeile parst, oder eineansible.cfg, die Vault-Prompts verbietet, ist betroffen.- Jinja2 in Werten zusätzlicher Variablen wird nicht mehr ausgewertet. Ein Playbook, das auf das Templating eines Webhook- oder Survey-Werts gesetzt hat, wird das nicht mehr tun.
- Der Endpunkt für Workflow-Läufe wurde umbenannt:
POST …/workflows/{id}/run→…/runs. - Monorepo-Repositories überschreiben die Vorlage: kein Branch pro Vorlage, kein Überschreiben von Branch oder Commit in Aufgaben.
- Das
repository_ideines Inventars entfällt für alle Typen außerfile. - Das Stoppen einer lokalen Aufgabe beendet ihre Prozessgruppe (unter Windows noch kein Äquivalent).
- Workflow-Outputs werden von den Docker- und Kubernetes-Executoren noch nicht erfasst; Survey-Secrets erreichen diese Executoren noch nicht.
Neue Konfiguration
audit, metrics, auth.max_session_life_hours, ssh.{config_path,known_hosts_file,strict_host_key_checking},
git_attempts, git_submodule_jobs, ldap_providers, ldap_tls_skip_verify,
external_auth_email_matching, groups_claim und require_verified_email pro OIDC-Anbieter,
runner.check_interval_seconds, runner.connection.timeout_seconds,
runners.{default_global_runners_mode,registration_token}. Alle sind optional. Konfigurationsfelder
mit Pointer-Typ können jetzt über Umgebungsvariablen gesetzt werden. Die Referenzseiten für
Konfiguration und CLI werden aus dem Quellcode generiert.
Datenbankmigrationen
v2.20.0 externe Identitäten · v2.20.1 aufgabengebundene Survey-Secrets · v2.20.2 Delay-Knoten ·
v2.20.3 Arbeitsverzeichnis · v2.20.4 eindeutige Vorlagennamen · v2.20.5 Unterdrückung von
Fehler-Alerts · v2.20.7 Host-Konfiguration · v2.20.8 Workflow-Revisionen · v2.20.9–v2.20.11
Audit-Log und Indizes, Input-Mappings für Kanten, Monorepo-Flag · v2.20.12–v2.20.13
Rollentabellen, Workflow-Variablen · v2.20.14 Workflow-Integrationen und Gruppen-Mappings ·
v2.20.16 globale Rollen.
Abhängigkeiten
Go 1.26; Docker-Images auf Alpine 3.24; prometheus/client_golang 1.23 hinzugefügt; go-oidc 3.21,
go-ldap 3.4.14, golang.org/x/crypto 0.57, modernc.org/sqlite 1.59, logrus 1.10; im Frontend
js-yaml 5 und cron-parser 5.10. Neue One-Click-Deployments: Cloudzy, RepoCloud und Pethost.
