
Semaphore UI 2.20 aggiunge un log di audit con esportazione verso SIEM, trasforma i Workflow in un vero motore di pipeline con nodi di ritardo, revisioni, output passati tra le attività e variabili dei workflow, rielabora i ruoli così che un membro possa averne più di uno e gli amministratori ottengano ruoli validi per tutta l’istanza e mappature dei gruppi dell’IdP, introduce la configurazione degli host per credenziali SSH e Git per singolo host, sposta ogni variabile extra di Ansible in file cifrati con Vault ed espone le metriche Prometheus.
La linea parte da v2.20.0. Le release correttive saranno elencate alla fine di questa pagina man mano
che vengono pubblicate.
Novità principali
- Log di audit — chi ha fatto cosa, da dove e con quale risultato; una schermata di amministrazione, la conservazione dei dati e l’esportazione Syslog / Splunk HEC verso i SIEM (esportazione e filtri in Pro).
- Workflow — nodi di ritardo, revisioni immutabili vincolate alle esecuzioni, output consegnati come input dell’attività successiva, variabili del workflow richieste in una finestra di avvio, un editor ridisegnato con scorciatoie e annullamento, e webhook che avviano i workflow.
- Più ruoli per membro, ruoli con id e slug, ruoli globali con permessi validi per tutta l’istanza (Pro) e mappature gruppo IdP → ruolo applicate all’accesso (Enterprise).
- Identità esterne — gli accessi LDAP e OIDC sono associati agli account tramite l’id stabile del provider, non tramite l’e‑mail; più directory LDAP su un’unica pagina di accesso.
- Configurazione degli host — associa host SSH e URL Git alle credenziali del progetto, con applicazione ai cloni, a Galaxy, ai moduli Terraform e ad Ansible.
- Le variabili extra di Ansible non compaiono più sulla riga di comando; i secret viaggiano in un file cifrato con Ansible Vault e Jinja2 all’interno dei valori non viene più valutato.
- Modelli: directory di lavoro di Ansible, nomi univoci e
template_namenell’API delle attività, notifiche di errore soppresse, Dry Run / Diff nascosti, opzioni di installazione Galaxy, variabili di survey a selezione multipla, secret di survey sui runner remoti. - I repository monorepo condividono un unico checkout tra i modelli; nuovi tentativi Git, fetch parallelo dei submodule, verifica delle host key SSH.
- Metriche Prometheus su
/api/metrics. - Generazione di coppie di chiavi SSH sul server e copia della chiave pubblica dal Key Store.
Log di audit

Semaphore registra ora gli eventi rilevanti per la sicurezza in un log dedicato e di sola aggiunta. Abilitalo con:
"audit": {
"enabled": true,
"instance_id": "semaphore-prod"
}
(SEMAPHORE_AUDIT_ENABLED, SEMAPHORE_AUDIT_INSTANCE_ID; instance_id è obbligatorio e identifica
l’installazione in ogni evento.)
Cosa viene registrato. 116 tipi di evento in otto categorie: auth (accessi, disconnessioni, MFA,
token API rifiutati, richieste negate, blocchi CSRF), iam (utenti, password, token API, identità,
appartenenze, ruoli, permessi sui modelli), resource (progetti, backup, inventari, repository, modelli,
pianificazioni, integrazioni, configurazioni degli host, workflow, gruppi di variabili), secret
(credenziali e archiviazioni dei secret), task (avvio con il relativo trigger, completamento con
risultato e durata, approvazioni, arresti, eliminazione della cronologia), runner (registrazione,
modifiche, report rifiutati), system (impostazioni, licenza) e audit stesso (avvio, conservazione,
esportazione). Password, token, valori dei secret, output delle attività e variabili non vengono mai
scritti.
Struttura dell’evento. Ogni evento contiene un UUID, un numero di sequenza senza interruzioni, un
timestamp UTC al microsecondo, l’attore (utente / anonimo / sistema / runner / integrazione, con
autenticazione tramite sessione o token API e l’impronta del token), l’IP di origine e lo User‑Agent, il
target, il progetto, un id di richiesta (restituito anche nell’header di risposta X-Request-ID), l’id
dell’istanza e l’id del nodo HA. I risultati sono success o failure con un elenco chiuso di motivi;
un’azione che ha salvato l’oggetto ma ha fallito in un passaggio successivo è un successo con
partial = true. Dietro un reverse proxy, X-Forwarded-For è attendibile solo se proviene da
audit.trusted_proxy_cidrs.

