ADR 022 â Mot de passe admin ArgoCD gĂ©rĂ© via ESO (2026-06-22)
Statut
Accepté (2026-06-22), validé en live le 2026-06-23. Issue #105 (MR1, sécu). Préalable à l'exposition publique de l'UI ArgoCD (MR2, ADR 023) : on durcit l'authentification avant d'ouvrir la porte. S'inscrit dans le Sprint 5 (accÚs plateforme).
Contexte
ArgoCD est posé par le bootstrap Ansible (#72) et n'est aujourd'hui accessible
qu'en kubectl port-forward. Le mot de passe admin est le secret initial généré
aléatoirement par le chart (argocd-initial-admin-secret) : acceptable tant que
l'accĂšs est local, inacceptable dĂšs qu'on expose l'UI publiquement (MR2). Une
console ArgoCD, c'est les clés du royaume GitOps (elle réconcilie tout le cluster).
Contraintes habituelles du projet : cluster EKS éphémÚre, GitOps via ArgoCD, tout déclaratif et versionné, aucun secret en clair dans Git. Le pattern ESO + IRSA est déjà éprouvé deux fois (#76 mot de passe Grafana, #77 webhook Slack).
DĂ©cision 1 â Mot de passe admin gĂ©rĂ© via ESO (et non le secret initial)
On remplace le mot de passe initial par un mot de passe maßtrisé, alimenté par
le mĂȘme pipeline que Grafana/Slack : secret AWS Secrets Manager â ESO â argocd-secret.
Source unique cÎté AWS, rien en clair dans Git, rotation centralisée.
DĂ©cision 2 â Stocker le HASH bcrypt, pas un mot de passe en clair
Contrairement Ă Grafana (qui accepte un mot de passe en clair via admin.existingSecret),
ArgoCD stocke le mot de passe admin hashé en bcrypt dans argocd-secret
(clés admin.password = hash, admin.passwordMtime = date de validité).
Conséquence : on ne peut pas se contenter d'un random_password Terraform comme
Grafana. Et la fonction bcrypt() de Terraform régénÚre un sel à chaque apply
â hash diffĂ©rent Ă chaque run (diff perpĂ©tuel, passwordMtime qui churne). On traite
donc le bcrypt comme le webhook Slack (#77) : une valeur externe générée une
fois en local (argocd account bcrypt ou htpasswd -nbBC 10 "" <pass>), fournie via
TF_VAR_argocd_admin_bcrypt (variable GitLab protected + masked), jamais commitée.
Terraform ne fait que la stocker dans fastapi-eks/argocd.
Le passwordMtime est une valeur littérale (RFC3339) injectée par le template de
l'ExternalSecret : il dit « depuis quand le mot de passe est valide » (les sessions
antérieures sont invalidées). On le bumpe à la main lors d'une rotation.
DĂ©cision 3 â creationPolicy: Merge (ne pas se battre avec le chart)
argocd-secret est déjà possédé par le chart ArgoCD (il contient aussi
server.secretkey, etc.). Si l'ExternalSecret le créait (creationPolicy: Owner
comme Grafana), ESO et ArgoCD se disputeraient la propriĂ©tĂ© du mĂȘme objet.
On utilise donc creationPolicy: Merge et template.mergePolicy: Merge : ESO
patche le secret existant en y ajoutant les seules clés admin.password +
admin.passwordMtime, sans en prendre la propriété ni écraser les autres clés.
DĂ©cision 4 â ArgoCD gĂšre sa propre config en GitOps (pas via Ansible)
Le SecretStore + l'ExternalSecret du ns argocd sont déployés par une Application
ArgoCD dédiée argocd-config (app-of-apps, path: k8s/platform/argocd), comme
monitoring/loki/etc. â pas appliquĂ©s Ă la main par le bootstrap Ansible.
ArgoCD ne dĂ©ploie pas argocd-secret lui-mĂȘme (ce serait mĂ©ta et conflictuel) :
il déploie l'ExternalSecret, et c'est ESO qui patche argocd-secret. Aucun conflit
de réconciliation ArgoCD/ESO. Cohérent avec le reste de la plateforme (GitOps pur).
ĂcartĂ© : application par Ansible (sortirait ce bout de config du flux GitOps).
PiÚges traités
bcrypt()Terraform non dĂ©terministe â valeur externe (cf. DĂ©cision 2).- PropriĂ©tĂ© partagĂ©e de
argocd-secretâMerge, pasOwner(cf. DĂ©cision 3). - Secret initial rĂ©siduel :
argocd-initial-admin-secretreste créé par le chart mais devient sans effet (le login litadmin.password). On peut le supprimer aprÚs cutover ; non bloquant. - Timing live : l'ExternalSecret en
Mergeattend queargocd-secretexiste (créé par le chart à l'install) ; etargocd-serverdoit relire le secret aprÚs le patch ESO. Confirmé live le 2026-06-23 : ESOSecretSynced, login admin OK du premier coup (la variablemaskeddu bcrypt n'a posé aucun souci).
Conséquences
- Least-privilege : l'IRSA ESO est étendu au seul 4e ARN (
fastapi-eks/argocd), pas de wildcard (app + grafana + alertmanager-slack + argocd). - Ătape manuelle unique (live) : gĂ©nĂ©rer le bcrypt et fournir
TF_VAR_argocd_admin_bcryptà l'applypersistent (fait le 2026-06-23). - Validé en live le 2026-06-23 : login admin avec le mot de passe géré OK,
conjointement avec l'exposition (ADR 023) et le SSO (ADR 024). Hors cluster :
kustomize build(k8s/platform/argocd),tfsec(0 HIGH). - GitOps pur : aucune modif Ansible, réconcilié par l'Application
argocd-config.
Ăvolution possible
- SSO OIDC (#106) : une fois le SSO en place, le mot de passe admin devient un
accÚs break-glass ; on pourra désactiver l'utilisateur admin (
admin.enabled: false). - Keycloak central sur le homelab : IdP cross-cluster (EKS + homelab + platform), suite logique du SSO (cf. #106).
Date : 2026-06-22 Sprint : 5 Issue : #105