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.
This commit was merged in pull request #74.
This commit is contained in:
2026-10-27 12:14:28 -07:00
parent a525a52580
commit 863c11d75f
3 changed files with 40 additions and 3 deletions
+11 -3
View File
@@ -28,9 +28,17 @@ spec:
value: "true" value: "true"
- name: ENABLE_SCALAR_UI - name: ENABLE_SCALAR_UI
value: "true" value: "true"
# GOTIFY_URLS / GOTIFY_CLIENT_TOKENS / SECNTFY_TOKENS intentionally # The bridge authenticates with a Gotify client token, not with
# left unset — not required when Gotify is reachable via public domain # ZITADEL. Gotify has no way to accept a forwarded identity, so the
# (gotify.riotpiao.com). iGotify iOS app registers itself at runtime. # 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: volumeMounts:
- name: data - name: data
mountPath: /app/data mountPath: /app/data
@@ -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
+1
View File
@@ -36,6 +36,7 @@ files:
- etcd-defrag-creds.enc.yaml - etcd-defrag-creds.enc.yaml
- zitadel-masterkey.enc.yaml - zitadel-masterkey.enc.yaml
- smtp-gotify-secrets.enc.yaml - smtp-gotify-secrets.enc.yaml
- igotify-client-token.enc.yaml
# Login UI RSA keypair, adopted from the chart-generated Secret so ArgoCD # 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, # owns it. Without this, the chart re-generates the keypair on every render,
# which changes checksum/secret-login-service-key and leaves both Zitadel # which changes checksum/secret-login-service-key and leaves both Zitadel