Rotazione dei Segreti
La CLI ruota i segreti per istanza in place, aggiorna il .env del tenant, riavvia
l'applicazione una volta, verifica i nuovi valori e opzionalmente li salva in un
password manager. I nuovi valori non sono mai stampati — solo hint mascherati (ab****cd).
Comandi
flo secrets status <id> # elenca segreti ruotabili + stato
flo secrets rotate <id> dbPassword oidcCerts # ruota chiavi specifiche
flo secrets rotate <id> --all # ruota tutto
flo secrets rotate <id> --all --skip emailPassword --save-to 1password
flo secrets rotate <id> --all --dry-run # anteprima, non cambia nulla
| Opzione | Descrizione |
|---|---|
--all | Ruota ogni segreto dell'istanza |
--dry-run | Anteprima di ciò che verrebbe ruotato senza modifiche |
--skip <keys> | Con --all: chiavi separate da virgole da saltare (es. emailPassword,auditHashSalt) |
--save-to <manager> | Password manager: 1password oppure keepassxc (auto-rilevato se omesso) |
--vault <name> | Nome vault/database di destinazione |
--confirm | Salta le conferme interattive — tranne emailPassword, che chiede sempre |
Chiavi valide: dbPassword, oidcCerts, auditHashSalt, emailPassword,
strapiApiKey.
Cosa ruota
I rotatori girano in ordine fisso: DB → OIDC → salt audit → email → Strapi.
| Chiave | Etichetta | Auto | Cosa fa | Verifica |
|---|---|---|---|---|
dbPassword | Password database | sì | ALTER USER … PASSWORD dentro il container Postgres; aggiorna DB_CONNECTION_STRING in .env | pg_isready + query di test dopo il riavvio |
oidcCerts | Certificati OIDC | sì | Genera insieme nuove password di firma + cifratura (condividono il ciclo di vita) e rigenera i cert OIDC; aggiorna OIDC_*_PASSWORD | /.well-known/openid-configuration restituisce 200 |
auditHashSalt | Salt hash audit log | sì | Genera un nuovo salt e lo accoda alla catena; scrive AUDIT_HASH_SALTS=old,new + AuditLog__HashSalt=new | no-op (semantica a catena) |
emailPassword | Password provider email | no | Richiede input manuale sicuro; aggiorna EMAIL_SENDER_EMAIL_PSW | manuale |
strapiApiKey | Chiavi API Strapi | sì | Per ogni istanza Strapi collegata: crea nuovi token read-only + blog-editor, aggiorna STRAPI_API_KEY / BLOG_EDITOR_STRAPI_API_KEY e il registry tenant, elimina i vecchi token dopo verifica | GET /api col nuovo token restituisce 200 |
Note:
- La rotazione di
auditHashSaltnon invalida i vecchi hash audit: i salt precedenti restano nella catena e il backend li prova uno a uno, così la correlazione storica continua a funzionare. - Ruotare
oidcCertsinvalida i token OIDC emessi in precedenza. emailPasswordnon ha percorso automatizzato — il rotatore chiede conferma anche con--confirm, e si auto-salta quando il tenant non ha provider email.
Flusso di rotazione
- Il registry tenant è fotografato (snapshot) per il rollback.
- Ogni rotatore genera il nuovo valore e lo applica all'infrastruttura (PostgreSQL, cert OIDC, API Strapi).
- Il file
.envè rigenerato e fuso così le variabili personalizzate sono preservate. - Il container applicativo è riavviato una sola volta con
docker compose up -d --force-recreate. - Ogni rotatore verifica il proprio segreto (predefinito 36 tentativi × 5 s ≈ 3 minuti).
- In caso di fallimento l'orchestratore esegue rollback: snapshot registry,
.envprecedente e riavvio — più un rollback infrastrutturale best-effort (ad esempio, reimpostare la password DB precedente).
A causa del riavvio, prevedi un breve downtime applicativo (~5–10 s) per rotazione.
Sync col password manager
- 1Password: usa
op; gli item sono creati come login con un campo nascosto per segreto e metadati di rotazione nelle note. - KeePassXC: usa
keepassxc-cli; il percorso database proviene dasecrets.keepassDbPathin~/.flo/config.json(o è chiesto a prompt), i campi sono memorizzati come attributi personalizzati. - L'auto-rilevamento controlla prima 1Password, poi KeePassXC. Se nessun manager è
disponibile (o configurato come
none), il comando avverte che i segreti esistono solo nel registry cifrato.
Chiavi config: secrets.passwordManager (1password | keepassxc | none),
secrets.vault, secrets.keepassDbPath.
Cifratura a riposo
I segreti tenant sono cifrati con AES-256-GCM prima di essere scritti nel
registry o nel .env:
- Formato:
enc:<salt>:<iv>:<authTag>:<ciphertext>(parti base64), salt e IV da 32 byte, auth tag da 16 byte. - Derivazione chiave: scrypt dal
~/.flo/master.keydell'operatore (creato al primo avvio con modo0600; i permessi sono verificati e riparati). - Il rilevamento campi è basato sul nome (
password,secret,key,token,apikey, piùdb_connection_stringedemail_sender_email_psw), condiviso col mascheratore diconfig env showcosì i due non divergono mai. - Gli archivi di backup usano lo stesso algoritmo con un formato file separato
FLOBK1(vedi Backup).
Sicurezza e avvertenze
- Inizia sempre con
--dry-runsu un tenant di produzione. - La rotazione richiede che l'istanza sia risolvibile e raggiungibile; una verifica
fallita esegue rollback, ma il rollback infrastrutturale è best-effort — controlla
flo secrets statuseflo instance healthdopo un fallimento. - Non ruotare mentre un incidente di failover DR è attivo; ri-specchia poi i segreti sullo
standby con
flo failover sync-secrets <id>(vedi Failover e Disaster Recovery). - I valori dei segreti non sono mai loggati; gli adapter ricevono il chiaro solo per l'operazione di salvataggio e lo stato CLI è azzerato dopo.
- Le password di login VPS e le chiavi SSH sono una superficie separata:
flo vps rotate-password [vpsName](--hardenper disabilitare l'autenticazione a password,--key-pathper riusare una chiave,--save-to/--vaultper memorizzare il risultato).