From 68107ba962fe673ec58c23022da0be7219c30111 Mon Sep 17 00:00:00 2001 From: Story Crater Bot <19826264+Riotpiaole@users.noreply.github.com> Date: Thu, 23 Jul 2026 10:05:37 -0700 Subject: [PATCH] fix(authentik): use 'app' database credentials from CNPG (GitOps) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GITOPS FIX: Permanent solution for database credentials CHANGES: 1. authentik-values.yaml: - postgresql.user: authentik → app - env vars reference ddb-cluster-app secret (via secretKeyRef) - Both server + worker containers updated 2. sync-db-credentials-job.yaml (PostSync): - Copies ddb-cluster-app from ddb → iam namespace - Allows secretKeyRef to work (no cross-namespace support) - Runs after every iam-jobs sync 3. kustomization.yaml: - Added sync-db-credentials-job to resources REPLACES: - Manual kubectl patch of authentik-secrets - SOPS-encrypted per-app credentials - Complex permission grants BENEFITS: ✅ ArgoCD won't revert changes (in git) ✅ Follows CNPG simple pattern (app user) ✅ Single source of truth (ddb-cluster-app) ✅ Auto-syncs on every deploy Deployed by: iam-jobs Application (wave 3) --- k8s/security/iam/authentik-values.yaml | 43 +++++++++++-- k8s/security/iam/kustomization.yaml | 1 + k8s/security/iam/sync-db-credentials-job.yaml | 60 +++++++++++++++++++ 3 files changed, 99 insertions(+), 5 deletions(-) create mode 100644 k8s/security/iam/sync-db-credentials-job.yaml diff --git a/k8s/security/iam/authentik-values.yaml b/k8s/security/iam/authentik-values.yaml index 146d82a..e20a816 100644 --- a/k8s/security/iam/authentik-values.yaml +++ b/k8s/security/iam/authentik-values.yaml @@ -23,13 +23,14 @@ authentik: enabled: false # do not phone home to Sentry # PostgreSQL connection — points at CloudNativePG cluster in ddb namespace. - # password is injected via helmfile --set at deploy time. + # Uses 'app' bootstrap user (CNPG simple pattern, same as Forgejo). + # Credentials injected from ddb-cluster-app secret via env vars below. postgresql: host: ddb-cluster-rw.ddb.svc.cluster.local port: 5432 name: authentik - user: authentik - password: "" # injected via helmfile --set authentik.postgresql.password + user: app # All apps use shared 'app' user (CNPG design pattern) + password: "" # overridden by AUTHENTIK_POSTGRESQL__PASSWORD env var # Redis connection — bundled subchart, standalone mode (no sentinel/cluster). redis: @@ -123,7 +124,23 @@ server: volumes: *caVolumes volumeMounts: *caVolumeMounts initContainers: *caInitContainers - env: *caEnv + env: + # Merge CA trust env vars + - name: REQUESTS_CA_BUNDLE + value: /merged/ca-bundle.crt + - name: SSL_CERT_FILE + value: /merged/ca-bundle.crt + # Override database credentials to use 'app' from ddb-cluster-app + - name: AUTHENTIK_POSTGRESQL__USER + valueFrom: + secretKeyRef: + name: ddb-cluster-app + key: username + - name: AUTHENTIK_POSTGRESQL__PASSWORD + valueFrom: + secretKeyRef: + name: ddb-cluster-app + key: password podAnnotations: configmap.reloader.stakater.com/reload: "homelab-ca" homelab.io/restart-at: "2026-06-21T13-40" @@ -178,7 +195,23 @@ worker: volumes: *caVolumes volumeMounts: *caVolumeMounts initContainers: *caInitContainers - env: *caEnv + env: + # Merge CA trust env vars + - name: REQUESTS_CA_BUNDLE + value: /merged/ca-bundle.crt + - name: SSL_CERT_FILE + value: /merged/ca-bundle.crt + # Override database credentials to use 'app' from ddb-cluster-app + - name: AUTHENTIK_POSTGRESQL__USER + valueFrom: + secretKeyRef: + name: ddb-cluster-app + key: username + - name: AUTHENTIK_POSTGRESQL__PASSWORD + valueFrom: + secretKeyRef: + name: ddb-cluster-app + key: password podAnnotations: configmap.reloader.stakater.com/reload: "homelab-ca" homelab.io/restart-at: "2026-06-21T13-40" diff --git a/k8s/security/iam/kustomization.yaml b/k8s/security/iam/kustomization.yaml index 57f060c..671a4ee 100644 --- a/k8s/security/iam/kustomization.yaml +++ b/k8s/security/iam/kustomization.yaml @@ -15,6 +15,7 @@ resources: - key-rotation-cronjob.yaml - authentik-provision-job.yaml - rbac-dashboard-rolebinding.yaml + - sync-db-credentials-job.yaml # Provisioning/verification python lives in scripts/*.py (real files, linted + # diff-friendly) and is generated into ConfigMaps here rather than embedded in diff --git a/k8s/security/iam/sync-db-credentials-job.yaml b/k8s/security/iam/sync-db-credentials-job.yaml new file mode 100644 index 0000000..448078e --- /dev/null +++ b/k8s/security/iam/sync-db-credentials-job.yaml @@ -0,0 +1,60 @@ +# PostSync Job to copy ddb-cluster-app credentials to iam namespace +# Allows authentik to reference 'app' user credentials locally +apiVersion: v1 +kind: ServiceAccount +metadata: + name: sync-db-credentials + namespace: iam +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: secret-copier +rules: + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "create", "update", "patch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: sync-db-credentials +subjects: + - kind: ServiceAccount + name: sync-db-credentials + namespace: iam +roleRef: + kind: ClusterRole + name: secret-copier + apiGroup: rbac.authorization.k8s.io +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: sync-db-credentials + namespace: iam + annotations: + argocd.argoproj.io/hook: PostSync + argocd.argoproj.io/hook-delete-policy: BeforeHookCreation +spec: + backoffLimit: 3 + template: + spec: + serviceAccountName: sync-db-credentials + restartPolicy: Never + containers: + - name: copy-secret + image: alpine/k8s:1.30.3 + command: + - /bin/sh + - -c + - | + set -e + echo "Copying ddb-cluster-app secret from ddb to iam namespace..." + + # Get secret from ddb namespace + kubectl get secret ddb-cluster-app -n ddb -o json | \ + jq 'del(.metadata.namespace, .metadata.uid, .metadata.resourceVersion, .metadata.creationTimestamp, .metadata.ownerReferences) | .metadata.namespace="iam"' | \ + kubectl apply -f - + + echo "Secret copied successfully"