fix: harden DWH auth recovery guidance
This commit is contained in:
+124
-34
@@ -84,7 +84,7 @@ pubblico, installazione e percorso. Il file di output non deve esistere.
|
||||
```bash
|
||||
installation_id=psd-mac-primary
|
||||
description=operatore-mac-primario
|
||||
key_output="/root/dwh-auth-provision/$installation_id-primary.key"
|
||||
key_output=/root/dwh-auth-provision/psd-mac-primary.key
|
||||
sudo /usr/local/sbin/dwh-auth --registry-root /var/lib/dwh-auth key create \
|
||||
--installation-id "$installation_id" \
|
||||
--description "$description" \
|
||||
@@ -120,11 +120,12 @@ La revoca non è annullabile e un ID revocato non si ricrea.
|
||||
|
||||
## Backup, rollback e disinstallazione
|
||||
|
||||
Prima di mutare, creare un archivio cifrato e protetto del registro e copie protette delle sole
|
||||
configurazioni coinvolte. L'archivio contiene digest, quindi è riservato: evidenza ammessa solo
|
||||
percorso, owner, mode, timestamp e checksum dell'archivio. Il rollback dual-key ripristina la route
|
||||
e il servizio revisionati, esegue `nginx -t` e fa reload solo autorizzato; non ripristina chiavi
|
||||
revocate, PostgreSQL, sessioni legacy, indici Qdrant o cache Ollama.
|
||||
Prima di mutare, creare un archivio root-only `0600` del registro e copie protette delle sole
|
||||
configurazioni coinvolte. L'archivio contiene digest, quindi è materiale riservato: custodirlo su
|
||||
storage cifrato approvato; l'evidenza ammessa riporta solo percorso, owner, mode, timestamp e
|
||||
checksum dell'archivio. Il rollback dual-key ripristina la route e il servizio revisionati, esegue
|
||||
`nginx -t` e fa reload solo autorizzato; non ripristina chiavi revocate, PostgreSQL, sessioni
|
||||
legacy, indici Qdrant o cache Ollama.
|
||||
|
||||
La disinstallazione richiede autorizzazione esplicita, client REST migrati/revocati e rollback non
|
||||
più necessario. Solo allora disabilitare l'unità; conservare registro e backup fino alla retention
|
||||
@@ -132,11 +133,14 @@ approvata. Non inserire `dwh-auth` in Compose o in `tht start`/`tht stop`.
|
||||
|
||||
## Procedure riproducibili e secret-safe
|
||||
|
||||
Eseguire soltanto nel gate autorizzato. Le variabili seguenti contengono percorsi, timestamp e codici, mai una chiave. Il manifest e l'archivio del registro sono `0600`; l'archivio resta materiale riservato.
|
||||
Eseguire soltanto nel gate autorizzato. Le variabili seguenti contengono percorsi, timestamp e
|
||||
codici, mai una chiave. Il manifest e l'archivio del registro sono `0600`; l'archivio resta
|
||||
materiale riservato su storage cifrato approvato.
|
||||
|
||||
```bash
|
||||
run_id=$(date -u +%Y%m%dT%H%M%SZ)
|
||||
backup_root=/root/dwh-auth-provision
|
||||
registry_root=/var/lib/dwh-auth
|
||||
registry_backup="$backup_root/registry-$run_id.tar"
|
||||
manifest="$backup_root/registry-$run_id.manifest"
|
||||
sudo install -o root -g root -m 0600 /dev/null "$registry_backup"
|
||||
@@ -146,52 +150,111 @@ sudo sh -c 'sha256sum "$1" > "$2"' sh "$registry_backup" "$manifest"
|
||||
if sudo sha256sum -c "$manifest" >/dev/null; then printf 'registry_manifest=PASS\n'; else printf 'registry_manifest=FAIL\n' >&2; exit 1; fi
|
||||
```
|
||||
|
||||
Per ripristinare, fermare prima il servizio, verificare il manifest senza stamparne il contenuto, estrarre l'archivio solo nel root autorizzato, rieseguire `dwh-auth check` e avviare l'unità. Conservare archivio e manifest per la retention approvata; non sovrascrivere né cancellare record per correggere un errore.
|
||||
Il ripristino non sovrappone mai un tar al registro attivo. Estrarre prima in staging nello stesso
|
||||
filesystem di `/var/lib`, verificare il candidato, rinominare il registro attuale in una copia
|
||||
recuperabile e sostituirlo. Non cancellare il pre-ripristino: serve al rollback se `check` o
|
||||
l'avvio falliscono.
|
||||
|
||||
```bash
|
||||
registry_staging="/var/lib/.dwh-auth-restore-$run_id"
|
||||
registry_candidate="$registry_staging/dwh-auth"
|
||||
registry_previous="/var/lib/dwh-auth.pre-restore-$run_id"
|
||||
if [ -e "$registry_staging" ] || [ -e "$registry_previous" ]; then printf 'registry_restore=FAIL\n' >&2; exit 1; fi
|
||||
if ! sudo sha256sum -c "$manifest" >/dev/null; then printf 'registry_restore=FAIL\n' >&2; exit 1; fi
|
||||
sudo systemctl stop dwh-auth
|
||||
sudo tar --acls --xattrs -C /var/lib -xf "$registry_backup"
|
||||
sudo /usr/local/sbin/dwh-auth --registry-root /var/lib/dwh-auth check
|
||||
sudo systemctl start dwh-auth
|
||||
printf 'registry_restore=PASS\n'
|
||||
if ! sudo install -d -o root -g root -m 0700 "$registry_staging"; then printf 'registry_restore=FAIL\n' >&2; exit 1; fi
|
||||
if ! sudo tar --acls --xattrs -C "$registry_staging" -xf "$registry_backup"; then printf 'registry_restore=FAIL\n' >&2; exit 1; fi
|
||||
if ! sudo /usr/local/sbin/dwh-auth --registry-root "$registry_candidate" check; then printf 'registry_restore=FAIL\n' >&2; exit 1; fi
|
||||
if ! sudo systemctl stop dwh-auth; then printf 'registry_restore=FAIL\n' >&2; exit 1; fi
|
||||
if ! sudo mv -T -- "$registry_root" "$registry_previous"; then
|
||||
if sudo systemctl start dwh-auth; then printf 'registry_restore_rollback=PASS\n' >&2; else printf 'registry_restore_rollback=FAIL\n' >&2; fi
|
||||
exit 1
|
||||
fi
|
||||
if ! sudo mv -T -- "$registry_candidate" "$registry_root"; then
|
||||
if ! sudo mv -T -- "$registry_previous" "$registry_root"; then printf 'registry_restore_rollback=FAIL\n' >&2; exit 1; fi
|
||||
if sudo /usr/local/sbin/dwh-auth --registry-root "$registry_root" check && sudo systemctl start dwh-auth; then printf 'registry_restore_rollback=PASS\n' >&2; else printf 'registry_restore_rollback=FAIL\n' >&2; fi
|
||||
exit 1
|
||||
fi
|
||||
if sudo /usr/local/sbin/dwh-auth --registry-root "$registry_root" check && sudo systemctl start dwh-auth; then
|
||||
printf 'registry_restore=PASS\n'
|
||||
else
|
||||
sudo systemctl stop dwh-auth || true
|
||||
if ! sudo mv -T -- "$registry_root" "$registry_staging/failed-dwh-auth"; then printf 'registry_restore_rollback=FAIL\n' >&2; exit 1; fi
|
||||
if ! sudo mv -T -- "$registry_previous" "$registry_root"; then printf 'registry_restore_rollback=FAIL\n' >&2; exit 1; fi
|
||||
if sudo /usr/local/sbin/dwh-auth --registry-root "$registry_root" check && sudo systemctl start dwh-auth; then printf 'registry_restore_rollback=PASS\n' >&2; else printf 'registry_restore_rollback=FAIL\n' >&2; fi
|
||||
exit 1
|
||||
fi
|
||||
```
|
||||
|
||||
Per i test socket, creare la configurazione curl `0600` leggendo il file chiave direttamente nel file di configurazione: il valore non passa in argv, ambiente o stdout.
|
||||
Per le prove, creare file header `0600` che contengono esattamente `X-API-Key: valore`. Il valore
|
||||
passa dal file chiave al file header senza argv, ambiente o stdout. I file header sono materiale
|
||||
segreto con la stessa custodia e retention delle chiavi.
|
||||
|
||||
```bash
|
||||
key_file=/root/dwh-auth-provision/psd-mac-primary.key
|
||||
curl_cfg=/root/dwh-auth-provision/dwh-auth-new.curl
|
||||
random_cfg=/root/dwh-auth-provision/dwh-auth-random.curl
|
||||
sudo install -o root -g root -m 0600 /dev/null "$curl_cfg"
|
||||
sudo install -o root -g root -m 0600 /dev/null "$random_cfg"
|
||||
sudo sh -c '{ printf "%s" "header = X-API-Key: "; tr -d "\r\n" < "$1"; printf "\n"; } > "$2"' sh "$key_file" "$curl_cfg"
|
||||
sudo sh -c 'printf "%s\n" "header = X-API-Key: invalid-test" > "$1"' sh "$random_cfg"
|
||||
v1_key_file="$key_output"
|
||||
legacy_key_file=/root/dwh-auth-provision/legacy-shared.key
|
||||
v1_header_file=/root/dwh-auth-provision/dwh-auth-v1.header
|
||||
legacy_header_file=/root/dwh-auth-provision/dwh-auth-legacy.header
|
||||
random_header_file=/root/dwh-auth-provision/dwh-auth-random.header
|
||||
if ! sudo python3 -c '
|
||||
import pathlib, sys
|
||||
if any(b"\n" in pathlib.Path(path).read_bytes() for path in sys.argv[1:]):
|
||||
raise SystemExit(1)
|
||||
' "$v1_key_file" "$legacy_key_file"; then
|
||||
printf 'key_file_bytes=FAIL\n' >&2
|
||||
exit 1
|
||||
fi
|
||||
printf 'key_file_bytes=PASS\n'
|
||||
for header_file in "$v1_header_file" "$legacy_header_file" "$random_header_file"; do
|
||||
sudo install -o root -g root -m 0600 /dev/null "$header_file"
|
||||
done
|
||||
sudo sh -c '{ printf "%s" "X-API-Key: "; dd if="$1" bs=65536 status=none; printf "\n"; } > "$2"' sh "$v1_key_file" "$v1_header_file"
|
||||
sudo sh -c '{ printf "%s" "X-API-Key: "; dd if="$1" bs=65536 status=none; printf "\n"; } > "$2"' sh "$legacy_key_file" "$legacy_header_file"
|
||||
sudo sh -c 'printf "%s\n" "X-API-Key: invalid-test" > "$1"' sh "$random_header_file"
|
||||
```
|
||||
|
||||
Il socket `/verify` deve restituire 204 per il file nuovo e 401 per configurazione casuale e richiesta senza header; stampare soltanto il codice.
|
||||
Il socket `/verify` deve restituire 204 per v1 e legacy durante il dual-key, 401 per file casuale
|
||||
e richiesta senza header. Stampare solo PASS/FAIL.
|
||||
|
||||
```bash
|
||||
status=$(sudo curl --config "$curl_cfg" --unix-socket /run/dwh-auth/verify.sock --output /dev/null --silent --show-error --write-out '%{http_code}' http://localhost/verify)
|
||||
[ "$status" = 204 ] && printf 'socket_new=PASS\n' || { printf 'socket_new=FAIL\n' >&2; exit 1; }
|
||||
status=$(sudo curl --config "$random_cfg" --unix-socket /run/dwh-auth/verify.sock --output /dev/null --silent --show-error --write-out '%{http_code}' http://localhost/verify)
|
||||
status=$(sudo curl --header "@$v1_header_file" --unix-socket /run/dwh-auth/verify.sock --output /dev/null --silent --show-error --write-out '%{http_code}' http://localhost/verify)
|
||||
[ "$status" = 204 ] && printf 'socket_v1=PASS\n' || { printf 'socket_v1=FAIL\n' >&2; exit 1; }
|
||||
status=$(sudo curl --header "@$legacy_header_file" --unix-socket /run/dwh-auth/verify.sock --output /dev/null --silent --show-error --write-out '%{http_code}' http://localhost/verify)
|
||||
[ "$status" = 204 ] && printf 'socket_legacy=PASS\n' || { printf 'socket_legacy=FAIL\n' >&2; exit 1; }
|
||||
status=$(sudo curl --header "@$random_header_file" --unix-socket /run/dwh-auth/verify.sock --output /dev/null --silent --show-error --write-out '%{http_code}' http://localhost/verify)
|
||||
[ "$status" = 401 ] && printf 'socket_random=PASS\n' || { printf 'socket_random=FAIL\n' >&2; exit 1; }
|
||||
status=$(sudo curl --unix-socket /run/dwh-auth/verify.sock --output /dev/null --silent --show-error --write-out '%{http_code}' http://localhost/verify)
|
||||
[ "$status" = 401 ] && printf 'socket_missing=PASS\n' || { printf 'socket_missing=FAIL\n' >&2; exit 1; }
|
||||
```
|
||||
|
||||
Per HTTPS reale usare la configurazione protetta e la CA approvata contro `/dwh/rpc/ping`: PostgREST può restituire qualsiasi 2xx, non si pretende 204. La prova 401 usa solo configurazione casuale protetta.
|
||||
Per HTTPS reale usare i file header protetti e la CA approvata contro `/dwh/rpc/ping`: PostgREST
|
||||
può restituire qualsiasi 2xx, non si pretende 204. Prima della revoca, v1 e legacy devono dare
|
||||
2xx; il file casuale deve dare 401.
|
||||
|
||||
```bash
|
||||
ping_url=https://supabase-aritmolab.policlinicosandonato.it/dwh/rpc/ping
|
||||
ca_file=/root/dwh-auth-provision/psd-dwh-ca.pem
|
||||
status=$(sudo curl --config "$curl_cfg" --cacert "$ca_file" --connect-timeout 5 --max-time 15 --output /dev/null --silent --show-error --write-out '%{http_code}' "$ping_url")
|
||||
case "$status" in 2??) printf 'https_new=PASS\n' ;; *) printf 'https_new=FAIL\n' >&2; exit 1 ;; esac
|
||||
status=$(sudo curl --config "$random_cfg" --cacert "$ca_file" --connect-timeout 5 --max-time 15 --output /dev/null --silent --show-error --write-out '%{http_code}' "$ping_url")
|
||||
status=$(sudo curl --header "@$v1_header_file" --cacert "$ca_file" --connect-timeout 5 --max-time 15 --output /dev/null --silent --show-error --write-out '%{http_code}' "$ping_url")
|
||||
case "$status" in 2??) printf 'https_v1_pre_revoke=PASS\n' ;; *) printf 'https_v1_pre_revoke=FAIL\n' >&2; exit 1 ;; esac
|
||||
status=$(sudo curl --header "@$legacy_header_file" --cacert "$ca_file" --connect-timeout 5 --max-time 15 --output /dev/null --silent --show-error --write-out '%{http_code}' "$ping_url")
|
||||
case "$status" in 2??) printf 'https_legacy_pre_revoke=PASS\n' ;; *) printf 'https_legacy_pre_revoke=FAIL\n' >&2; exit 1 ;; esac
|
||||
status=$(sudo curl --header "@$random_header_file" --cacert "$ca_file" --connect-timeout 5 --max-time 15 --output /dev/null --silent --show-error --write-out '%{http_code}' "$ping_url")
|
||||
[ "$status" = 401 ] && printf 'https_random=PASS\n' || { printf 'https_random=FAIL\n' >&2; exit 1; }
|
||||
```
|
||||
|
||||
Per provare 503 in una finestra approvata, registrare l'orario, fermare temporaneamente l'unità, eseguire il ping con timeout e trap di ripristino; il comando deve stampare solo PASS/FAIL.
|
||||
Dopo l'osservazione, revocare solo la legacy usando il suo ID pubblico già registrato. Dopo la
|
||||
revoca v1 resta 2xx e legacy diventa 401 anche via HTTPS.
|
||||
|
||||
```bash
|
||||
legacy_key_id=legacy-shared
|
||||
sudo /usr/local/sbin/dwh-auth --registry-root "$registry_root" key revoke --key-id "$legacy_key_id" --reason shared-credential-rotation
|
||||
status=$(sudo curl --header "@$v1_header_file" --cacert "$ca_file" --connect-timeout 5 --max-time 15 --output /dev/null --silent --show-error --write-out '%{http_code}' "$ping_url")
|
||||
case "$status" in 2??) printf 'https_v1_post_revoke=PASS\n' ;; *) printf 'https_v1_post_revoke=FAIL\n' >&2; exit 1 ;; esac
|
||||
status=$(sudo curl --header "@$legacy_header_file" --cacert "$ca_file" --connect-timeout 5 --max-time 15 --output /dev/null --silent --show-error --write-out '%{http_code}' "$ping_url")
|
||||
[ "$status" = 401 ] && printf 'https_legacy_post_revoke=PASS\n' || { printf 'https_legacy_post_revoke=FAIL\n' >&2; exit 1; }
|
||||
```
|
||||
|
||||
Per provare 503 in una finestra approvata, registrare l'orario, fermare temporaneamente l'unità,
|
||||
eseguire il ping con timeout e trap di ripristino; il comando deve stampare solo PASS/FAIL.
|
||||
|
||||
```bash
|
||||
was_active=$(sudo systemctl is-active dwh-auth || true)
|
||||
@@ -199,20 +262,47 @@ was_active=$(sudo systemctl is-active dwh-auth || true)
|
||||
restore_auth() { sudo systemctl start dwh-auth; }
|
||||
trap restore_auth EXIT INT TERM
|
||||
sudo systemctl stop dwh-auth
|
||||
status=$(sudo curl --config "$random_cfg" --cacert "$ca_file" --connect-timeout 5 --max-time 15 --output /dev/null --silent --show-error --write-out '%{http_code}' "$ping_url" || true)
|
||||
status=$(sudo curl --header "@$random_header_file" --cacert "$ca_file" --connect-timeout 5 --max-time 15 --output /dev/null --silent --show-error --write-out '%{http_code}' "$ping_url" || true)
|
||||
[ "$status" = 503 ] && printf 'https_auth_down=PASS\n' || { printf 'https_auth_down=FAIL\n' >&2; exit 1; }
|
||||
sudo systemctl start dwh-auth
|
||||
trap - EXIT INT TERM
|
||||
```
|
||||
|
||||
Lo scan journal non salva righe grezze: emette solo PASS/FAIL.
|
||||
Lo scan journal non salva righe grezze: controlla davvero le chiavi v1 e legacy leggendo solo i
|
||||
percorsi dei file da argv, e conserva anche la difesa generica per prefisso e digest. Il filtro
|
||||
emette solo PASS/FAIL.
|
||||
|
||||
```bash
|
||||
since=$(date -u -d '15 minutes ago' +%Y-%m-%dT%H:%M:%SZ)
|
||||
if sudo journalctl -u dwh-auth --since "$since" --no-pager --output=cat | grep -E 'thtdwh_v1|secret_sha256' >/dev/null; then printf 'journal_secret_scan=FAIL\n' >&2; exit 1; else printf 'journal_secret_scan=PASS\n'; fi
|
||||
if sudo python3 -c '
|
||||
import pathlib, subprocess, sys
|
||||
try:
|
||||
actual_keys = {pathlib.Path(path).read_bytes() for path in sys.argv[2:]}
|
||||
result = subprocess.run(
|
||||
["journalctl", "-u", "dwh-auth", "--since", sys.argv[1], "--no-pager", "--output=cat"],
|
||||
check=False,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.DEVNULL,
|
||||
)
|
||||
except OSError:
|
||||
raise SystemExit(2)
|
||||
if result.returncode != 0:
|
||||
raise SystemExit(2)
|
||||
for line in result.stdout.splitlines(keepends=True):
|
||||
if b"thtdwh_v1" in line or b"secret_sha256" in line or any(key in line for key in actual_keys):
|
||||
raise SystemExit(1)
|
||||
' "$since" "$v1_key_file" "$legacy_key_file"; then
|
||||
printf 'journal_actual_key_scan=PASS\n'
|
||||
else
|
||||
printf 'journal_actual_key_scan=FAIL\n' >&2
|
||||
exit 1
|
||||
fi
|
||||
```
|
||||
|
||||
Dopo rollback verificato e migrazione/revoca di ogni client REST, la disinstallazione resta condizionata all'approvazione: eseguire `sudo systemctl disable --now dwh-auth`, ma mantenere registro, backup e manifest protetti per la retention; non cancellarli durante il rollback.
|
||||
Dopo rollback verificato e migrazione/revoca di ogni client REST, la disinstallazione resta
|
||||
condizionata all'approvazione: eseguire `sudo systemctl disable --now dwh-auth`, ma mantenere
|
||||
registro, backup, manifest e file header protetti per la retention; non cancellarli durante il
|
||||
rollback.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
|
||||
@@ -18,22 +18,22 @@ Richiedere prima autorizzazione per SHA congelato, target, rollback e impatto le
|
||||
2. Costruire con `bash scripts/build-dwh-auth.sh --output /tmp/dwh-auth-release`; registrare solo SHA sorgente e checksum binario.
|
||||
3. Installare binario/unit/tmpfiles come nella [guida server](../install/dwh-auth-server.md): registry `root:dwh-auth` `2750`, lock/record `0640`, socket `dwh-auth:www-data` `0660`.
|
||||
4. Importare una sola legacy `legacy-shared` dal file protetto e creare `psd-mac-primary` in nuovo file `0600` sotto `/root/dwh-auth-provision/`; mai segreti in argv, ambiente, log o evidenze.
|
||||
5. Eseguire `dwh-auth check`, `systemd-analyze verify`, avviare l'unità e testare sul socket Unix con config curl protette `0600`: nuova=204, legacy=204, casuale=401, assente=401.
|
||||
5. Eseguire `dwh-auth check`, `systemd-analyze verify`, avviare l'unità e testare sul socket Unix con file header curl protetti `0600`: v1=204, legacy=204, casuale=401, assente=401.
|
||||
6. Salvare solo ID pubblici, owner/mode, stato unit/socket, timestamp, checksum binario/config e rollback. Non modificare Nginx in questo gate.
|
||||
|
||||
## Gate B — Task 10, Nginx e client
|
||||
|
||||
Serve un secondo consenso: presentare file, backup, canale consegna Mac, osservazione ed esiti 204/401/503.
|
||||
Serve un secondo consenso: presentare file, backup, canale consegna Mac, osservazione ed esiti 2xx/401/503.
|
||||
|
||||
1. Creare copie timestampate `root:root` `0600` di `/etc/nginx/sites-available/policlinicosandonato` e file coinvolti; non allegare configurazioni Nginx grezze alle evidenze.
|
||||
2. Aggiungere solo `/etc/nginx/conf.d/dwh-auth-rate-limit.conf` e route DWH; preservare upstream `http://127.0.0.1:3001/`, mantenere byte-identiche le location vector e rimuovere la chiave prima di PostgREST.
|
||||
3. Eseguire checker strutturale, scansione segreti con solo `PASS/FAIL` e metadati, installare candidati e `sudo nginx -t`. No raw diff: non eseguire o conservare raw diff, `nginx -T` o dump: il file legacy può contenere la chiave. Se uno fallisce, ripristinare backup prima di reload e registrare FAIL sanitizzato.
|
||||
4. Dopo consenso fare reload, poi HTTPS `.it` con CA e config curl protette: legacy=2xx, nuova=2xx, casuale=401, assente=401 su `/dwh/rpc/ping`; guasto autenticatore=503, mai accesso permissivo.
|
||||
4. Dopo consenso fare reload, poi HTTPS `.it` con CA e file header curl protetti 0600: v1=2xx, legacy=2xx, casuale=401, assente=401 su `/dwh/rpc/ping`; guasto autenticatore=503, mai accesso permissivo.
|
||||
5. Consegnare al Mac chiave e CA separatamente, verificare fingerprint fuori banda, configurare vault GUI o `API_KEY_FILE`, poi **Validate workspace source** e **Test workspace connections**.
|
||||
6. Dopo osservazione revocare `legacy-shared` con ragione `shared-credential-rotation`; nuova=204, legacy=401 e journal limitato senza chiavi/digest.
|
||||
6. Dopo osservazione revocare `legacy-shared` con ragione `shared-credential-rotation`; v1=2xx post-revoca, legacy=401 post-revoca e journal limitato senza chiavi/digest.
|
||||
|
||||
## Rollback e chiusura
|
||||
|
||||
Durante dual-key il rollback ripristina solo route/servizio revisionati, verifica `nginx -t` e fa reload autorizzato. Non ripristina chiavi revocate, PostgreSQL, dati legacy o stack. Scatta per TLS, risposte inattese, salute degradata o assenza di consenso.
|
||||
|
||||
Activity 1 diventa `PASS` solo con nuova positiva, legacy 401, servizio/Nginx validi, log sanitizzati, rollback leggibile e accettazione owner; poi avanza a Activity 2, con programma ancora `SURVEY_NO_GO`. Compilare [evidenza](../testing/evidence/psd-dwh-auth-rollout-report-template.md) e [collaudo](../testing/dwh-auth-manual-acceptance.md).
|
||||
Activity 1 diventa `PASS` solo con v1=2xx post-revoca, legacy=401 post-revoca, servizio/Nginx validi, log sanitizzati, rollback leggibile e accettazione owner; poi avanza a Activity 2, con programma ancora `SURVEY_NO_GO`. Compilare [evidenza](../testing/evidence/psd-dwh-auth-rollout-report-template.md) e [collaudo](../testing/dwh-auth-manual-acceptance.md).
|
||||
|
||||
@@ -16,12 +16,12 @@ clinici.
|
||||
| Caso | Azione autorizzata | Atteso | Evidenza ammessa |
|
||||
| --- | --- | --- | --- |
|
||||
| Registro | `check`, `key list`, `key status` | Stato e soli ID pubblici | ID, status, owner/mode, timestamp |
|
||||
| Socket locale | Config curl protetta, nuova/legacy | `204` durante dual-key | codice, unit/socket status |
|
||||
| Negativo locale | Config casuale e richiesta senza header | `401` | codice, nessun valore header |
|
||||
| Socket locale | File header protetti, v1/legacy | `204` v1 e legacy durante dual-key | codice, unit/socket status |
|
||||
| Negativo locale | File header casuale e richiesta senza header | `401` | codice, nessun valore header |
|
||||
| Guasto controllato | Autenticatore/registro non disponibili nel test approvato | `503`, mai accesso | codice e rollback |
|
||||
| HTTPS reale | `/dwh/rpc/ping` con CA approvata | qualsiasi `2xx`, TLS valido | ID, esito e approvazione fingerprint |
|
||||
| HTTPS dual-key | `/dwh/rpc/ping` con CA approvata, file header v1/legacy | v1 e legacy qualsiasi `2xx`, TLS valido | ID, esito e approvazione fingerprint |
|
||||
| Mac | **Validate workspace source**, **Test workspace connections** | Ping positivo | timestamp e stato GUI |
|
||||
| Revoca | Chiave precedente dopo osservazione | `401`; nuova ancora positiva | ID pubblico e codici |
|
||||
| Revoca | Chiave legacy dopo osservazione | v1 qualsiasi `2xx`; legacy `401` post-revoca | ID pubblico e codici |
|
||||
| Trasporti | Server PSD diretto e SSH diagnostico | nessuna chiave `dwh-auth` | trasporto selezionato |
|
||||
|
||||
## Sequenza
|
||||
@@ -30,7 +30,7 @@ clinici.
|
||||
stack. Nessun reload Nginx.
|
||||
2. Al Gate B, fare backup protetti, `nginx -t`, reload autorizzato e ping `.it` con CA verificata.
|
||||
3. Configurare il Mac nel vault GUI o con `API_KEY_FILE`; verificare ping e ID pubblico.
|
||||
4. Dopo la finestra approvata, revocare legacy, ripetere nuova positiva/legacy 401 e controllare
|
||||
4. Dopo la finestra approvata, revocare legacy, ripetere v1 2xx/legacy 401 post-revoca e controllare
|
||||
solo un journal bounded sanitizzato.
|
||||
5. Verificare rollback: backup leggibili, scope limitato a route/unit; nessuna migrazione di
|
||||
sessioni legacy, indici Qdrant o cache Ollama.
|
||||
|
||||
Reference in New Issue
Block a user