Files
home-network-k3s-impl/apps/wave-1/nextcloud-bootstrap-secret.sops.yaml
T
jakman85andClaude Opus 4.8 f163026954 feat(nextcloud,semaphore): wire native Keycloak OIDC SSO (break-glass admins retained)
Extends the SSO work to the two remaining `auth: oidc` apps still on local-admin
logins, each as a native confidential client of the Keycloak `homelab` realm with
its local admin kept as break-glass (docs/15 availability caveat; R-IDP-02/06).

Realm (source of truth): add the `nextcloud` and `semaphore` confidential clients
to platform/keycloak/keycloak-realm-import.yaml (modeled on grafana/gitea) + their
NEXTCLOUD_CLIENT_SECRET / SEMAPHORE_CLIENT_SECRET placeholders. As before, a
KeycloakRealmImport no-ops on an already-existing realm, so both live clients were
ALSO created via kcadm (nextcloud e95049ed-ca10-4085-97d9-4bbef495fe61, semaphore
1835bfe9-b125-4026-8f69-33557519cf4a); the YAML keeps git authoritative.

Secrets (SOPS/age): add nextcloud-client-secret + semaphore-client-secret to
keycloak-realm-clients.sops.yaml (keycloak ns). Mirror the nextcloud secret as
oidc-client-secret into nextcloud-bootstrap (nextcloud ns). For semaphore, the
whole SEMAPHORE_OIDC_PROVIDERS JSON (which embeds the client secret) is held
encrypted as oidc-providers-json in semaphore-bootstrap (semaphore ns). All values
verified == the live clients; existing keys untouched; no plaintext in git.

App config (catalog source + re-render):
- nextcloud: add NEXTCLOUD_OIDC_CLIENT_SECRET env + an idempotent postStart hook
  that installs/enables user_oidc and runs `occ user_oidc:provider keycloak`
  (create-or-update; secret via --clientsecret-env so it never hits argv; occ as
  www-data; group provisioning on the `groups` claim). Syntax verified against the
  running user_oidc 8.11.0 on Nextcloud 31.0.14; su-to-www-data env passthrough
  verified. Missing-secret/not-installed guards prevent crashloops.
- semaphore: add SEMAPHORE_OIDC_PROVIDERS env sourced from the encrypted
  oidc-providers-json (provider_url=realm issuer/auto-discovery, redirect
  /api/auth/oidc/keycloak/redirect). Mechanism verified against semaphore v2.19.10
  source (util ConfigType oidc_providers env tag + OidcProvider struct + router
  redirect path); no kubelet service-link env collision.
apps/wave-1/{nextcloud,semaphore}.yaml re-rendered via
`render.py --no-image-automation` (diffs are env/lifecycle-only).

Verified: realm import Done=True/HasErrors=False and platform-config
Ready=True/Healthy=True (unchanged); edited realm YAML passes server dry-run; live
homelab clients now include gitea/nextcloud/semaphore; static gate (lint/l0/l1)
green. Browser SSO login for each still needs a human check.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-08-27 17:17:13 -05:00

38 lines
2.3 KiB
YAML

# Nextcloud break-glass admin + DB password (WS-APPS, Phase 6). SOPS-encrypted (age).
# admin-*: break-glass local admin (docs/15 availability caveat), created on first-boot install.
# db-password: MIRRORS nextcloud-db-app/password (ns nextcloud-db) so the app can read the DB
# credential from its own namespace. Recover: infra/devcontainer/dev.sh run sops -d apps/nextcloud-bootstrap-secret.sops.yaml
apiVersion: v1
kind: Secret
metadata:
name: nextcloud-bootstrap
namespace: nextcloud
labels:
app.kubernetes.io/name: nextcloud
type: Opaque
stringData:
admin-username: ENC[AES256_GCM,data:GVvF2Q6ymg==,iv:z0aNezBuAit4nZU0o8C5vd0V0eqFV27Ly6BX6EHA/QQ=,tag:mX17Bc5uC/HMH1d4uA3WGw==,type:str]
admin-password: ENC[AES256_GCM,data:kdP3lOEMKTOrefDNYY0m9b2JsVEWF0cwYHhpizFRvN0tA8nYv0blgvYmS16KvuUI,iv:9bbntbUewcayR3RgdeieThaFxt0UwFYHIqQoD1VSHHo=,tag:E1DHYb5TuNLl/WVFRuDCtw==,type:str]
db-password: ENC[AES256_GCM,data:Xh62RMSTEv9uS4UYhL63qclbRWFhHtUZn9/YCEbBHwkYtImYNSgKltt9d5ntUeKk,iv:ITCJE3J1eSdIzBEnWh3q2BGW3O82fqqRZ+GnWodFh78=,tag:f9MsOPPTec3dGCXweFUetQ==,type:str]
oidc-client-secret: ENC[AES256_GCM,data:5eFxTbW6MsrynLBXb8jNljcwDvG5XYFp9z6TtfVXvIaJPGBLlBc21f+0PSZ7mCaGUq9d6pyhqco3LFdJFSg77w==,iv:no50G222ahfHr1J+OYORpgj0olin26FjAE58n2Z1e9o=,tag:4qh1cqnziUIGJtEcJLVX3w==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age175l8mdpdfu7hq0aml3exs3gykarwjmuvr23sq56s3wjejnyk44wsp4mfzg
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB3bVlRZXNLZmZROHQ2czM0
OTdXQzczTmcvYWlMdDJDQkttMnJwZ21Ka2djCjZpMTN5WUxCcDhOT0Z2bnk3eXU0
aHg3N3Vvdk9Yc2xSNXJFamZLMnVsYkEKLS0tIEJGK2xyd2lKVjdXOERCMURIR2ZV
SDdoWXhVRi9DR0RzL0dlM0dtcTlFQlEKNVBukqVCZ7ZjREYAl2xK/YxuJVKEgESh
ToKuzCgydEaxW3NoKWMvZxJUM5vnGI1rPxSZdGgXDjcpI4Q4iTYmZA==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2026-08-27T22:12:32Z"
mac: ENC[AES256_GCM,data:vnwIPefz9V/s6lbkoCvnylEzaPO788eSS5grFOaBJbjT5p0yYCVVpEoh19Z1k9BnQiMKwRL2btMYGwxgN2/BdsmWE8QdpQd25ma5Fso2/EnNxTZ87aM8loA0f8JFaSvU9iyFioqGWqLxXhm7pFzJYUn/vn6cZNB/mcuPcvMI3VY=,iv:HjPfmg77anshGGv+WIOS/vsI5ctsS4JLzh4WJe/xmTk=,tag:QcMgV68/iclfAfLCWK+siQ==,type:str]
pgp: []
encrypted_regex: ^(data|stringData)$
version: 3.9.4