Schermata di amministrazione. Log di audit nel menu utente (/audit-log) elenca gli eventi dal più
recente, 50 per pagina, con la navigazione Più vecchi / Più recenti; una riga apre una scheda con le
sezioni Chi, Oggetto, Dove, Quando, Dettagli e Tecnico e un pulsante che copia l’evento nel
formato JSON inviato a un SIEM. L’accesso richiede il nuovo permesso globale Leggere il log di audit.
Conservazione. audit.retention_days elimina gli eventi più vecchi a blocchi, ogni ora con un jitter
così che i nodi HA non si sovrappongano; ogni passaggio che elimina qualcosa viene a sua volta registrato.
Pro: filtri ed esportazione. Filtra per periodo, utente, progetto, tipo di evento, risultato e IP; usa qualsiasi valore della scheda come filtro; esporta la selezione corrente come CSV o JSON Lines.
Pro: esportazione verso SIEM. Due destinazioni, ognuna con il proprio cursore così che nulla venga
saltato quando un ricevitore è fuori servizio: Syslog su TLS (RFC 5424, JSON dell’evento come corpo)
tramite audit.syslog e Splunk HTTP Event Collector tramite audit.splunk_hec (url, token,
index, source, sourcetype, ca_file, …). La consegna è at‑least‑once, ordinata per numero di
sequenza; in HA solo un nodo esporta per destinazione, coordinato tramite un lease Redis. Tre serie
Prometheus descrivono l’esportatore: semaphore_audit_export_pending_events,
semaphore_audit_export_oldest_pending_seconds e semaphore_audit_export_errors_total.
Archiviazione: tabelle audit_event, audit_event_sequence, audit_export_state (migrazioni v2.20.9
a v2.20.11). API: GET /api/audit/events e GET /api/audit/events/export.
Workflow
I Workflow sono una funzionalità Pro; l’etichetta Beta è stata rimossa.
Nodi di ritardo
Un quarto tipo di nodo accanto ad attività, approvazione e nota: Ritardo mette in pausa l’esecuzione
per un certo numero di secondi e poi rilascia i propri archi. La vista dell’esecuzione mostra un conto
alla rovescia dal vivo sulla scheda; un’esecuzione interrotta annulla il ritardo. Campo delay_seconds,
migrazione v2.20.2.
Revisioni
Ogni salvataggio di un workflow crea una nuova revisione del grafo; un’esecuzione si vincola alla
revisione da cui è partita, così la modifica di un workflow non altera mai un’esecuzione in corso e non
lascia mai orfani i nodi delle esecuzioni passate. L’editor mostra un chip rev. N e quante esecuzioni
stanno ancora eseguendo una revisione precedente; la vista dell’esecuzione mostra quale revisione sta
eseguendo. Le revisioni non referenziate da alcuna esecuzione vengono eliminate quando ne viene salvata
una più recente. API: GET …/workflows/{id}/revisions e …/revisions/{revision_id}.
Output e input

Un’attività può passare dati strutturati ai nodi successivi. Ogni attività avviata da un workflow riceve
SEMAPHORE_OUTPUTS_FILE; tutto ciò che vi scrive come oggetto JSON diventa i suoi output:
cat > "$SEMAPHORE_OUTPUTS_FILE" <<EOF
{"image_tag": "1.4.2", "replicas": 3, "subnet_ids": ["subnet-1", "subnet-2"]}
EOF
Ansible produce output con ansible.builtin.set_stats tramite un plugin di callback incluso; gli output
di Terraform, OpenTofu e Terragrunt vengono catturati automaticamente da output -json (i valori
sensitive vengono saltati ed elencati come Non catturati). Gli output vengono letti solo quando
l’attività riesce; i limiti sono 100 output, 32 KB ciascuno, 256 KB per file.
Una connessione verso un nodo attività consegna gli input — riempie le variabili di survey del modello di destinazione con gli output del nodo di origine:
- Per nome (predefinito): ogni output il cui nome corrisponde a una variabile di survey la riempie.
- Mappatura esplicita degli input: elenca le coppie
variable ← output keyda consegnare; quando il workflow ha un’esecuzione conclusa il pannello suggerisce le chiavi prodotte da quella esecuzione.

