Mascheramento dei segreti in Ansible

I playbook Ansible hanno spesso bisogno di password e token API per connettersi ai server e distribuire applicazioni. Questi valori possono comparire anche nell’output delle attività, per esempio quando un comando restituisce un errore che contiene una password.

Ansible sta introducendo il mascheramento dei segreti per affrontare questo problema. Sostituisce i valori segreti conosciuti con $REDACTED$ nell’output, lasciando leggibile il resto del messaggio. Le attività continuano a usare i valori originali.

La funzionalità è stata aggiunta con la pull request Secret Masking API, integrata il 10 settembre 2026. Al momento della pubblicazione è disponibile nelle build di sviluppo di ansible-core 2.22. Non fa ancora parte di una versione stabile.

Vediamo un semplice playbook e poi come intendiamo usare questa funzionalità in Semaphore UI.

Per prima cosa, registriamo un segreto

Ansible deve sapere quali valori mascherare. La nuova API registra i valori provenienti da fonti di segreti conosciute, come le variabili cifrate con Vault e i parametri dei moduli contrassegnati con no_log.

Per una variabile ordinaria possiamo usare il filtro register_secret. Anche una variabile passata tramite --extra-vars deve essere registrata: chiamarla db_password non basta.

Per questo esempio useremo una password di database fittizia. Crea un playbook chiamato masking.yml:

- name: Try secret masking
  hosts: localhost
  gather_facts: false
  vars:
    db_password: "example-db-password-123456"

  tasks:
    - name: Register the password before using it
      ansible.builtin.set_fact:
        db_password: "{{ db_password | ansible.builtin.register_secret }}"

    - name: Show a message containing the password
      ansible.builtin.debug:
        msg: "Connecting to db.internal with password={{ db_password }}"

La prima attività registra la password. Il filtro restituisce il valore originale, quindi il playbook può ancora usarlo per connettersi al database. La registrazione deve avvenire prima che qualsiasi attività mostri il valore.

Esegui il playbook con una build di sviluppo di ansible-core 2.22:

ansible-playbook -i localhost, -c local masking.yml

La seconda attività mostrerà questo messaggio:

Connecting to db.internal with password=$REDACTED$

Qui mostriamo la password solo per dimostrare il mascheramento. In un playbook reale, recuperala dalla tua fonte di segreti ed evita di stampare intenzionalmente le credenziali.

Integrazione con Semaphore UI

Semaphore UI sa già quali variabili hai contrassegnato come segrete. Nelle future versioni intendiamo usare queste informazioni per registrare automaticamente tali valori in Ansible.

Per farlo useremo l’opzione _SECRETS_INPUT_FILES di Ansible. Si configura tramite la variabile d’ambiente _ANSIBLE_SECRETS_INPUT_FILES e permette ad Ansible di leggere un elenco di segreti prima dell’avvio di un playbook.

L’input può essere in YAML o JSON. Un documento con la password del nostro esempio si presenta così:

version: 1
secrets:
  - example-db-password-123456

Questo elenco indica ad Ansible cosa mascherare. Le variabili stesse vengono ancora passate separatamente al playbook.

L’integrazione prevista coprirà i valori segreti provenienti da:

  • Gruppi di variabili (Variable Groups) — segreti salvati per essere usati dalle attività.
  • Questionari (Surveys) — risposte segrete inserite all’avvio di un’attività.

Per questi valori non sarà necessario aggiungere un’attività con register_secret a ogni playbook.

Integrazione prevista di Semaphore UI: il segreto viene passato al playbook e registrato separatamente tramite _SECRETS_INPUT_FILES. Le attività usano il valore reale, mentre Ansible lo sostituisce con $REDACTED$ nel log dell’attività.

Abbiamo provato questo approccio su una build di sviluppo di ansible-core 2.22. I valori registrati sono stati mascherati nei messaggi debug, nei risultati dei comandi, nei messaggi di errore, nell’output dettagliato e nel file di log di Ansible. Anche il passaggio dell’elenco tramite una pipe ha funzionato, senza scrivere su disco un file separato contenente i segreti.

L’opzione è attualmente interna e potrebbe cambiare. Il supporto in Semaphore UI è previsto per una versione futura e richiederà una versione compatibile di Ansible.

Esempio: distribuire un’applicazione

Supponiamo di avere un modello di attività (Task Template) che distribuisce un’applicazione. Lo script di distribuzione usa un token API salvato come segreto in un gruppo di variabili.

Con l’integrazione prevista, l’attività funzionerà così:

  1. Semaphore UI passa il token al playbook.
  2. Prima dell’esecuzione, fornisce anche il token all’elenco di mascheramento di Ansible tramite _SECRETS_INPUT_FILES.
  3. Il playbook esegue lo script di distribuzione con il token reale.
  4. Se lo script include quel token nel proprio output, Ansible lo maschera nel risultato visualizzato.

Per esempio, un token scaduto potrebbe produrre questo messaggio nel log dell’attività:

Deployment rejected: service=payments environment=staging token=$REDACTED$ reason=token expired

Possiamo vedere quale distribuzione è fallita e perché, senza mostrare il token a tutti quelli che leggono il log. Lo stesso flusso si applicherà a un token temporaneo inserito in un campo segreto di un questionario.

Limitazioni

Il mascheramento funziona con i valori registrati. L’implementazione di sviluppo ignora i segreti più corti di quattro caratteri, e un valore codificato o trasformato in altro modo potrebbe richiedere una registrazione separata.

Inoltre, non protegge le credenziali negli argomenti dei processi, nei file scritti da un playbook o nei log prodotti al di fuori di Ansible. Continua a usare no_log: true per le attività il cui intero output deve restare privato.

Con questa integrazione, i segreti contrassegnati in Semaphore UI saranno noti anche al sistema di mascheramento di Ansible. Questo aiuterà a tenere le credenziali fuori dai log delle attività, mantenendo informazioni utili per la diagnosi dei problemi.