Gestión de Secretos¶
Parte de la guía de implementación
- Sealed Secrets — Fase 4 wave 0; CAPN (Cluster API Provider for Incus) Fase 6.
- OAuth Dex — Fase 4 paso 4.7.
- Plataforma symintel (Apps de ArgoCD, ARC y OpenTofu, FTP) — 1Password → clúster.
Diagrama — tres vías de secretos¶
flowchart LR
subgraph git [En_git]
SS[Sealed_Secrets]
SOPS[SOPS_age]
end
subgraph station [Estacion_operador]
OP[1Password_SDK_DesktopAuth]
end
subgraph cluster [En_cluster]
SEC[k8s_Secret]
end
SS --> SEC
SOPS --> git
OP --> SEC
Sealed Secrets (default en clúster)¶
Sealed Secrets — un controller (~20–30 MB RAM), sin cuenta externa.
kubeseal --format yaml < secret-plano.yaml > secret-sellado.yaml
kubectl apply -f secret-sellado.yaml
rm secret-plano.yaml
La llave de cifrado vive en 1Password
Por defecto el controller genera su par de llaves dentro del clúster (y lo
renueva cada 30 días): si reinstalas K3s, se pierde y los SealedSecret
de git ya no se pueden descifrar. Aquí el par se genera una vez, se
guarda en 1Password (item sealed-secrets) y
playbook-platform-secrets.yml lo lleva al clúster; la renovación
automática está desactivada (keyrenewperiod: "0"). Cómo generarlo:
Plataforma symintel — Paso 2.
Como el certificado (la llave pública) también está en 1Password, puedes
sellar sin tener acceso al clúster:
kubeseal --cert tls.crt --format yaml < secret-plano.yaml > secret-sellado.yaml.
SOPS + age (complemento, cero pods)¶
SOPS — config pre-bootstrap (tokens Incus, etc.).
OAuth Dex (GitHub + vCluster + Incus UI) — 1Password SDK local¶
Credenciales de GitHub OAuth App y clientes Dex vCluster Platform e Incus UI (interfaz de usuario) no van en git.
| Origen | Campos |
|---|---|
GitHub (OAuth App de la org symintel) |
GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET |
Ansible (playbook-dex-oauth-secrets.yml) |
VCLUSTER_CLIENT_SECRET, INCUS_CLIENT_SECRET (genera en 1Password si faltan; aplica en Dex, Incus y/o Helm) |
INCUS_CLIENT_SECRET no se crea en GitHub. Ansible lo genera en 1Password
si falta y lo aplica en Dex e Incus.
Se leen con el 1Password Python SDK y DesktopAuth en la estación donde la app 1Password está desbloqueada.
Por defecto: cuenta personal (ONEPASSWORD_ACCOUNT_NAME=Personal), bóveda
HomeLab, un ítem con campos GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET,
VCLUSTER_CLIENT_SECRET, INCUS_CLIENT_SECRET. Probar: ansible/scripts/test-1password.py.
Homepage https://argocd.homelab.local (informativa); Redirect URIs
https://argocd.homelab.local/api/dex/callback (crítico).
Detalle: Fase 4 — 4.7
· 1password.md
Rotación de password de root (1Password SDK local)¶
playbook-rotate-root-passwords.yml
genera una password nueva por nodo (no idempotente a propósito — cada
corrida rota), la aplica en el root local de cada host (become +
ansible.builtin.user, hasheada con password_hash('sha512')) y la guarda
en la bóveda HomeLab, un ítem por host (root@invincible,
root@oliver, root@deborah, campo password). No toca SSH (Secure Shell) — el login de
root por SSH ya está deshabilitado por host_hardening
(PermitRootLogin no); esto es defensa en profundidad para consola/su -.
cd ansible
ansible-playbook -i inventory.ini playbook-rotate-root-passwords.yml
ansible-playbook -i inventory.ini playbook-rotate-root-passwords.yml \
--limit deborah
Descartados¶
- HashiCorp Vault — demasiado pesado para el M700.
- 1Password + ESO (External Secrets Operator) en clúster — requiere plan Business; usamos SDK (Software Development Kit) Python local (DesktopAuth) desde la estación.
- RustyVault — proyecto joven, sin ARM64 (arquitectura ARM de 64 bits) confirmado.
Stack completo: Stack tecnológico.