I valori vengono convertiti nel tipo della variabile, i nodi di approvazione e di ritardo trasmettono gli
output, una mappatura esplicita prevale sulla consegna per nome e una variabile obbligatoria lasciata
senza valore fa fallire l’attività del nodo prima che inizi, così l’esecuzione segue gli archi In caso
di errore. La vista dell’esecuzione mostra un badge N output per nodo, la finestra dell’attività ha una
tabella Output e il log dell’attività inizia con una riga Input "x" <- output "y" of node N per
ogni valore consegnato. Gli output sono memorizzati in chiaro e non riempiono mai una variabile secret;
un secret non può essere passato tramite gli output. Le attività sui runner remoti producono e ricevono
output; gli esecutori Docker e Kubernetes non li catturano ancora.

Variabili del workflow e finestra di avvio
Un workflow ha le proprie variabili di survey, richieste una sola volta in una finestra Esegui “…”
quando parte un’esecuzione (un workflow senza variabili parte immediatamente, come prima). Le risposte
vengono memorizzate sull’esecuzione, mostrate come chip in una barra Variabili sopra la tela
dell’esecuzione e raggiungono un’attività solo tramite un binding esplicito nel pannello del nodo —
una variabile del workflow non finisce mai in un modello per corrispondenza di nome. I secret non sono
ammessi come variabili del workflow. POST …/workflows/{id}/runs accetta
{"environment": {"image_tag": "1.4.3"}}; una risposta non conforme al proprio tipo o un valore
obbligatorio mancante impediscono l’avvio.
Ambiente di un’attività del workflow
Ogni attività avviata da un workflow riceve SEMAPHORE_WORKFLOW_ID, SEMAPHORE_WORKFLOW_RUN_ID,
SEMAPHORE_WORKFLOW_URL (richiede web_host) e SEMAPHORE_OUTPUTS_FILE, per ogni app e sui runner
remoti.
Editor ridisegnato

- Nuove schede dei nodi con riquadro del tipo, stato, durata, badge degli output e Approva / Rifiuta inline; etichette degli archi con un menu a tendina della condizione modificabile sul posto e un pulsante di eliminazione; una tela a griglia di punti.
- Menu di aggiunta rapida dalla maniglia
+di un nodo, con un clic destro sulla tela o dal pulsante dello stato vuoto: elenco ricercabile di tipi di nodo e modelli di attività, il nuovo nodo viene collegato in caso di successo. - Annulla / ripeti (
Ctrl/⌘+Z,Ctrl/⌘+Shift+Z), rinomina inline del workflow, un menu Problemi che porta il focus sul nodo interessato, un badge Salva per le modifiche non salvate e una protezione all’abbandono della pagina. - Scorciatoie sulla tela: le frecce spostano la vista (
Shiftper un passo ampio),+/-zoom,0adatta il grafo,1reimposta lo zoom,Escazzera la selezione; le schede dei nodi possono ricevere il focus da tastiera. - Controlli flottanti: zoom avanti / indietro, adatta la vista, auto‑layout Riordina, percentuale di zoom.
- Un unico chevron comprime insieme la palette e la navigazione principale; lo stato viene ricordato.
- L’overscroll del trackpad non attiva più il gesto Indietro del browser su macOS.

