3. Promozione, approvazioni e freeze#
In questo tutorial
Aggiungi un ambiente prod e lo proteggi: ogni richiesta è autenticata, ogni identità ha un ruolo, la produzione riceve solo un artefatto già passato da test, una seconda persona approva e un freeze blocca i rilasci durante un incidente.
Tempo: 25 minuti · Serve: il risultato del tutorial 2
flowchart LR
A["alice<br/>deployer"] -->|deploy 2.0.0| T[test]
A -->|promote test → prod| W{{AWAITING_APPROVAL}}
B["bob<br/>approver"] -->|approve| W
W --> P[prod]
1. Due identità#
Finora l'API accettava chiunque (auth.mode: none, identità none:anonymous). Crea due token statici, uno per Alice, che rilascia, e uno per Bob, che approva. manent ne conserva solo lo sha256:
openssl rand -hex 32 > lab/alice.token
openssl rand -hex 32 > lab/bob.token
printf '%s' "$(cat lab/alice.token)" | shasum -a 256 # sha256sum su Linux
printf '%s' "$(cat lab/bob.token)" | shasum -a 256
Le persone accedono con OIDC
I token statici servono ai sistemi automatici come la CI. Le persone di solito accedono tramite un identity provider: vedi Identity provider OIDC. Le regole qui sotto valgono allo stesso modo per entrambi.
L'interfaccia web richiede OIDC
L'interfaccia web accede solo tramite un identity provider. Quando auth.mode è enabled con i soli token statici, mostra Sign-in is not configured e il resto del tutorial usa la CLI. Per tornare a usare l'interfaccia configura auth.oidc con un client pubblico per la UI (auth.oidc.ui.client_id), come spiegato in Identity provider OIDC; token e OIDC funzionano insieme, quindi i token di Alice e Bob restano validi per la CLI.
2. Ruoli e regole#
Aggiungi autenticazione, permessi e una regola di governance a manent.yml:
auth:
mode: enabled
tokens:
- {name: alice, sha256: "<sha256 di alice.token>", groups: [team-hello]}
- {name: bob, sha256: "<sha256 di bob.token>", groups: [cab]}
rbac:
bindings:
- {groups: [team-hello], role: deployer, applications: ["hello"], environments: ["*"]}
- {groups: [cab], role: approver, applications: ["*"], environments: [prod]}
- {groups: [cab], role: release-manager, applications: ["*"], environments: [prod]}
governance:
rules:
- name: production
applications: ["*"]
environments: [prod]
requires: [test] # lo stesso artefatto deve essere riuscito in test
approvals: {required: 1, timeout: 24h}
deployerpuò rilasciare, annullare e fare rollback, ma non può approvare: chi rilascia non deve potersi approvare da solo tramite un secondo ruolo.approverpuò solo leggere e approvare;release-managerpuò creare ed eliminare finestre di freeze.- Per ogni deploy vale la prima regola che corrisponde. Senza regole corrispondenti non ci sono vincoli, ed è per questo che
testresta libero.
3. L'ambiente di produzione#
La produzione usa un'altra directory sullo stesso container e un proprio percorso in Vault:
sed -e 's#/opt/hello#/home/deploy/hello-prod#' -e 's#hello/test#hello/prod#' \
envconfig/untenanted/hello/test-consul.yml > envconfig/untenanted/hello/prod-consul.yml
docker cp envconfig/untenanted/hello/prod-consul.yml manent-tutorial-consul:/tmp/prod.yml
docker exec manent-tutorial-consul consul kv put manent/untenanted/hello/hello/prod @/tmp/prod.yml
docker cp lab/deploy_key manent-tutorial-vault:/tmp/k
docker exec -e VAULT_ADDR=http://127.0.0.1:8200 -e VAULT_TOKEN=tutorial-root manent-tutorial-vault \
vault kv put secret/hello/prod ssh_key=@/tmp/k
docker exec manent-tutorial-vault rm /tmp/k
Riavvia il server (VAULT_TOKEN=tutorial-root manent-server -c manent.yml serve) e verifica che le richieste anonime siano rifiutate:
D'ora in poi lavora come Alice, e guarda cosa può fare:
{"subject": "token:alice", "method": "token", "groups": ["team-hello"], "auth_enabled": true,
"grants": [{"role": "deployer", "actions": ["deployment.read", "schedule.read", "deployment.dry-run",
"deployment.submit", "deployment.cancel", "deployment.rollback"], "applications": ["hello"], "environments": ["*"]}]}
4. La produzione riceve solo artefatti promossi#
Costruisci una 2.0.0 e prova a mandarla direttamente in produzione:
sed -i.bak 's/1\.[01]\.0/2.0.0/' src/bin/hello
tar -czf dist/hello-2.0.0.tar.gz -C src .
sed 's/environment: test/environment: prod/' hello-min.yml > hello-prod.yml
manent deploy -f hello-prod.yml --version 2.0.0 --source "$PWD/dist/hello-2.0.0.tar.gz"
invalid request: hello 2.0.0 was not released successfully in test: it must be promoted from there (governance)
Rilasciala prima in test, poi promuovila:
manent deploy -f hello-min.yml --version 2.0.0 --source "$PWD/dist/hello-2.0.0.tar.gz"
manent promote -a hello --from test --to prod --no-wait
Nei comandi che seguono sostituisci <id> con l'ID stampato da promote.
Una promozione prende la richiesta dell'ultimo deploy riuscito in test, cambia l'ambiente e fissa artifact.sha256 all'hash effettivamente rilasciato: lo step qa rifiuterà qualunque altro file. I target non vengono mai copiati: arrivano dalla configurazione di prod, insieme ai suoi parametri e segreti. Quello che il descrittore di origine impostava da sé viene invece copiato, quindi si possono promuovere solo le versioni rilasciate in test con il descrittore corto hello-min.yml: le versioni 1.x del tutorial 1, rilasciate con un descrittore che imposta dest_dir e la chiave, andrebbero in conflitto con la configurazione di prod (environment configuration incompatible with the descriptor). Se serve, --deploy-file sostituisce la sezione deploy del deploy di origine.
5. Quattro occhi#
Alice non può approvare la propria promozione: il suo ruolo non lo consente, e anche con il permesso chi ha richiesto un deploy non può approvarlo.
Bob vede la richiesta tra quelle su cui può decidere, e la approva citando il change:
MANENT_TOKEN_FILE=lab/bob.token manent approvals
MANENT_TOKEN_FILE=lab/bob.token manent approve <id> -m "CHG-1234"
Il deploy viene accodato con lo stesso ID e parte. Il suo stato conserva tutta la storia:
{"state": "SUCCESS", "kind": "promotion", "version": "2.0.0", "requested_by": "token:alice",
"approval": [{"approver": "token:bob", "approve": true, "comment": "CHG-1234", "time": "…"}]}
Entrambe le decisioni, quella negata e l'approvazione, sono anche nell'audit (deployment.approve), inviato al SIEM.
6. Congela la produzione durante un incidente#
Una finestra di freeze blocca i deploy reali. Quelle configurate stanno in governance.freezes (per esempio ogni fine settimana); una di emergenza si crea a runtime, senza riavviare nulla, da un'identità con freeze.write:
MANENT_TOKEN_FILE=lab/bob.token manent freeze add --name incident-42 -e prod --for 2h --reason "incident 42 in progress"
manent promote -a hello --from test --to prod --version 2.0.0 --no-wait
invalid request: deploy blocked by freeze "incident-42" until 2026-10-19T21:30:13+02:00 (incident 42 in progress); in an emergency set freezeOverride with the reason
Una correzione che deve uscire comunque usa --freeze-override "<motivo>", che richiede il permesso deployment.freeze-override (di default solo admin), viene registrato nell'audit e non supera le finestre --hard. Finito l'incidente:
Cosa hai imparato#
- Con
auth.mode: enabledogni richiesta ha un'identità, e l'RBAC assegna ruoli per applicazione e ambiente. requiresfa accettare alla produzione solo ciò che è già riuscito altrove, epromoterilascia esattamente quell'artefatto.- Le approvazioni vengono da identità diverse dal richiedente, con commenti, scadenza e audit.
- Le finestre di freeze si configurano o si creano a runtime, e una deroga è esplicita, soggetta a permesso e registrata.
Prossimo passo#
- Ticket di change e approvazioni dalla chat: ServiceNow, Jira, Slack.
- Regole scritte come codice, testate e approvate come codice: Policy in Rego.
- Il tutorial 4 lascia SSH e rilascia su Kubernetes.