# Phase 0a — Pre-cluster Secret Bootstrap This directory contains tooling for the KeePassXC bootstrap phase (T01 Phase 0a). No secrets are stored here — only scripts and documentation. ## Why KeePassXC first? The single-credential bootstrap principle (Decision D1): one master password unlocks the KeePassXC vault; all other credentials are generated inside it. KeePassXC is the pre-cluster source of truth. After the K3s cluster is running, secrets migrate into HashiCorp Vault (T01 Phase 0b) and KeePassXC becomes the break-glass / dev-local backup. ## KeePassXC database structure Create a new `.kdbx` database. Use a strong master password stored in your personal password manager (Bitwarden, 1Password, etc.). Recommended group structure: ``` net-kingdom/ ├── privacyIDEA/ │ ├── pi-admin (username: pi-admin, password: PI_ADMIN_PASSWORD) │ ├── database (username: privacyidea, password: PI_DB_PASSWORD) │ ├── SECRET_KEY (password field only — PI_SECRET_KEY value) │ ├── PI_PEPPER (password field only — PI_PEPPER value) │ └── PI_ENCFILE (binary attachment: pi.enc — generate after deploy) ├── PostgreSQL/ │ ├── postgres root (username: postgres, password: PG_ROOT_PASSWORD) │ ├── keycloak user (username: keycloak, password: PG_KEYCLOAK_PASSWORD) │ └── privacyidea user (username: privacyidea — same password as PI_DB_PASSWORD) ├── Keycloak/ │ ├── admin (username: admin, password: KC_ADMIN_PASSWORD) │ └── database (username: keycloak — same password as PG_KEYCLOAK_PASSWORD) ├── Break-glass/ │ ├── break-glass (username: break-glass, password: BREAKGLASS_PASSWORD) │ └── recovery-otp (TOTP seed — enroll manually after Keycloak is up) └── Vault/ └── (populated in Phase 0b after Vault is deployed) ``` ## Workflow ### Step 1 — Generate secrets ```bash chmod +x gen-secrets.sh ./gen-secrets.sh ./secrets ``` This writes `.env` files to `./secrets/` (gitignored). Inspect each file, then copy each value into the appropriate KeePassXC entry. ### Step 2 — Create the age encryption key (one-time) ```bash age-keygen -o ~/net-kingdom-ops-bundle.key ``` The public key prints to stdout. The private key is in the `.key` file. Store the `.key` file somewhere safe (NOT in this repo; NOT in the secrets/ dir). ### Step 3 — Create the encrypted ops bundle ```bash chmod +x pack-bundle.sh ./pack-bundle.sh ./secrets "age1..." ops-bundle.tar.age ``` Store `ops-bundle.tar.age` offsite (cloud storage, external drive, separate location). ### Step 4 — Shred the generated files ```bash find ./secrets -type f -exec shred -u {} \; rm -rf ./secrets ``` ### Step 5 — PI_ENCFILE (after privacyIDEA container is running — T04) ```bash # Generate the encryption key inside the running container: kubectl exec -n mfa -- pi-manage create_enckey # Extract it: kubectl cp -n mfa :/etc/privacyidea/enckey ./pi.enc # Store as a binary attachment in KeePassXC → net-kingdom/privacyIDEA/PI_ENCFILE # Create the K8s Secret: kubectl create secret generic privacyidea-enckey \ --from-file=PI_ENCFILE=./pi.enc \ --namespace mfa # Shred the local copy: shred -u ./pi.enc ``` ## Notes on secret reuse Some secrets appear in multiple components — this is intentional to avoid drift. When adding to KeePassXC, note the cross-references rather than duplicating the value: - `PI_DB_PASSWORD` == PostgreSQL `privacyidea` user password - `KC_DB_PASSWORD` == PostgreSQL `keycloak` user password Use KeePassXC references (`{REF:P@T:UUID}`) to avoid maintaining two copies. ## Phase 0b — HashiCorp Vault (after T02, once K3s is running) See `../vault/` (created in T01 Phase 0b) for: - Vault Helm chart values - ESO (External Secrets Operator) configuration - Vault secret path layout - Migration procedure: KeePassXC → Vault