I webhook avviano i workflow
Un’integrazione può ora eseguire un workflow invece di un modello (Esegue: Modello / Workflow nel
modulo dell’integrazione). Ogni valore estratto diventa una risposta alla survey del workflow. La
gestione di tali integrazioni richiede la funzionalità Pro workflow_integrations_management. Per le
integrazioni di modelli, un valore Task Params estratto di nome git_branch imposta il branch
dell’attività avviata quando il modello ne consente la sovrascrittura.
Modifiche all’API
POST …/workflows/{id}/run è stato rinominato in POST …/workflows/{id}/runs e accetta il corpo
environment. I dettagli dell’esecuzione contengono revision_id, revision, un oggetto delay per
nodo e task.artifacts. I campi workflow_run_id, workflow_node_id e artifacts forniti dal client
su un’attività vengono ignorati, così un’attività non può spacciarsi per un nodo dell’esecuzione di
qualcun altro.
Ruoli e controllo degli accessi
Più ruoli per membro

Un membro del progetto detiene un insieme di ruoli, modificabile come chip nella pagina del team.
L’API accetta roles: ["manager", "release_approver"] accanto al vecchio role; la risposta mantiene il
campo scalare role solo per i membri con un unico ruolo. Un non amministratore non può togliere il ruolo
integrato Owner all’ultimo proprietario.
Ruoli con id, slug e ambiti
I ruoli sono ora righe con un id intero e uno slug (^[A-Za-z0-9_-]{1,100}$, derivato dal nome nel
modulo); anche i quattro ruoli integrati sono righe e non possono più essere oscurati da un ruolo
personalizzato. I ruoli hanno un ambito: integrato, condiviso (utilizzabile in qualsiasi progetto) o
di progetto. L’eliminazione di un ruolo in uso risponde 409 con il relativo impatto (membri, progetti,
permessi sui modelli, mappature) e può essere ripetuta con ?force=true — Elimina con le assegnazioni
nell’interfaccia. Le migrazioni v2.20.12 e v2.20.13 ricostruiscono le tabelle dei ruoli; vedi le note
di aggiornamento.
Ruoli e permessi globali (Pro)

I diritti validi per tutta l’istanza non si limitano più al flag di amministratore. Un ruolo globale
concede una maschera di quattro permessi — Gestire gli utenti, Gestire i ruoli globali, Gestire le
impostazioni di sistema, Leggere il log di audit — e viene assegnato agli utenti nella scheda Ruoli
della pagina degli utenti (/users/roles) e nella scheda Ruoli globali della finestra dell’utente, che
mostra anche i permessi effettivi e quale ruolo concede ciascuno. Ogni route di amministrazione è
protetta da uno dei quattro bit; GET /api/user restituisce global_permissions. Un’istanza conserva
sempre almeno un amministratore, garantito con un lock di riga sicuro tra i nodi HA. Un utente con
Gestire gli utenti non può modificare un amministratore né chiunque detenga un permesso che lui non ha.
API: /api/global-roles, /api/users/{id}/global-roles, /api/users/{id}/global-permissions, catalogo
su /api/global-roles/permissions.
Mappature dei ruoli dei gruppi (Enterprise)

Associa un gruppo del provider di identità a un ruolo di progetto nella nuova pagina Mappature dei
gruppi (/role-mappings): provider, gruppo, progetto, ruolo. A ogni accesso OIDC i ruoli mappati
dell’utente vengono allineati ai gruppi presenti nel token (groups_claim del provider). I ruoli mappati
compaiono nella pagina del team come chip bloccati con un tooltip provider: group e non possono essere
rimossi come ruoli di membro; i ruoli mappati non contano come ultimo proprietario del progetto. Un
accesso con password o LDAP azzera i ruoli mappati, perché non porta alcun gruppo. API:
/api/role_mappings.
Autenticazione e identità

