# B3 — Closeout Passo B3 di `plans/PhaseB-user-checklist.md`: trasferimento credenziali e chiavi SSH al user `ci-runner` headless. ## Stato ✅ **COMPLETATO** — chiavi SSH, credenziale guest Windows e GiteaPAT disponibili a `ci-runner`; PoC headless verificato. ## Cosa è stato fatto - [x] Chiavi SSH guest Linux già presenti in `/var/lib/ci/keys/` (copiate con i template in B2). Permessi corretti: - `ci_linux`: `600` (owner `ci-runner`) - `ci_linux.pub`: `644` (owner `ci-runner`) - [x] Credenziale guest Windows `BuildVMGuest` già salvata come prerequisito del Passo 2 con `tools/ci-cred-set.py`. - Backend: `keyrings.alt.file.PlaintextKeyring` (`~/.local/share/python_keyring/keyring_pass.cfg`) - Verificata con `tools/ci-cred-check.py BuildVMGuest` → `OK (file) username='WINBUILD-2025\ci_build'` - [x] Gitea PAT salvato: ```bash sudo -u ci-runner /opt/ci/venv/bin/python \ /opt/ci/local-ci-cd-system/tools/ci-cred-set.py GiteaPAT ci-runner-linux ``` Verificato con `ci-cred-check.py GiteaPAT` → `OK (file)`. - [x] PoC headless confermato: il backend `PlaintextKeyring` non dipende da D-Bus e funziona sia da `sudo -u ci-runner` che dall'interno di `act-runner.service` (verificato durante smoke test B2 e B4). ## Deviazioni / gotcha - **`secret-tool` scartato**: il piano originale usava `secret-tool` (GNOME Secret Service). Non funziona senza una D-Bus session attiva, che non è disponibile in contesti systemd headless. Alternativa adottata: `keyrings.alt.file.PlaintextKeyring` — nessuna dipendenza da D-Bus, file in chiaro in `~/.local/share/python_keyring/keyring_pass.cfg` (accessibile solo a `ci-runner`). Configurazione in `~/.local/share/python_keyring/keyringrc.cfg`. - **Credenziale B2**: il prerequisito del Passo 2 anticipava la parte minima di B3 (solo `BuildVMGuest`) per sbloccare lo smoke test Windows. In B3 si è completato aggiungendo il GiteaPAT e fissando i permessi chiavi SSH. ## Riferimenti commit - `3921758` — feat: add credential management scripts (`tools/ci-cred-set.py`, `tools/ci-cred-check.py`)