diff --git a/cluster/argocd/externalsecret.yaml b/cluster/argocd/externalsecret.yaml new file mode 100644 index 0000000..6f522ec --- /dev/null +++ b/cluster/argocd/externalsecret.yaml @@ -0,0 +1,30 @@ +# ------------------------------------------------------------------------------ +# ExternalSecret — Authentik OIDC credentials for ArgoCD +# Pulled from 1Password via Connect Server, materialized as argocd-oidc-secret +# in the argocd namespace. +# +# 1Password item: "argocd-oidc" in the "mk-labs" vault +# Fields: client-id, client-secret +# ------------------------------------------------------------------------------ +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: argocd-oidc-secret + namespace: argocd +spec: + secretStoreRef: + kind: ClusterSecretStore + name: onepassword-connect + refreshInterval: "1h" + target: + name: argocd-oidc-secret + creationPolicy: Owner + data: + - secretKey: client-id + remoteRef: + key: argocd-oidc + property: client-id + - secretKey: client-secret + remoteRef: + key: argocd-oidc + property: client-secret diff --git a/cluster/argocd/values.yaml b/cluster/argocd/values.yaml index 3fd50e2..fc4c9ec 100644 --- a/cluster/argocd/values.yaml +++ b/cluster/argocd/values.yaml @@ -1,4 +1,4 @@ -# ─── ArgoCD Helm values — fastpass cluster ─────────────────────────────────── +# ─── ArgoCD Helm values — fastpass cluster ───────────────────────────────────── # Chart: argo/argo-cd # Version: 7.8.23 # @@ -14,13 +14,13 @@ # # Then apply the root app-of-apps (second and final manual step): # kubectl apply -n argocd -f cluster/argocd/apps-of-apps.yaml -# ───────────────────────────────────────────────────────────────────────────── +# ─────────────────────────────────────────────────────────────────────────────── -# ─── Global ────────────────────────────────────────────────────────────────── +# ─── Global ───────────────────────────────────────────────────────────────────── global: domain: argocd.local.mk-labs.cloud -# ─── ArgoCD server ─────────────────────────────────────────────────────────── +# ─── ArgoCD server ────────────────────────────────────────────────────────────── server: # Run insecure — TLS is terminated at ingress-nginx, not at ArgoCD itself. # Without this, ArgoCD redirects to HTTPS internally and breaks behind ingress. @@ -37,29 +37,27 @@ server: nginx.ingress.kubernetes.io/ssl-passthrough: "false" nginx.ingress.kubernetes.io/backend-protocol: "HTTP" -# ─── ConfigMap — core ArgoCD settings ──────────────────────────────────────── +# ─── ConfigMap — core ArgoCD settings ─────────────────────────────────────────── configs: params: - # Matches --insecure above — tells the server not to handle TLS server.insecure: "true" cm: - # Gitea as the source repo — HTTPS with token auth (set in secret below) - # SSH alternative is in the repositories section if preferred url: https://argocd.local.mk-labs.cloud - # Authentik OIDC SSO - # Uncomment once Authentik is configured with an ArgoCD OIDC provider - # oidc.config: | - # name: Authentik - # issuer: https://authentik.local.mk-labs.cloud/application/o/argocd/ - # clientID: - # clientSecret: $oidc.authentik.clientSecret - # requestedScopes: - # - openid - # - profile - # - email - # - groups + # Authentik native OIDC SSO + # Client secret pulled from 1Password via ESO → argocd-oidc-secret + oidc.config: | + name: Authentik + issuer: https://authentik.local.mk-labs.cloud/application/o/argocd/ + clientID: $oidc.authentik.clientID + clientSecret: $oidc.authentik.clientSecret + requestedScopes: + - openid + - profile + - email + - groups + groupsClaim: groups # Resource health checks — ignore progressing Cilium CRDs resource.customizations.health.cilium.io_CiliumLoadBalancerIPPool: | @@ -69,7 +67,6 @@ configs: return hs # Ignore ESO-injected default fields on ExternalSecret resources. - # ESO mutates these fields after sync causing false OutOfSync state. resource.customizations.ignoreDifferences.external-secrets.io_ExternalSecret: | jqPathExpressions: - '.spec.data[]?.remoteRef?.conversionStrategy' @@ -78,23 +75,23 @@ configs: - '.spec.dataFrom[]?.extract?.conversionStrategy' - '.spec.dataFrom[]?.extract?.decodingStrategy' - '.spec.dataFrom[]?.extract?.metadataPolicy' - - # RBAC — admin gets full access, SSO groups mapped after Authentik integration + + # RBAC — argocd-admins group from Authentik gets full access rbac: policy.default: role:readonly policy.csv: | g, argocd-admins, role:admin + g, argocd-viewers, role:readonly + + # Secret reference for OIDC credentials + # ArgoCD reads $oidc.authentik.clientID and $oidc.authentik.clientSecret + # from the argocd-secret Kubernetes secret. We patch it via the ExternalSecret. + secret: + extra: + oidc.authentik.clientID: $argocd-oidc-secret:client-id + oidc.authentik.clientSecret: $argocd-oidc-secret:client-secret # Repository credentials — Gitea SSH - # Private key is injected via ESO once external-secrets is bootstrapped. - # For initial bootstrap, create the secret manually: - # kubectl create secret generic gitea-repo \ - # --namespace argocd \ - # --from-literal=type=git \ - # --from-literal=url=git@gitea.mk-labs.cloud:rblundon/homelab.git \ - # --from-file=sshPrivateKey=/path/to/argocd_gitea_ed25519 \ - # kubectl label secret gitea-repo -n argocd \ - # argocd.argoproj.io/secret-type=repository repositories: homelab-repo: url: git@gitea.mk-labs.cloud:rblundon/homelab.git @@ -102,20 +99,20 @@ configs: type: git insecure: "false" -# ─── Redis ─────────────────────────────────────────────────────────────────── +# ─── Redis ────────────────────────────────────────────────────────────────────── redis: enabled: true -# ─── Notifications ─────────────────────────────────────────────────────────── +# ─── Notifications ────────────────────────────────────────────────────────────── # Disabled for now — wire into n8n via webhook later notifications: enabled: false -# ─── ApplicationSet controller ─────────────────────────────────────────────── +# ─── ApplicationSet controller ────────────────────────────────────────────────── applicationSet: enabled: true -# ─── Dex (built-in OIDC) ───────────────────────────────────────────────────── -# Disabled — using Authentik as the OIDC provider +# ─── Dex ──────────────────────────────────────────────────────────────────────── +# Disabled — using Authentik as the native OIDC provider dex: enabled: false