Maskiranje tajni u Ansible-u

Ansible playbook datotekama često su potrebne lozinke i API tokeni za povezivanje sa serverima i postavljanje aplikacija. Ove vrednosti mogu se pojaviti i u izlazu zadataka, na primer kada komanda vrati grešku koja sadrži lozinku.

Ansible uvodi maskiranje tajni kako bi pomogao u rešavanju ovog problema. Poznate tajne vrednosti u izlazu zamenjuje oznakom $REDACTED$, dok ostatak poruke ostaje čitljiv. Zadaci i dalje koriste originalne vrednosti.

Ova mogućnost je dodata kroz pull request za Secret Masking API, koji je prihvaćen 10. septembra 2026. godine. U vreme pisanja ovog teksta dostupna je u razvojnim verzijama ansible-core 2.22. Još nije deo stabilnog izdanja.

Pogledajmo jednostavan playbook, a zatim kako planiramo da ovu mogućnost koristimo u Semaphore UI.

Prvo registrujmo tajnu

Ansible mora da zna koje vrednosti treba da maskira. Novi API registruje vrednosti iz poznatih izvora tajni, kao što su promenljive šifrovane pomoću Vault-a i parametri modula označeni sa no_log.

Za običnu promenljivu možemo da koristimo filter register_secret. I promenljivu prosleđenu kroz --extra-vars treba registrovati; nije dovoljno da se zove db_password.

U ovom primeru koristićemo izmišljenu lozinku baze podataka. Napravite playbook pod nazivom 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 }}"

Prvi zadatak registruje lozinku. Filter vraća originalnu vrednost, pa playbook i dalje može da je koristi za povezivanje sa bazom podataka. Registracija mora da se obavi pre nego što bilo koji zadatak ispiše tu vrednost.

Pokrenite playbook uz razvojnu verziju ansible-core 2.22:

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

Drugi zadatak će prikazati sledeću poruku:

Connecting to db.internal with password=$REDACTED$

Ovde ispisujemo lozinku samo da bismo pokazali maskiranje. U stvarnom playbook-u preuzmite je iz svog izvora tajni i izbegavajte namerno ispisivanje pristupnih podataka.

Integracija sa Semaphore UI

Semaphore UI već zna koje ste promenljive označili kao tajne. Planiramo da u budućim verzijama koristimo ove informacije da automatski registrujemo te vrednosti u Ansible-u.

Za to ćemo koristiti Ansible opciju _SECRETS_INPUT_FILES. Ona se podešava preko promenljive okruženja _ANSIBLE_SECRETS_INPUT_FILES i omogućava Ansible-u da pročita listu tajni pre pokretanja playbook-a.

Ulaz može biti u YAML ili JSON formatu. Dokument sa lozinkom iz našeg primera izgleda ovako:

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

Ova lista govori Ansible-u šta treba da maskira. Same promenljive se i dalje odvojeno prosleđuju playbook-u.

Planirana integracija obuhvatiće tajne vrednosti iz:

  • Grupa promenljivih (Variable Groups) — tajne sačuvane za upotrebu u zadacima.
  • Upitnika (Surveys) — tajni odgovori uneti pri pokretanju zadatka.

Za ove vrednosti neće biti potrebno da svakom playbook-u dodajete zadatak sa register_secret.

Planirana integracija Semaphore UI: tajna se prosleđuje playbook-u i odvojeno registruje preko _SECRETS_INPUT_FILES. Zadaci koriste stvarnu vrednost, dok je Ansible u dnevniku zadatka zamenjuje oznakom $REDACTED$.

Ovaj pristup smo testirali na razvojnoj verziji ansible-core 2.22. Registrovane vrednosti bile su maskirane u debug porukama, rezultatima komandi, porukama o greškama, detaljnom izlazu i Ansible datoteci dnevnika. Prosleđivanje liste kroz pipe takođe je radilo, bez upisivanja zasebne datoteke sa tajnama na disk.

Opcija je trenutno interna i može da se promeni. Podrška u Semaphore UI planirana je za buduće izdanje i zahtevaće kompatibilnu verziju Ansible-a.

Primer: postavljanje aplikacije

Pretpostavimo da imamo šablon zadatka (Task Template) koji postavlja aplikaciju. Skripta za postavljanje koristi API token sačuvan kao tajna u grupi promenljivih.

Uz planiranu integraciju, zadatak će raditi ovako:

  1. Semaphore UI prosleđuje token playbook-u.
  2. Pre izvršavanja takođe prosleđuje token Ansible listi za maskiranje preko _SECRETS_INPUT_FILES.
  3. Playbook pokreće skriptu za postavljanje sa stvarnim tokenom.
  4. Ako skripta uključi taj token u svoj izlaz, Ansible ga maskira u prikazanom rezultatu.

Na primer, token koji je istekao mogao bi da proizvede ovu poruku u dnevniku zadatka:

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

Možemo da vidimo koje postavljanje nije uspelo i zašto, bez pokazivanja tokena svima koji čitaju dnevnik. Isti tok će važiti i za privremeni token unet kroz tajno polje upitnika.

Ograničenja

Maskiranje radi sa registrovanim vrednostima. Razvojna implementacija preskače tajne kraće od četiri znaka, a kodirana ili na drugi način izmenjena vrednost može zahtevati zasebnu registraciju.

Ono takođe ne štiti pristupne podatke u argumentima procesa, datotekama koje playbook upisuje ili dnevnicima nastalim van Ansible-a. Nastavite da koristite no_log: true za zadatke čiji ceo izlaz treba da ostane privatan.

Uz ovu integraciju, tajne označene u Semaphore UI biće poznate i Ansible sistemu za maskiranje. To će pomoći da pristupni podaci ne završe u dnevnicima zadataka, uz očuvanje korisnih informacija za otklanjanje problema.