From 863c11d75fa74e7b4cffcb0d63549e381ceeefb0 Mon Sep 17 00:00:00 2001 From: rock Date: Tue, 27 Oct 2026 12:14:28 -0700 Subject: [PATCH] feat(igotify): wire the assist bridge with a Gotify client token The bridge runs server-side, so it cannot run a browser flow and ZITADEL has no part in it. Give it a Gotify client token instead: GOTIFY_URLS points at the public host, GOTIFY_CLIENT_TOKENS comes from a SOPS secret. The token belongs to user `rock`, is named igotify-assist, and has expiresAfterInactivitySeconds 0 so it never idles out. Delete the client row in Gotify to revoke it. Verified with the token: GET /client returns 200 and GET /message returns the latest message. --- k8s/apps/gotify/igotify-deployment.yaml | 14 ++++++++-- .../secrets/igotify-client-token.enc.yaml | 28 +++++++++++++++++++ k8s/argocd/secrets/secret-generator.yaml | 1 + 3 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 k8s/argocd/secrets/igotify-client-token.enc.yaml diff --git a/k8s/apps/gotify/igotify-deployment.yaml b/k8s/apps/gotify/igotify-deployment.yaml index fe611a1..4f12b25 100644 --- a/k8s/apps/gotify/igotify-deployment.yaml +++ b/k8s/apps/gotify/igotify-deployment.yaml @@ -28,9 +28,17 @@ spec: value: "true" - name: ENABLE_SCALAR_UI value: "true" - # GOTIFY_URLS / GOTIFY_CLIENT_TOKENS / SECNTFY_TOKENS intentionally - # left unset — not required when Gotify is reachable via public domain - # (gotify.riotpiao.com). iGotify iOS app registers itself at runtime. + # The bridge authenticates with a Gotify client token, not with + # ZITADEL. Gotify has no way to accept a forwarded identity, so the + # token is the only credential that works server-side. The token + # belongs to user `rock`, never expires, and is revoked by deleting + # the client row in Gotify. + - name: GOTIFY_URLS + value: "https://gotify.riotpiao.com" + - name: GOTIFY_CLIENT_TOKENS + valueFrom: + secretKeyRef: {name: igotify-client-token, key: client-token} + # SECNTFY_TOKENS intentionally left unset: secntfy is not deployed. volumeMounts: - name: data mountPath: /app/data diff --git a/k8s/argocd/secrets/igotify-client-token.enc.yaml b/k8s/argocd/secrets/igotify-client-token.enc.yaml new file mode 100644 index 0000000..5704ba0 --- /dev/null +++ b/k8s/argocd/secrets/igotify-client-token.enc.yaml @@ -0,0 +1,28 @@ +apiVersion: v1 +kind: Secret +metadata: + name: igotify-client-token + namespace: notifications +type: Opaque +data: + client-token: ENC[AES256_GCM,data:W+InmDyZkU0i+OqQUsIaRNY/3p6zjMC19ASj/qYHTldhtGmHwj4koQX3tIxdCQV72xZKOxsc8eV3hGX3pqbW02c2/ng=,iv:wWI5AZdpxnzX61f8iTiWmxKcDFMaFM4PHFYo4DMBK4Q=,tag:CpE8Kg5V8fL7P3oAjWjSvQ==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1e5fq3hwxy78psus2nfvmtmua36g0u3suk78ephw6246l974d2utsvn0hla + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwaUlFU0xKaEs0SWcxWEEr + T0tUSmErR08zVkhuLy9VMEc3VXdmU1o3cWdrCjhuOW1yTmZPdWxDZHhMeUZtQlcz + UmVzaEMyVHZOZS9KVHdMd2pndUJwUW8KLS0tIGxYeENwVEFDdUpDTGszdGtNRHBQ + Y041WW9HdTJwUlJCUGhMN2RGZWZpUmMKiQbi/O9X3cFJgqw3tvwWcyy8QKkUuq/7 + Y+V51R/WFobEQuAZLmDKgWcPSGt51effufB/Vm9LRRqtbkbYQAIoXQ== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2026-10-27T19:14:20Z" + mac: ENC[AES256_GCM,data:Hxl7AGzMOMK0pwe6T9ZmrE6K45XhQkq4qk/7YkrVuneL1e7jc8Bmv4NlywqRkt9fPVOCMwKikeX9U3ZcsqK13xPPfm1CmAxV3CCluwK0/9589N70OQxL4qJSkO6CXyGaa0Y9wVRX4y/N3wSjW+d25+GOYUXrOxkRpVyU4GFSqAQ=,iv:0Af/MCZBEYJVI3yi7DpPX1eBKwSANXJPCpSAEE3zCq4=,tag:SS1U9TfRQR3z8KkoQ6ZuZA==,type:str] + pgp: [] + encrypted_regex: ^(data|stringData)$ + version: 3.9.3 diff --git a/k8s/argocd/secrets/secret-generator.yaml b/k8s/argocd/secrets/secret-generator.yaml index 77211d2..56ead34 100644 --- a/k8s/argocd/secrets/secret-generator.yaml +++ b/k8s/argocd/secrets/secret-generator.yaml @@ -36,6 +36,7 @@ files: - etcd-defrag-creds.enc.yaml - zitadel-masterkey.enc.yaml - smtp-gotify-secrets.enc.yaml + - igotify-client-token.enc.yaml # Login UI RSA keypair, adopted from the chart-generated Secret so ArgoCD # owns it. Without this, the chart re-generates the keypair on every render, # which changes checksum/secret-login-service-key and leaves both Zitadel