# ConfigMap holding the SOPS CMP plugin spec + generate script. Mounted into the # repo-server sidecar at /home/argocd/cmp-server/config/plugin.yaml (the path the # argocd-cmp-server binary reads) and /home/argocd/plugins/generate.sh. # # The plugin decrypts every k8s/**/*secrets*.enc.yaml Helm-values fragment and # emits correctly-keyed Kubernetes Secrets to stdout — no helm template inside # the plugin. Applied to the argocd namespace (bootstrap resource). apiVersion: v1 kind: ConfigMap metadata: name: sops-cmp-plugin namespace: argocd data: plugin.yaml: | apiVersion: argoproj.io/v1alpha1 kind: ConfigManagementPlugin metadata: name: sops-secrets spec: version: v1.0 generate: command: [sh, -c] args: - /home/argocd/plugins/generate.sh generate.sh: | #!/bin/sh set -eu export SOPS_AGE_KEY_FILE=/sops-age/keys.txt # CMP runs with cwd = the app source path; sops-secrets app points at repo # root, so enc files resolve from the current directory. REPO_ROOT="$(pwd)" emit_secret() { # $1 ns $2 name then key=jqpath pairs read from decrypted $ENC ns="$1"; name="$2"; shift 2 printf 'apiVersion: v1\nkind: Secret\nmetadata:\n name: %s\n namespace: %s\ntype: Opaque\ndata:\n' "$name" "$ns" for kv in "$@"; do k="${kv%%=*}"; path="${kv#*=}" val="$(echo "$DEC" | yq -r "$path")" printf ' %s: %s\n' "$k" "$(printf '%s' "$val" | base64 -w0)" done printf -- '---\n' } # ── authentik (iam) ──────────────────────────────────────────────── # Separate secret (authentik-secrets) merged via envFrom AFTER the chart's # own `authentik` config secret — avoids two ArgoCD apps owning `authentik`. DEC="$(sops -d "$REPO_ROOT/k8s/security/iam/authentik-secrets.enc.yaml")" emit_secret iam authentik-secrets \ AUTHENTIK_SECRET_KEY=.authentik.secret_key \ AUTHENTIK_BOOTSTRAP_PASSWORD=.authentik.bootstrap_password \ AUTHENTIK_BOOTSTRAP_TOKEN=.authentik.bootstrap_token \ AUTHENTIK_POSTGRESQL__PASSWORD=.authentik.postgresql_password # ── loki S3 (logging) ────────────────────────────────────────────── DEC="$(sops -d "$REPO_ROOT/k8s/platform/logging/loki-secrets.enc.yaml")" emit_secret logging loki-s3-creds \ access_key_id=.loki.storage.s3.accessKeyId \ secret_access_key=.loki.storage.s3.secretAccessKey # ── grafana (logging) ────────────────────────────────────────────── DEC="$(sops -d "$REPO_ROOT/k8s/platform/logging/grafana-secrets.enc.yaml")" # grafana chart's admin.existingSecret needs BOTH admin-user and admin-password. printf 'apiVersion: v1\nkind: Secret\nmetadata:\n name: grafana-admin\n namespace: logging\ntype: Opaque\ndata:\n admin-user: %s\n admin-password: %s\n---\n' \ "$(printf 'admin' | base64 -w0)" \ "$(echo "$DEC" | yq -r '.adminPassword' | base64 -w0)" emit_secret logging grafana-oidc \ GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET=.env.GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET