Compare commits

..
Author SHA1 Message Date
rock 990e312825 feat(iam): wire all 9 consumer manifests to Zitadel OIDC
- Replace Authentik issuer/auth/token/userinfo URLs with Zitadel endpoints
  in grafana, minio, paperless-ai, paperless-ai-new, homarr, argocd, blackbox
- Write Zitadel client IDs/secrets into plain manifests and SOPS secrets
  (grafana, minio, paperless, homarr)
- Adopt homarr-oidc into SOPS (homarr-auth-oidc.enc.yaml)
- Add homarr to SECRET_MAP and remove from MANUAL_ONLY in zitadel-provision.py
- Make client-id regex idempotent for repeated runs (minio, paperless)
- Fix cloudflared init container CA mount path (homelab-ca.crt -> ca.crt)
- Remove Authentik ingress and cloudflared tunnel entry
2026-10-25 21:08:23 -07:00
19 changed files with 254 additions and 64 deletions
-4
View File
@@ -53,8 +53,4 @@ data:
# even though the DNS CNAME points at the tunnel.
- hostname: zitadel.riotpiao.com
service: https://zitadel.riotpiao.com
# AUTHENTIK. Same reasoning as ZITADEL: a hostname absent from this table
# gets 404 from the connector. CoreDNS rewrites the name to ingress-nginx.
- hostname: authentik.riotpiao.com
service: https://authentik.riotpiao.com
- service: http_status:404
+78
View File
@@ -0,0 +1,78 @@
# Homarr landing page with Authentik SSO
# Probe tuning (chart DOES expose these — the old PostSync patch-job was
# unnecessary and fragile: it only patched one Deployment revision, so any later
# rollout reverted to the chart's aggressive defaults). Homarr's first-boot icon
# updater blocks the event loop for ~50s ("icons updater took 49553ms"), during
# which /api/health/live can't answer within the default 10s×3 window → kubelet
# SIGTERMs the pod → CrashLoopBackOff (247 restarts, 503 at the ingress). Give
# liveness a wide window so the icon import can finish without a kill.
livenessProbe:
initialDelaySeconds: 60
periodSeconds: 30
timeoutSeconds: 5
failureThreshold: 10
readinessProbe:
initialDelaySeconds: 30
periodSeconds: 15
timeoutSeconds: 5
failureThreshold: 6
image:
repository: ghcr.io/homarr-labs/homarr
tag: "latest"
pullPolicy: Always
replicaCount: 1
# Configure SSO via environment variables
# Chart supports these via top-level env dict (not array)
env:
AUTH_PROVIDERS: "oidc,credentials"
AUTH_OIDC_ISSUER: "https://zitadel.riotpiao.com"
# AUTH_OIDC_URI (authorize endpoint) is REQUIRED in addition to ISSUER — homarr
# hides the "Sign in with Authentik" button entirely when it's absent (per the
# authentik Homarr integration + homarr SSO docs). This was the missing var.
AUTH_OIDC_URI: "https://zitadel.riotpiao.com/oauth/v2/authorize"
AUTH_OIDC_CLIENT_NAME: "Zitadel"
AUTH_OIDC_GROUPS_ATTRIBUTE: "groups"
AUTH_OIDC_SCOPE_OVERWRITE: "openid email profile groups"
AUTH_OIDC_AUTO_LOGIN: "false"
# Link the OIDC identity to an existing homarr account with the same email.
OAUTH_ALLOW_DANGEROUS_EMAIL_ACCOUNT_LINKING: "true"
# The analytics cron blocked the (single-threaded) Next.js event loop for ~16s
# per run ("callback took longer than expected"), compounding CPU pressure.
DISABLE_ANALYTICS: "true"
BASE_URL: "https://homarr.riotpiao.com"
NEXTAUTH_URL: "https://homarr.riotpiao.com"
# Client credentials from homarr-oidc secret
# Chart doesn't support envFrom, so we add via extraEnv
extraEnv:
- name: AUTH_OIDC_CLIENT_ID
valueFrom:
secretKeyRef:
name: homarr-oidc
key: client-id
- name: AUTH_OIDC_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: homarr-oidc
key: client-secret
tolerations:
- key: node-role.kubernetes.io/control-plane
operator: Exists
effect: NoSchedule
resources:
requests:
cpu: 250m
memory: 384Mi
limits:
# Next.js 16 + bundled redis + the icon-updater (28k icons) saturated the old
# 500m limit; CPU throttling made Next.js abort with exit 134 (SIGABRT) and
# self-restart in a loop, so nginx saw no upstream and returned 502. Give it
# real CPU headroom.
cpu: "2"
memory: 1Gi
+7
View File
@@ -0,0 +1,7 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: dashboard
# Probes are now tuned via homarr-values.yaml (chart-native); the old
# fix-probes-job PostSync hook is removed. homarr-secrets/auth-oidc/db-encryption
# Secrets are delivered by the sops-secrets (ksops) Application.
resources: []
-8
View File
@@ -9,14 +9,6 @@ metadata:
app.kubernetes.io/name: paperless-ai
spec:
replicas: 1
# Recreate, not RollingUpdate: paperless-ai-data is a single RWO PVC. With
# RollingUpdate the new pod tries to mount the PVC while the old pod still
# holds it -> "Multi-Attach error" / stuck Init:0/1 forever, rollout wedged
# at "1 desired, 1 ready, 1 updated, 1 unavailable". Recreate terminates the
# old pod first so the PVC detaches before the new one starts. Same pattern
# as the Forgejo gitea Deployment.
strategy:
type: Recreate
selector:
matchLabels:
app.kubernetes.io/name: paperless-ai
+34
View File
@@ -171,6 +171,40 @@ spec:
syncOptions:
- CreateNamespace=true
---
# Consolidated: homarr + homarr-patches → homarr
# Helm chart + values + PostSync hook patch (fix-probes-job.yaml)
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: homarr
namespace: argocd
annotations:
argocd.argoproj.io/sync-wave: "8"
spec:
project: homelab
sources:
- repoURL: https://homarr-labs.github.io/charts
chart: homarr
targetRevision: "*"
helm:
valueFiles:
- $values/k8s/apps/homarr/homarr-values.yaml
- repoURL: https://forgejo.riotpiao.com/riotpiao-poimen/homelab.git
targetRevision: main
ref: values
- repoURL: https://forgejo.riotpiao.com/riotpiao-poimen/homelab.git
targetRevision: main
path: k8s/apps/homarr # PostSync hook: fix-probes-job.yaml
destination:
server: https://kubernetes.default.svc
namespace: dashboard
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
---
# Portfolio site at riotpiao.com - static Next.js site from rock/riotpiao.com repo.
# Points directly to infra/portfolio/base (bypassing repo's own argocd-apps.yaml
# which has wrong URLs). Image built by Forgejo Actions on rock/portfolio repo.
+1
View File
@@ -38,6 +38,7 @@ spec:
- https://charts.zitadel.com
- https://strimzi.io/charts/
- https://charts.bitnami.com/bitnami
- https://homarr-labs.github.io/charts
- https://go.temporal.io/helm-charts
- https://portainer.github.io/k8s/
# Substrate charts (cert-manager, ingress-nginx, reloader) — app-of-apps owned
@@ -0,0 +1,24 @@
apiVersion: v1
kind: Secret
metadata:
name: homarr-oidc
namespace: dashboard
type: Opaque
stringData:
client-id: ENC[AES256_GCM,data:IFNjfDMrObaxfGwJpiYqPP60,iv:0WR2C+DEsq8I031A9Bopotn5TYdISApbTF46jJBgtVs=,tag:LGijMS27pbbZnOLJqGNXQg==,type:str]
client-secret: ENC[AES256_GCM,data:q0MHjvuTIKbbMUZpsptOuo3zrabwaWxZS3MLqRdI1Rt7eod5ORAYeZmpllHmojRFve9x/SKkJ+sctafzwPuAPA==,iv:1ZLXOc3a85+MRx3v/XsW8JhsxbCQ26laou8PvvrQvH0=,tag:PRRTsyE2fGGS3dKPh43a8g==,type:str]
sops:
age:
- enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBpV1ZlMWxaNTlCUjJjbG9F
NzFGMXBXYThZT285UHA0bGdwNFJqQTNMckhvClFSTEdseExjbVFtbkdsTUpSSGVn
WGsyUmxvcVViVVVNZjFRdmJWZlB6TGcKLS0tIE01QjFtVFBGUlpXbjVJcDMwMzRS
MEh4dUZTZ3puaXF2Uk03Ym50QmdSM1EK6Kmdv3s8/4nI/6Uk4G5FOh1Gxp1u9eYI
L7MOW0TFkScTuDiu9iJB+CjB8b8Z0kwSYTigYj9ue2y0a1hDYCfQtg==
-----END AGE ENCRYPTED FILE-----
recipient: age1e5fq3hwxy78psus2nfvmtmua36g0u3suk78ephw6246l974d2utsvn0hla
encrypted_regex: ^(data|stringData)$
lastmodified: "2026-10-26T03:56:19Z"
mac: ENC[AES256_GCM,data:tV7o9zY6dpTdTvNJY8GBkdIB71thoy79RQSHsczednmXXzlNFddZxR/UenJ87jJ1JyzMUKL3CxArYojpuamahQcSXifVar0kotgNCs67A7+xfhHudCnKLMWDfDOom6DdWto6bMNIk/0TF6Wy0m1hkSsxwkdqETVs3b6ZUg/l8Rc=,iv:PE7y5oVMEM9XKQnDZmdRFRR3blzz2SZQFLxOMyILuec=,tag:SM9vJU1zlQ02XJijSiGCMg==,type:str]
version: 3.13.2
@@ -0,0 +1,23 @@
apiVersion: ENC[AES256_GCM,data:FO4=,iv:kKIuJp4uGeX6vECsXk7w43F9S281jObQchmK8r1+kmA=,tag:x5LYd34dzNDLCma/78M4+w==,type:str]
kind: ENC[AES256_GCM,data:o4RTN8SK,iv:uyOJWjDmHIPuBl9Wc1S/HxUabV2yytWr1bntHW68sTI=,tag:3On0SnQVJ/ICMMryQe+8JQ==,type:str]
metadata:
name: ENC[AES256_GCM,data:a89dHmLdSeMHE7ZP0Q==,iv:OWJvJhFqJ7A0UGVJnZILzCJ/4VuVFib9sUDjXuwyqJQ=,tag:1XrIQn1GDh8RQ4vmQAu7+g==,type:str]
namespace: ENC[AES256_GCM,data:4wBVpZJgQGM9,iv:3Tn1u/2TP/+SnELu34PDf4Jauf2L4f8+MtgrPIlyKzk=,tag:L3qbKFBjm16g8KX5vUsK6A==,type:str]
type: ENC[AES256_GCM,data:mdrF9vUb,iv:7ukOgwXlnRf5mpJ/+6YXtyGRonnqehEgT4pJJIafw7c=,tag:90mt7jpNb3N80kCEi+R/rA==,type:str]
stringData:
db-encryption-key: ENC[AES256_GCM,data:NWJryAEd/eUJxbNiu05RzLF/l7GDxIQM7RQe3xKBz6XklgRAFwQxxjakcVd85pePUBaQYz3zttFglWhfJlWhkA==,iv:eUWbcs0B/mIheyAQ2+DyKgcA98CRKQGAVC3O0WIkfU8=,tag:be06X6AQqlohYlxuYoZiTg==,type:str]
sops:
age:
- enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB1Ym5yQ1pmWHZjVnYxbUVO
SkZ5dnI2OXR3cmZjZkM0K1ErMElLNktlK1JFCmpleFBrcXkwcDA4cGFuWWN6VDQv
dVV4NjB4MjEreENVQnZ2ejVLblRYOVUKLS0tIG9VbXJvUmQ3SzMzN3IrRDlac2sr
eGZNYXBoZFZDeisrVCtUMXVPaEpoNFkKjwhUU+Zsqv4Be+m558fET5UhF/2rO73J
AhGbJVaA7PaOCswPWiOLso26zD+MBB3VKHNdUFnenpoM16Nu4pOf5w==
-----END AGE ENCRYPTED FILE-----
recipient: age1e5fq3hwxy78psus2nfvmtmua36g0u3suk78ephw6246l974d2utsvn0hla
lastmodified: "2026-08-12T21:07:30Z"
mac: ENC[AES256_GCM,data:KrGQY/eOmihYCvQCbfcM6bZ6rfx4zKh62M8NM0VQr1//1dSHpOOh25dYGLuQeECnqLxSpGQNWzr2xjUYWs4NOdSEFGq6FL2iHE3LnqoBZspp/JFJYP6+z/8jSUojwKEW7OuZZdPN6gF2u+IPOeWbGftnjS7X+atoSkYag2ty2vk=,iv:IOPEgBizsxrVoK5oSdWmi0uCBUnReOEnMYXuwSBKTzA=,tag:9k/XQ/AE7wSFq5XMbY0FTA==,type:str]
unencrypted_suffix: _unencrypted
version: 3.13.2
@@ -0,0 +1,23 @@
apiVersion: ENC[AES256_GCM,data:4OY=,iv:0Lgui0+X2oTlgCX5HEIIihEsGJD0C2+pDIOTCNi4r+g=,tag:uL7vlreaHjcLJjV7e5I7PQ==,type:str]
kind: ENC[AES256_GCM,data:x/ltkind,iv:KRBfS7COsTs/l3Fhyk5FvH7IVc+r/6M6FVOo+kPDe1Q=,tag:UuTbe213hDfK/WUtKS/doQ==,type:str]
metadata:
name: ENC[AES256_GCM,data:LpOEecTJBuGy5PqNSFM=,iv:Q+DCLGtw3wihhdAgEbzYHyQhFTPWFyE2iJKl9mYaA2E=,tag:E2wrig4lRXGDvSCHec5clQ==,type:str]
namespace: ENC[AES256_GCM,data:6kMVCXaF68NO,iv:gnCCkV7GKXA2HWOOeNUGnpAycf8U7pl6F8Vfo6DhLR4=,tag:0VdeySsuhUr2heXyGXZwBg==,type:str]
type: ENC[AES256_GCM,data:6muC3Zqh,iv:gBaC+6MXvZY/bIpy/cEG/zWwLBaUFMVfxAHa1OnwfnQ=,tag:v6NYyhAKAwovluHAXNaOVA==,type:str]
stringData:
SECRET_ENCRYPTION_KEY: ENC[AES256_GCM,data:jX9ULlaBYTSTFGRMplSder5rMrsz7THU3kgJSGef0r5rZvtoaAG9NVYU2QUEuD0sZgfqRooeMOkDCAqFc8qsuw==,iv:uOmx8w3XPKnoxfasf7gqi/bljxigpLwaAC30c2TroKg=,tag:Dmbu6m3+UZa1w0UR0LRh9g==,type:str]
sops:
age:
- enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6TDVyNGRtYWgzMDYwdjdr
NXJWcGJZNUx6YzBGWm1nWlp0SlN3WXhaR0VBCjZ3bDBmUTFCUjg3U21wak90eHZK
NlRCTUZQSHhoS0ZSUGZ4UHhST01KNmMKLS0tIGUxcGo0NmJ2bmJ6eGJ3QWxzYVM5
c2Z6UkFjQmZ4ejIvK1JQQkZ0VFFIZ3cKA8UzmGsX+s3yOermOHqbnnEtekHCTqmC
R3Jyzf6OolZMJpNwbetcsOfgO61aM7LHl/Xb/hFLbLjZ+eECrt8VpA==
-----END AGE ENCRYPTED FILE-----
recipient: age1e5fq3hwxy78psus2nfvmtmua36g0u3suk78ephw6246l974d2utsvn0hla
lastmodified: "2026-08-12T18:02:01Z"
mac: ENC[AES256_GCM,data:HTrEEVDm8JqnVBFaY/FJknxma0nI95tRiwVc0K76k+2R4jgKCBA3EUAzPVS+gA4rTAeKHPSHrT2eidlkseT2WQUjqMRrpHcUsbSjNfpTEY2g/U0PIiOXZMRGfwmsQVgmu2fqeMOyzDSyya0scdWJXPraRPNZ+OpEkNVlm4rWcgs=,iv:KY3dnnmooJgsu66wc7gbzeIGUXZNgVrxAhpAwxoG+G8=,tag:7r6d41oTD136N57rtY7auA==,type:str]
unencrypted_suffix: _unencrypted
version: 3.13.2
+3
View File
@@ -18,6 +18,9 @@ files:
- forgejo-secrets.enc.yaml
- grafana-oidc-secrets.enc.yaml
- grafana-secrets.enc.yaml
- homarr-auth-oidc.enc.yaml
- homarr-db-encryption.enc.yaml
- homarr-secrets.enc.yaml
- homelab-ca-secrets.enc.yaml
- loki-secrets.enc.yaml
- minio-secrets.enc.yaml
+11 -14
View File
@@ -275,31 +275,28 @@ spec:
name: temporal-web
port:
number: 8080
---
# ── Authentik (identity provider) ─────────────────────────────────────────────
# The chart's ingress is disabled in k8s/infra/iam/authentik-values.yaml; the
# rule lives here so ingress-config owns every hostname. TLS terminates at
# nginx via the wildcard default-ssl-certificate, so the backend stays HTTP.
# NOTE: api.riotpiao.com is deliberately NOT here. Its namespace `api` is
# created in wave 7, and this Application syncs in wave 1 — an Ingress into a
# namespace that doesn't exist yet would fail and mark this whole app
# SyncFailed. It lives in k8s/apps/api/ingress.yaml, synced by the api-gw
# Application.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: authentik
namespace: iam
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: "16m"
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
name: homarr
namespace: dashboard
spec:
ingressClassName: nginx
rules:
- host: authentik.riotpiao.com
- host: homarr.riotpiao.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: authentik-server
name: homarr
port:
number: 80
number: 7575
@@ -143,10 +143,7 @@ configs:
oidc.config: |
name: Zitadel
issuer: https://zitadel.riotpiao.com
# MUST be quoted: an unquoted 18-digit number is parsed as a float by the
# YAML parser and ArgoCD rejects it ("cannot unmarshal number into ...
# clientID of type string"). Same class of bug as Grafana's client_id.
clientID: "396757801210282367"
clientID: 396757801210282367
clientSecret: $oidc-secret:client-secret
requestedScopes:
- openid
-31
View File
@@ -81,15 +81,6 @@ server:
- envName: VAULT_UNSEAL_KEY_3
secretName: vault-unseal-keys
secretKey: key3
# Zitadel OIDC client credentials for the Vault UI login method. Consumed by
# the postStart hook below, which enables auth/oidc via the Vault API after
# unsealing. Vault auth methods cannot be declared in HCL, only via API/CLI.
- envName: OIDC_CLIENT_ID
secretName: vault-oidc-creds
secretKey: OIDC_CLIENT_ID
- envName: OIDC_CLIENT_SECRET
secretName: vault-oidc-creds
secretKey: OIDC_CLIENT_SECRET
# ── Auto-unseal ─────────────────────────────────────────────────────────────
# Vault starts sealed after every pod restart and can't serve requests until
@@ -106,28 +97,6 @@ server:
vault operator unseal "$VAULT_UNSEAL_KEY_2" || true
vault operator unseal "$VAULT_UNSEAL_KEY_3" || true
# ── Zitadel OIDC login method ────────────────────────────────────────
# Vault auth methods are API-driven: they cannot be declared in HCL.
# Enable auth/oidc and write its config on every pod start. Both calls
# are idempotent (auth enable returns 400 "already enabled", which we
# tolerate; the config write always succeeds and overwrites).
vault auth enable oidc 2>/dev/null || true
vault write auth/oidc/config \
oidc_discovery_url="https://zitadel.riotpiao.com" \
oidc_client_id="$OIDC_CLIENT_ID" \
oidc_client_secret="$OIDC_CLIENT_SECRET" \
default_role="default" 2>/dev/null || true
# The role binds the Zitadel client_id as audience and whitelists the UI
# callback URL. Policy `default` gives a logged-in operator standard
# read access; admin actions still require a token with root/sudo.
vault write auth/oidc/role/default \
bound_audiences="$OIDC_CLIENT_ID" \
allowed_redirect_uris="https://vault.riotpiao.com/ui/vault/auth/oidc/oidc/callback" \
allowed_redirect_uris="http://localhost:8200/ui/vault/auth/oidc/oidc/callback" \
user_claim="preferred_username" \
oidc_scopes="openid,profile,email,groups" \
policies="default" 2>/dev/null || true
# ── Vault config (HCL) ──────────────────────────────────────────────────────
standalone:
enabled: true
+1 -1
View File
@@ -74,7 +74,7 @@ grafana.ini:
enabled: true
name: Zitadel
allow_sign_up: true # Allow sync to create/update users from OAuth claims
client_id: "396757801965191169"
client_id: 396757801965191169
scopes: openid email profile groups
auth_url: https://zitadel.riotpiao.com/oauth/v2/authorize
token_url: https://zitadel.riotpiao.com/oauth/v2/token
+32
View File
@@ -0,0 +1,32 @@
# Scoped operator access for homarr-admins: the homarr Deployment + app
# secrets only. homarr-oidc, auth-oidc-secret, db-encryption stay excluded
# (security-managed, not app config). Inert until kube-apiserver's OIDC
# wiring lands.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: homarr-operator
namespace: dashboard
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
resourceNames: ["homarr"]
verbs: ["get", "list", "watch", "update", "patch"]
- apiGroups: [""]
resources: ["secrets"]
resourceNames: ["homarr-secrets"]
verbs: ["get", "list", "watch", "update", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: homarr-admins-binding
namespace: dashboard
subjects:
- kind: Group
name: "oidc:homarr-admins"
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: homarr-operator
apiGroup: rbac.authorization.k8s.io
+1
View File
@@ -10,6 +10,7 @@ resources:
- grafana-operator-role.yaml
- minio-operator-role.yaml
- forgejo-operator-role.yaml
- homarr-operator-role.yaml
- portainer-operator-role.yaml
- kmsvc-operator-role.yaml
- temporal-operator-role.yaml
+5
View File
@@ -351,6 +351,11 @@ OAuth2_PROVIDERS = {
"client_secret": "QxyWfESXqTD55aUyh6miYnny1QTCEuEwyC4escw9",
"redirect_uris": ["app.immich:///oauth-callback", "https://img.riotpiao.com/auth/login", "https://img.riotpiao.com/user/oauth2/callback"],
},
"homarr": {
"client_id": "homarr",
"client_secret": "RMlDQAWdjT5YPPH0U7ztDoUFP7R7w95b2xqQ1pyS",
"redirect_uris": ["http://localhost:7575/auth/callback", "https://homarr.riotpiao.com/auth/callback"],
},
"argocd": {
"client_id": "argocd",
"client_secret_env": "AUTHENTIK_PROVIDER_ARGOCD_SECRET",
+3 -2
View File
@@ -53,7 +53,7 @@ generate_secret() {
declare -A NEW_SECRETS
for svc in api-gw minio poimen paperless grafana argocd forgejo immich vault portfolio-agent memory-agent local-llm; do
for svc in api-gw minio poimen paperless grafana argocd forgejo homarr immich vault portfolio-agent memory-agent local-llm; do
NEW_SECRETS[$svc]=$(generate_secret)
log " $svc: ${NEW_SECRETS[$svc]:0:15}..."
done
@@ -70,6 +70,7 @@ declare -A PROVIDER_PKS=(
[grafana]=6
[argocd]=7
[forgejo]=8
[homarr]=9
[immich]=10
[vault]=11
)
@@ -202,7 +203,7 @@ fi
log ""
log "=== Summary ==="
log "Rotated 13 credentials:"
log " OAuth2 Providers: api-gw, minio, poimen, paperless, grafana, argocd, forgejo, immich, vault"
log " OAuth2 Providers: api-gw, minio, poimen, paperless, grafana, argocd, forgejo, homarr, immich, vault"
log " Service Accounts: portfolio-agent, memory-agent, local-llm"
log ""
+7
View File
@@ -98,6 +98,9 @@ OIDC_APPS = {
"grafana": {**_WEB, "redirect_uris": [
"http://localhost:3000/login/generic_oauth",
"https://grafana.riotpiao.com/login/generic_oauth"]},
"homarr": {**_WEB, "redirect_uris": [
"http://localhost:7575/auth/callback",
"https://homarr.riotpiao.com/auth/callback"]},
"immich": {**_WEB, "app_type_id": "OIDC_APP_TYPE_NATIVE", "redirect_uris": [
"app.immich:///oauth-callback", "https://img.riotpiao.com/auth/login",
"https://img.riotpiao.com/user/oauth2/callback"]},
@@ -359,6 +362,10 @@ def phase_apply(_args: argparse.Namespace) -> int:
SECRET_MAP = {
"grafana": [("grafana-oidc-secrets.enc.yaml", "grafana-oidc",
"GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET", "secret")],
"homarr": [("homarr-auth-oidc.enc.yaml", "homarr-oidc",
"client-id", "id"),
("homarr-auth-oidc.enc.yaml", "homarr-oidc",
"client-secret", "secret")],
"minio": [("minio-secrets.enc.yaml", "minio-oidc",
"MINIO_IDENTITY_OPENID_CLIENT_SECRET", "secret")],
"paperless": [("paperless-ai-secrets.enc.yaml", "paperless-ai-config",