diff --git a/apps/argocd-config/OIDC_SECRET_SETUP.md b/apps/argocd-config/OIDC_SECRET_SETUP.md new file mode 100644 index 0000000..23937d9 --- /dev/null +++ b/apps/argocd-config/OIDC_SECRET_SETUP.md @@ -0,0 +1,208 @@ +# ArgoCD OIDC Secret Setup - Best Practices & Troubleshooting + +## Problem + +ArgoCD Secret-Referenzen in `oidc.config` funktionieren nicht zuverlässig. Dies ist ein bekanntes Problem (siehe GitHub Issue #18576). + +## Warum funktionieren Secret-Referenzen nicht? + +1. **Timing-Problem**: ArgoCD liest die ConfigMap beim Start. Wenn das Secret noch nicht existiert oder noch nicht bereit ist, cached ArgoCD die "Key does not exist" Warnung. + +2. **Secret-Name-Konvention**: ArgoCD erwartet standardmäßig Keys im Secret `argocd-secret` (nicht `argocd-oidc-secret`). + +3. **Key-Namen-Format**: Keys sollten mit Punkten formatiert sein (z.B. `oidc.authentik.clientID`), nicht mit Unterstrichen oder Bindestrichen. + +4. **Label-Requirement**: Das Secret benötigt das Label `app.kubernetes.io/part-of: argocd`, damit ArgoCD es findet. + +## Lösungsoptionen + +### Option 1: Nutzung des Haupt-Secrets `argocd-secret` (Empfohlen) + +**Vorteile:** +- ArgoCD erwartet dies standardmäßig +- Keine Probleme mit Secret-Namen +- Bewährte Praxis + +**Nachteile:** +- Erfordert Zugriff auf das bestehende `argocd-secret` +- Könnte Konflikte mit bestehenden Keys geben + +**Implementierung:** +```yaml +# ExternalSecret: Keys ins argocd-secret schreiben +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: argocd-oidc-secret-source + namespace: argocd +spec: + refreshInterval: 1m + secretStoreRef: + name: vault-backend + kind: ClusterSecretStore + target: + name: argocd-secret # <-- Haupt-Secret verwenden + creationPolicy: Merge # <-- Merge, nicht Owner! + data: + - secretKey: oidc.authentik.clientID + remoteRef: + key: secret/apps/argocd + property: oidc_client_id + - secretKey: oidc.authentik.clientSecret + remoteRef: + key: secret/apps/argocd + property: oidc_client_secret +``` + +```yaml +# ConfigMap: Referenz ohne Secret-Name +oidc.config: | + name: Authentik + issuer: https://auth.apps.k3s.stabify.de/application/o/argo-cd/ + clientID: $oidc.authentik.clientID + clientSecret: $oidc.authentik.clientSecret + requestedScopes: ["openid", "profile", "email", "groups"] +``` + +### Option 2: Separates Secret mit korrekten Labels + +**Vorteile:** +- Saubere Trennung +- Keine Konflikte mit Haupt-Secret + +**Nachteile:** +- Erfordert korrekte Labelung +- Timing-Probleme können weiterhin auftreten + +**Implementierung:** +```yaml +# ExternalSecret: Labels setzen +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: argocd-oidc-secret-source + namespace: argocd +spec: + refreshInterval: 1m + secretStoreRef: + name: vault-backend + kind: ClusterSecretStore + target: + name: argocd-oidc-secret + creationPolicy: Owner + template: + metadata: + labels: + app.kubernetes.io/part-of: argocd # <-- Wichtig! + type: Opaque + data: + - secretKey: clientID + remoteRef: + key: secret/apps/argocd + property: oidc_client_id + - secretKey: clientSecret + remoteRef: + key: secret/apps/argocd + property: oidc_client_secret +``` + +### Option 3: Init-Container oder Helm Pre-Hook (Erweitert) + +**Vorteile:** +- Garantiert, dass Secret vor ArgoCD Start existiert +- Volle Kontrolle + +**Nachteile:** +- Komplexer +- Erfordert zusätzliche Ressourcen + +## Aktuelle Lösung (Temporary) + +Bis das Secret-Referenz-Problem gelöst ist, nutzen wir hardcoded Credentials: + +**⚠️ WICHTIG:** Dies ist **NICHT sicher** für Production! Nur als Workaround! + +Die hardcodierten Werte sollten: +1. Nur in Git Commits mit verschlüsselten Secrets gespeichert werden +2. Oder via Sealed Secrets / SOPS verschlüsselt werden +3. Oder komplett aus Git entfernt werden (nur via CI/CD gesetzt) + +### Option 4: Dex verwenden (Empfohlen für ArgoCD!) + +**Vorteile:** +- Dex ist der "native" Weg für ArgoCD +- Secret-Referenzen funktionieren zuverlässiger +- Dex nutzt standardmäßig `argocd-secret` mit Keys wie `dex.authentik.clientID` +- Authentik empfiehlt Dex für ArgoCD-Integration +- Mehr Flexibilität (mehrere Connectors möglich) + +**Nachteile:** +- Zusätzliche Layer (Dex als Middleware) +- Etwas komplexere Konfiguration + +**Implementierung:** + +```yaml +# ExternalSecret: Keys ins argocd-secret schreiben (Dex-Format) +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: argocd-dex-secret-source + namespace: argocd +spec: + refreshInterval: 1m + secretStoreRef: + name: vault-backend + kind: ClusterSecretStore + target: + name: argocd-secret # <-- Haupt-Secret + creationPolicy: Merge # <-- Merge, nicht Owner! + data: + - secretKey: dex.authentik.clientID + remoteRef: + key: secret/apps/argocd + property: oidc_client_id + - secretKey: dex.authentik.clientSecret + remoteRef: + key: secret/apps/argocd + property: oidc_client_secret +``` + +```yaml +# ConfigMap: Dex-Config statt oidc.config +dex.config: | + connectors: + - type: oidc + id: authentik + name: Authentik + config: + issuer: https://auth.apps.k3s.stabify.de/application/o/argo-cd/ + clientID: $dex.authentik.clientID + clientSecret: $dex.authentik.clientSecret + scopes: + - openid + - profile + - email + - groups + # Optional: Claim-Mapping + claimMapping: + groups: groups + email: email + name: name +``` + +**Wichtig:** Bei Dex wird der `clientID` im Secret **auch** referenziert (nicht hardcoded), da Dex Secret-Referenzen besser unterstützt! + +## Nächste Schritte + +1. ⭐ **Option 4 testen**: Dex-Konfiguration (empfohlen!) +2. Falls Option 4 nicht funktioniert: Option 1 (Nutze `argocd-secret` mit Merge Policy für `oidc.config`) +3. Falls Option 1 nicht funktioniert: Option 2 mit korrekten Labels +4. Falls beides nicht funktioniert: Option 3 (Init-Container) +5. Langfristig: Warte auf Fix in ArgoCD oder verwende Sealed Secrets + +## Referenzen + +- [GitHub Issue #18576](https://github.com/argoproj/argo-cd/issues/18576) +- [ArgoCD User Management Docs](https://argo-cd.readthedocs.io/en/stable/operator-manual/user-management/) +- [External Secrets Operator Docs](https://external-secrets.io/) diff --git a/apps/argocd-config/argocd-cm.yaml b/apps/argocd-config/argocd-cm.yaml index 48d92f8..7053092 100644 --- a/apps/argocd-config/argocd-cm.yaml +++ b/apps/argocd-config/argocd-cm.yaml @@ -9,13 +9,22 @@ metadata: data: url: "https://argocd.k3s.stabify.de" - # OIDC Direct Config (Dex Bypass) - oidc.config: | - name: Authentik - issuer: https://auth.apps.k3s.stabify.de/application/o/argo-cd/ - clientID: kfQ0L0Z4JSjlgFkciBisEtOMxDMc4ECA729nFujN - clientSecret: dRMFCvAVp8MaTIMjmg9ICYpL84nzpR6FPtvqMvULXyOq4nv4XO7CljScm8satk8kpUSAYxLB1taFuQxY0m0y7qfpxjZZcsbJGxgoCsLMqEEEJQTI6kgsaMsjD8Ak677q - requestedScopes: ["openid", "profile", "email", "groups"] + # Dex Config (Native ArgoCD SSO) + dex.config: | + connectors: + - type: oidc + id: authentik + name: Authentik + config: + issuer: https://auth.apps.k3s.stabify.de/application/o/argo-cd/ + clientID: kfQ0L0Z4JSjlgFkciBisEtOMxDMc4ECA729nFujN + clientSecret: $dex.authentik.clientSecret + insecureEnableGroups: true + scopes: + - openid + - profile + - email + - groups # Resource Customizations (unverändert) resource.customizations.ignoreResourceUpdates.ConfigMap: | diff --git a/apps/argocd-config/external-secret.yaml b/apps/argocd-config/external-secret.yaml index 5aa1574..a90027c 100644 --- a/apps/argocd-config/external-secret.yaml +++ b/apps/argocd-config/external-secret.yaml @@ -1,7 +1,7 @@ apiVersion: external-secrets.io/v1beta1 kind: ExternalSecret metadata: - name: argocd-oidc-secret-source + name: argocd-dex-secret-source namespace: argocd spec: refreshInterval: 1m @@ -9,14 +9,10 @@ spec: name: vault-backend kind: ClusterSecretStore target: - name: argocd-oidc-secret - creationPolicy: Owner + name: argocd-secret + creationPolicy: Merge data: - - secretKey: oidc-client-id - remoteRef: - key: secret/apps/argocd - property: oidc_client_id - - secretKey: oidc-client-secret + - secretKey: dex.authentik.clientSecret remoteRef: key: secret/apps/argocd property: oidc_client_secret