Switch Mealie OIDC to confidential client
Mealie requires OIDC_CLIENT_SECRET even though its docs say "public client with PKCE". The token exchange happens server-side in Mealie's Python backend, so the secret never reaches the browser. - Generate client secret, store in 1Password - Add to Authentik external-secret and worker env - Switch blueprint from public to confidential - Add ExternalSecret for mealie namespace - Update docs to reflect confidential client Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
7dce0abbb9
commit
b0023fef92
7 changed files with 39 additions and 4 deletions
|
|
@ -353,7 +353,7 @@ data:
|
||||||
labels:
|
labels:
|
||||||
blueprints.goauthentik.io/description: "Mealie OIDC provider and application"
|
blueprints.goauthentik.io/description: "Mealie OIDC provider and application"
|
||||||
entries:
|
entries:
|
||||||
# OAuth2 provider for Mealie (public client — Mealie uses PKCE)
|
# OAuth2 provider for Mealie (confidential — Mealie requires client_secret)
|
||||||
- model: authentik_providers_oauth2.oauth2provider
|
- model: authentik_providers_oauth2.oauth2provider
|
||||||
id: mealie-provider
|
id: mealie-provider
|
||||||
identifiers:
|
identifiers:
|
||||||
|
|
@ -362,8 +362,9 @@ data:
|
||||||
name: Mealie
|
name: Mealie
|
||||||
authorization_flow: !Find [authentik_flows.flow, [slug, default-provider-authorization-implicit-consent]]
|
authorization_flow: !Find [authentik_flows.flow, [slug, default-provider-authorization-implicit-consent]]
|
||||||
invalidation_flow: !Find [authentik_flows.flow, [slug, default-provider-invalidation-flow]]
|
invalidation_flow: !Find [authentik_flows.flow, [slug, default-provider-invalidation-flow]]
|
||||||
client_type: public
|
client_type: confidential
|
||||||
client_id: mealie
|
client_id: mealie
|
||||||
|
client_secret: !Env AUTHENTIK_MEALIE_CLIENT_SECRET
|
||||||
redirect_uris:
|
redirect_uris:
|
||||||
- matching_mode: strict
|
- matching_mode: strict
|
||||||
url: https://meals.ops.eblu.me/login
|
url: https://meals.ops.eblu.me/login
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,11 @@ spec:
|
||||||
secretKeyRef:
|
secretKeyRef:
|
||||||
name: authentik-config
|
name: authentik-config
|
||||||
key: argocd-client-secret
|
key: argocd-client-secret
|
||||||
|
- name: AUTHENTIK_MEALIE_CLIENT_SECRET
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: authentik-config
|
||||||
|
key: mealie-client-secret
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: blueprints
|
- name: blueprints
|
||||||
mountPath: /blueprints/custom
|
mountPath: /blueprints/custom
|
||||||
|
|
|
||||||
|
|
@ -57,3 +57,7 @@ spec:
|
||||||
remoteRef:
|
remoteRef:
|
||||||
key: "Authentik (blumeops)"
|
key: "Authentik (blumeops)"
|
||||||
property: argocd-client-secret
|
property: argocd-client-secret
|
||||||
|
- secretKey: mealie-client-secret
|
||||||
|
remoteRef:
|
||||||
|
key: "Authentik (blumeops)"
|
||||||
|
property: mealie-client-secret
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,11 @@ spec:
|
||||||
value: "https://authentik.ops.eblu.me/application/o/mealie/.well-known/openid-configuration"
|
value: "https://authentik.ops.eblu.me/application/o/mealie/.well-known/openid-configuration"
|
||||||
- name: OIDC_CLIENT_ID
|
- name: OIDC_CLIENT_ID
|
||||||
value: "mealie"
|
value: "mealie"
|
||||||
|
- name: OIDC_CLIENT_SECRET
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: mealie-oidc
|
||||||
|
key: client-secret
|
||||||
- name: OIDC_AUTO_REDIRECT
|
- name: OIDC_AUTO_REDIRECT
|
||||||
value: "false"
|
value: "false"
|
||||||
- name: OIDC_PROVIDER_NAME
|
- name: OIDC_PROVIDER_NAME
|
||||||
|
|
|
||||||
19
argocd/manifests/mealie/external-secret.yaml
Normal file
19
argocd/manifests/mealie/external-secret.yaml
Normal file
|
|
@ -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
|
||||||
|
|
@ -8,6 +8,7 @@ resources:
|
||||||
- service.yaml
|
- service.yaml
|
||||||
- pvc.yaml
|
- pvc.yaml
|
||||||
- ingress-tailscale.yaml
|
- ingress-tailscale.yaml
|
||||||
|
- external-secret.yaml
|
||||||
|
|
||||||
images:
|
images:
|
||||||
- name: registry.ops.eblu.me/blumeops/mealie
|
- name: registry.ops.eblu.me/blumeops/mealie
|
||||||
|
|
|
||||||
|
|
@ -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
|
- Built-in meal planning and shopping lists
|
||||||
- Recipe import from URLs
|
- Recipe import from URLs
|
||||||
- API token auth for automation
|
- API token auth for automation
|
||||||
- OIDC login via [[authentik]] (public client with PKCE)
|
- OIDC login via [[authentik]] (confidential client)
|
||||||
|
|
||||||
## Authentication
|
## 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
|
## Storage
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue