diff --git a/argocd/manifests/authentik/configmap-blueprint.yaml b/argocd/manifests/authentik/configmap-blueprint.yaml index 285bb82..cc3ff43 100644 --- a/argocd/manifests/authentik/configmap-blueprint.yaml +++ b/argocd/manifests/authentik/configmap-blueprint.yaml @@ -353,7 +353,7 @@ data: labels: blueprints.goauthentik.io/description: "Mealie OIDC provider and application" entries: - # OAuth2 provider for Mealie (public client — Mealie uses PKCE) + # OAuth2 provider for Mealie (confidential — Mealie requires client_secret) - model: authentik_providers_oauth2.oauth2provider id: mealie-provider identifiers: @@ -362,8 +362,9 @@ data: name: Mealie authorization_flow: !Find [authentik_flows.flow, [slug, default-provider-authorization-implicit-consent]] invalidation_flow: !Find [authentik_flows.flow, [slug, default-provider-invalidation-flow]] - client_type: public + client_type: confidential client_id: mealie + client_secret: !Env AUTHENTIK_MEALIE_CLIENT_SECRET redirect_uris: - matching_mode: strict url: https://meals.ops.eblu.me/login diff --git a/argocd/manifests/authentik/deployment-worker.yaml b/argocd/manifests/authentik/deployment-worker.yaml index 2b341bf..3d4fb0c 100644 --- a/argocd/manifests/authentik/deployment-worker.yaml +++ b/argocd/manifests/authentik/deployment-worker.yaml @@ -78,6 +78,11 @@ spec: secretKeyRef: name: authentik-config key: argocd-client-secret + - name: AUTHENTIK_MEALIE_CLIENT_SECRET + valueFrom: + secretKeyRef: + name: authentik-config + key: mealie-client-secret volumeMounts: - name: blueprints mountPath: /blueprints/custom diff --git a/argocd/manifests/authentik/external-secret.yaml b/argocd/manifests/authentik/external-secret.yaml index 495eda8..fb22f2b 100644 --- a/argocd/manifests/authentik/external-secret.yaml +++ b/argocd/manifests/authentik/external-secret.yaml @@ -57,3 +57,7 @@ spec: remoteRef: key: "Authentik (blumeops)" property: argocd-client-secret + - secretKey: mealie-client-secret + remoteRef: + key: "Authentik (blumeops)" + property: mealie-client-secret diff --git a/argocd/manifests/mealie/deployment.yaml b/argocd/manifests/mealie/deployment.yaml index d88d632..4eab901 100644 --- a/argocd/manifests/mealie/deployment.yaml +++ b/argocd/manifests/mealie/deployment.yaml @@ -36,6 +36,11 @@ spec: value: "https://authentik.ops.eblu.me/application/o/mealie/.well-known/openid-configuration" - name: OIDC_CLIENT_ID value: "mealie" + - name: OIDC_CLIENT_SECRET + valueFrom: + secretKeyRef: + name: mealie-oidc + key: client-secret - name: OIDC_AUTO_REDIRECT value: "false" - name: OIDC_PROVIDER_NAME diff --git a/argocd/manifests/mealie/external-secret.yaml b/argocd/manifests/mealie/external-secret.yaml new file mode 100644 index 0000000..6a77c5d --- /dev/null +++ b/argocd/manifests/mealie/external-secret.yaml @@ -0,0 +1,19 @@ +--- +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: mealie-oidc + namespace: mealie +spec: + refreshInterval: 1h + secretStoreRef: + kind: ClusterSecretStore + name: onepassword-blumeops + target: + name: mealie-oidc + creationPolicy: Owner + data: + - secretKey: client-secret + remoteRef: + key: "Authentik (blumeops)" + property: mealie-client-secret diff --git a/argocd/manifests/mealie/kustomization.yaml b/argocd/manifests/mealie/kustomization.yaml index 4046658..0d1ee04 100644 --- a/argocd/manifests/mealie/kustomization.yaml +++ b/argocd/manifests/mealie/kustomization.yaml @@ -8,6 +8,7 @@ resources: - service.yaml - pvc.yaml - ingress-tailscale.yaml + - external-secret.yaml images: - name: registry.ops.eblu.me/blumeops/mealie diff --git a/docs/reference/services/mealie.md b/docs/reference/services/mealie.md index 4081291..f309a5e 100644 --- a/docs/reference/services/mealie.md +++ b/docs/reference/services/mealie.md @@ -30,11 +30,11 @@ Self-hosted recipe manager with a REST API. Part of the meal planning pipeline: - Built-in meal planning and shopping lists - Recipe import from URLs - API token auth for automation -- OIDC login via [[authentik]] (public client with PKCE) +- OIDC login via [[authentik]] (confidential client) ## Authentication -OIDC via [[authentik]] using a public client with PKCE (no client secret needed). All Authentik users can log in; members of the `admins` group get Mealie admin privileges via `OIDC_ADMIN_GROUP`. +OIDC via [[authentik]] using a confidential client. Client secret stored in 1Password (`Authentik (blumeops)` / `mealie-client-secret`) and delivered via ExternalSecret. All Authentik users can log in; members of the `admins` group get Mealie admin privileges via `OIDC_ADMIN_GROUP`. ## Storage