- Identità esterne. Gli accessi LDAP e OIDC sono associati agli account Semaphore tramite l’id
stabile del provider (
subOIDC, DN LDAP) nella nuova tabellauser__external_identity, non tramite l’e‑mail. Questo chiude la classe di bug in cui un IdP che accetta qualsiasi indirizzo digitato fa prendere possesso dell’account di qualcun altro.external_auth_email_matching(autopredefinito,always,never) controlla se un utente esterno esistente senza identità possa ancora essere associato una volta tramite e‑mail; gli account locali con password non vengono mai adottati. L’e‑mail OIDC vale solo quandoemail_verifiedè presente e il provider impostarequire_verified_email. Gli utenti collegano e scollegano le identità da soli nella finestra dell’account (/api/users/{id}/identities,POST /api/user/identities/ldap,/api/auth/oidc/{provider}/login?link=1). - Più directory LDAP.
ldap_providersè una mappa di directory con nome, ognuna con il proprio server, bind, ricerca, mappature, colore e ordine; il vecchio blocco piattoldap_*continua a funzionare come providerldap. La pagina di accesso mostra un selettore quando c’è più di una scheda e la scheda interna non invia mai una password a una directory.GET /api/auth/loginrestituisceldap_providerselogin_with_password. - I certificati LDAPS sono verificati per impostazione predefinita. Imposta
ldap_tls_skip_verify(blocco piatto) otls_skip_verify(per provider) per un certificato autofirmato. - Durata assoluta della sessione.
auth.max_session_life_hours(SEMAPHORE_AUTH_MAX_SESSION_LIFE_HOURS) fa scadere una sessione a un intervallo fisso dall’accesso, indipendentemente dall’attività;0mantiene solo il timeout di inattività. - Un utente senza progetti che non può crearne uno vede una pagina Nessun progetto invece di un modulo
che non può inviare; in quel caso
POST /api/projectsrisponde403. - La lingua scelta nel menu utente viene memorizzata sul server e segue l’utente tra i browser (
langin/api/user/options).
Configurazione degli host

Una nuova pagina di progetto, Configurazione degli host, associa host SSH e URL Git alle credenziali del progetto:
- una mappatura Host (
bastion.example.com) collega una chiave SSH, come bloccoHostdi unssh_configgenerato; - una mappatura URL (
https://github.com/acme/, un prefisso che termina con/copre un gruppo) collega una chiave SSH o una coppia login/password (solo HTTPS), come riscrittura GitinsteadOf; vince l’URL più specifico.
Le mappature si applicano al repository del modello e ai suoi submodule, ai ruoli e alle collection di
requirements.yml, ai moduli di terraform init, ai comandi git eseguiti da un playbook, ai repository
di inventario e agli host di inventario, e alla navigazione di branch e playbook; vengono inviate ai
runner remoti. Le chiavi private non toccano mai il disco — un agente SSH per mappatura, collegato con
IdentityAgent; le password passano tramite GIT_CONFIG_PARAMETERS e gli URL dei repository vengono
oscurati nei log delle attività. Una chiave referenziata da una mappatura non può essere eliminata. Le
mappature fanno parte dei backup del progetto. Richiede git_client: cmd_git. Tabella
project__host_config, migrazione v2.20.7; API /api/project/{id}/host_configs.
Modelli e attività

-
Directory di lavoro di Ansible. Directory di lavoro differente esegue
ansible-playbookda una sottodirectory del repository; il percorso deve restare dentro il checkout (working_directory, migrazionev2.20.3). -
Nomi dei modelli univoci per progetto (migrazione
v2.20.4), ePOST /api/project/{id}/tasksaccettatemplate_nameinvece ditemplate_id. -
Soppressione delle notifiche di errore per modello, accanto alla soppressione dei successi già esistente; gli avvisi e‑mail rispettano per la prima volta entrambe le opzioni (
suppress_error_alerts, migrazionev2.20.5). -
Nascondere Dry Run / Diff dalla finestra dell’attività per modello; il server smette anche di aggiungere
--check/--diffper quel modello (task_params.hide_dry_run,hide_diff). -
Opzioni di installazione Galaxy — una sezione comprimibile con Salta l’installazione Galaxy, argomenti CLI separati per
ansible-galaxy role installecollection install(una allow‑list di flag;--token,--api-keye i flag di percorso vengono rifiutati) e la richiesta di sovrascrittura per singola attività. -
Il selettore dei playbook elenca le sottodirectory mentre digiti, filtrate per app (
.ymlper Ansible, directory di primo livello per Terraform / OpenTofu / Terragrunt / Pulumi,.sh,.py,.ps1), salta le directory di layout di Ansible e le directory nascoste, è limitato a 30 voci e naviga un clone shallow confinato alla radice del repository. -
Variabili di survey a selezione multipla — il nuovo tipo
selectaccetta più valori, resi come chip nella finestra dell’attività;default_valuepuò essere un array.
-
I secret di survey raggiungono i runner remoti. Una risposta di survey di tipo
secretarrivava vuota su un runner. Ora viene memorizzata cifrata come chiave di accesso vincolata all’attività (access_key.task_id,expire_at, migrazionev2.20.1), decifrata dal nodo HA che serve il runner, eliminata al termine dell’attività e rimossa ogni ora; è nascosta dal Key Store, dai backup e dall’API delle chiavi. -
Variabili extra in YAML. L’editor dei gruppi di variabili ha guadagnato un selettore Tabella | JSON | YAML e un editor a schermo intero; le conversioni sono rigorose (le date restano stringhe, le radici non oggetto e i numeri non finiti vengono rifiutati). L’archiviazione è invariata.

-
La pagina dell’attività indica e collega la pianificazione o integrazione che l’ha avviata e contrassegna un’origine eliminata come
#id (deleted). I timestamp del log non vengono più selezionati quando si copia un log. -
Le pianificazioni validano l’espressione sul server prima del salvataggio, così
@hourlyviene accettato, e il banner del fuso orario può essere chiuso.
-
L’arresto di un’attività locale termina tutto il suo gruppo di processi:
SIGTERM, un periodo di grazia di 15 s, poiSIGKILL; i processissho dei provider rimasti orfani non sopravvivono più all’attività. Un piano Terraform interrotto non continua più; un piano che esce con0suSIGTERMnon viene interpretato come successo. -
Il campo
repository_iddell’inventario viene mantenuto solo per il tipofilee deve appartenere al progetto. -
I log del server indicano l’utente nelle voci Task added to queue / Task started.
Secret e Ansible Vault
-
Le variabili extra viaggiano in file, non sulla riga di comando. Gruppi di variabili, risposte di survey, input dei workflow e dettagli dell’attività vengono scritti in un file YAML
0600passato come--extra-vars @file. I secret — le risposte di survey di tiposecrete i secret dei gruppi di variabili — finiscono in un secondo file cifrato nel formato Ansible Vault 1.1 / AES‑256 da un’implementazione nativa in Go (non serve il binarioansible-vault), sbloccato con una password monouso fornita al--vault-id <uuid>@promptdiansible-playbook. Né i valori né la password compaiono inps, ed entrambi i file vengono rimossi al termine dell’attività. -
Jinja2 nei valori è dato, non codice. Ogni stringa che contiene
{{,{%,{#o un’intestazione#jinja2:viene marcata!unsafe, in modo ricorsivo, così una risposta di survey come{{ lookup('pipe', 'id') }}viene passata letteralmente. Le stringhe senza delimitatore restano volutamente non marcate: ansible‑core ≥ 2.19 ri‑risolve gli scalari!unsafe, il che trasformerebbe"2026.08"in un numero in virgola mobile. -
Un nuovo namespace di debug
extra_vars(SEMAPHORE_DEBUG_FILTER=extra_vars) registra come le variabili vengono suddivise e scritte — solo nomi, file e dimensioni, mai i valori. -
Generazione di una coppia di chiavi SSH sul server. Generate SSH Key nel Key Store crea una chiave RSA; la chiave pubblica viene conservata con la chiave, mostrata con Mostra / Nascondi e un pulsante di copia, e proposta in una finestra subito dopo la creazione (
generate_ssh_key).
-
L’aggiornamento di una chiave scrive
type,secrete la parte pubblica solo quando Override è impostato, così un client non può alterare il payload di una chiave senza sostituire il secret. -
La lettura di una credenziale da una variabile d’ambiente del server o da un file sotto
dirs.secretsè ora documentata (schede Env / File del modulo del Key Store).
Repository e Git
- Monorepo: un unico checkout per tutti i modelli. Un’opzione del repository clona il repository una
sola volta e lo condivide tra i modelli invece di una copia per modello; il checkout viene bloccato
durante fetch e pull, poi le attività vengono eseguite in parallelo. I modelli di un repository di
questo tipo non possono avere un branch proprio e le loro attività non possono sovrascrivere branch o
commit (
monorepo, migrazionev2.20.11). - Nuovi tentativi Git.
cloneepullvengono ritentati con un ritardo esponenziale limitato a un minuto;git_attempts(SEMAPHORE_GIT_ATTEMPTS, predefinito4). - Submodule in parallelo.
git_submodule_jobs(SEMAPHORE_GIT_SUBMODULE_JOBS, predefinito4) viene passato come--jobs. - Verifica delle host key SSH. Nuova sezione
ssh:config_path,known_hosts_file(SEMAPHORE_SSH_KNOWN_HOSTS_FILE) estrict_host_key_checking—no(predefinito),yesoaccept-new— applicata a Git su SSH. - La navigazione del repository usa un clone shallow indicizzato per branch; le credenziali vengono codificate in percent‑encoding per i cloni bare‑metal e oscurate nei log e nel feed degli eventi.
Runner e integrazioni
-
runner.check_interval_seconds(SEMAPHORE_RUNNER_CHECK_INTERVAL_SECONDS, predefinito5) imposta la frequenza di polling di un runner; un interruttore Opzioni avanzate nella pagina dei runner lo inserisce negli snippet generati di env, configurazione e Docker (pubblicato inv2.19.17). -
runner.connection.timeout_seconds(SEMAPHORE_RUNNER_CONNECTION_TIMEOUT_SECONDS, predefinito3) limita separatamente connessione, handshake TLS e header di risposta; i caricamenti dei log non vengono interrotti. -
runners.default_global_runners_mode(SEMAPHORE_DEFAULT_GLOBAL_RUNNERS_MODE:disable,prefer,require) sostituisce il deprecatouse_remote_runner;runners.registration_tokensostituisce ilrunner_registration_tokendi primo livello. -
Diagnostica dei runner lato server sotto
SEMAPHORE_DEBUG_FILTER=runner: motivi di rifiuto dei token, rilevamento di riavvio e stato online, report di avanzamento rifiutati, tracciamento dell’assegnazione. -
Le richieste di
unregisterdei runner sono autenticate; il client runner rifiuta i redirect HTTP. -
Autenticazione dei webhook con HMAC‑SHA512 (
hmac-sha512) accanto all’esistente HMAC‑SHA256; l’header della firma è configurabile.
-
Un webhook la cui integrazione appartiene a un altro progetto viene rifiutato.
Osservabilità
-
Metriche Prometheus.
GET /api/metricsprotetto da HTTP Basic Auth con una credenziale di servizio statica:"metrics": { "enabled": true, "username": "prometheus", "password": "…" }(
SEMAPHORE_METRICS_ENABLED,SEMAPHORE_METRICS_USERNAME,SEMAPHORE_METRICS_PASSWORD.) Serie:semaphore_tasks_running,semaphore_tasks_total{status}, i collector standardgo_*eprocess_*, e gli indicatori dell’esportazione di audit in Pro. -
Nuovi namespace di debug
extra_varserunner; la navigazione del repository registra l’output di Git a livello DEBUG. -
L’esportazione e il ripristino dei backup di progetto vengono registrati.
Sicurezza
- Collegamento delle identità tramite l’id del provider invece dell’e‑mail; verifica dei certificati LDAPS attiva per impostazione predefinita.
- Variabili extra fuori dalla riga di comando; secret cifrati con Vault; Jinja2 nei valori non valutato.
workflow_run_id,workflow_node_ideartifactscontraffatti rimossi dalle attività dei client.- Route di amministrazione protette da permessi globali espliciti invece del flag di amministratore; bit di permesso sconosciuti rifiutati; protezione contro l’escalation dei privilegi nella gestione degli utenti.
- Selettore dei playbook confinato alla radice del repository (
OpenRoot), limitato e filtrato. - Radici delle variabili extra e numeri YAML validati; argomenti CLI di Galaxy in allow‑list.
- Credenziali dei repository oscurate nei log e nel feed degli eventi;
=sottoposto a escape nei parametri di configurazione Git. - Gli endpoint di audit rifiutano le letture cross‑site e i cursori malformati; reti dei proxy attendibili validate.
unregisterdei runner autenticato; redirect rifiutati dal client runner.- Id di progetto e di integrazione dei webhook verificati.
- Attività locali interrotte insieme a tutto il loro gruppo di processi.
Note di aggiornamento
Modifiche incompatibili e di comportamento
- I nomi dei modelli devono essere univoci per progetto. La migrazione
v2.20.4aggiunge un indice univoco; rinomina i duplicati prima di aggiornare. - Le tabelle dei ruoli vengono ricostruite (
v2.20.12/v2.20.13). Esegui prima un backup. Un ruolo personalizzato il cui slug collide senza distinzione tra maiuscole e minuscole con uno integrato o con un altro ruolo viene rinominato (registrato nel log); i permessi sui modelli che puntano a un ruolo non risolvibile vengono eliminati (registrato nel log). L’appartenenza è stata spostata inproject__user_role; la colonnaproject__user.rolenon esiste più. GET /api/project/{id}/usersrestituiscerolesolo per i membri con un unico ruolo — leggiroles./roles*è passato dal flag di amministratore al permesso Gestire i ruoli globali; gli amministratori non sono interessati.- I certificati LDAPS sono verificati per impostazione predefinita. Imposta
ldap_tls_skip_verifyo iltls_skip_verifydi un provider per i certificati autofirmati. ansible-playbookviene invocato in modo diverso:--extra-vars @file, più un secondo file e un--vault-id <uuid>@promptquando l’attività ha dei secret, anche per i modelli senza vault. Tutto ciò che analizza la riga di comando, o unansible.cfgche vieta i prompt del vault, ne è interessato.- Jinja2 all’interno dei valori delle variabili extra non viene più valutato. Un playbook che contava sul templating di un valore di webhook o di survey smetterà di funzionare in quel modo.
- Endpoint di esecuzione dei workflow rinominato:
POST …/workflows/{id}/run→…/runs. - I repository monorepo prevalgono sul modello: nessun branch per modello, nessuna sovrascrittura di branch o commit nelle attività.
- Il campo
repository_iddell’inventario viene eliminato per ogni tipo trannefile. - L’arresto di un’attività locale termina il suo gruppo di processi (nessun equivalente su Windows per ora).
- Gli output dei workflow non vengono ancora catturati dagli esecutori Docker e Kubernetes; i secret di survey non raggiungono ancora quegli esecutori.
Nuova configurazione
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 e require_verified_email per provider OIDC,
runner.check_interval_seconds, runner.connection.timeout_seconds,
runners.{default_global_runners_mode,registration_token}. Sono tutti facoltativi. I campi di
configurazione di tipo puntatore possono ora essere impostati da variabili d’ambiente. Le pagine di
riferimento della configurazione e della CLI sono generate dal codice sorgente.
Migrazioni del database
v2.20.0 identità esterne · v2.20.1 secret di survey vincolati all’attività · v2.20.2 nodi di
ritardo · v2.20.3 directory di lavoro · v2.20.4 nomi dei modelli univoci · v2.20.5 soppressione
degli avvisi di errore · v2.20.7 configurazione degli host · v2.20.8 revisioni dei workflow ·
v2.20.9–v2.20.11 log di audit e indici, mappature degli input degli archi, flag monorepo ·
v2.20.12–v2.20.13 tabelle dei ruoli, variabili dei workflow · v2.20.14 integrazioni dei workflow e
mappature dei gruppi · v2.20.16 ruoli globali.
Dipendenze
Go 1.26; immagini Docker su Alpine 3.24; aggiunto prometheus/client_golang 1.23; go-oidc 3.21,
go-ldap 3.4.14, golang.org/x/crypto 0.57, modernc.org/sqlite 1.59, logrus 1.10; frontend
js-yaml 5 e cron-parser 5.10. Nuovi deployment one‑click: Cloudzy, RepoCloud e Pethost.
