From bf7e78a57379f12358d01c1512219e840e1959bd Mon Sep 17 00:00:00 2001 From: CTO Date: Sat, 5 Sep 2026 10:01:52 +0000 Subject: [PATCH] feat(kaneo): wire SMTP submission via kaneo@basicstack.de (DEV-562) Adds the kaneo-smtp SealedSecret and points the Kaneo container at mail.basicstack.de:587 (STARTTLS) for outbound workspace invites and notifications. DISABLE_EMAIL_OTP_SIGN_IN stays true so sign-in remains OIDC-only via Pocket ID. Co-Authored-By: Paperclip --- apps/kaneo/README.md | 20 ++++++++++++++------ apps/kaneo/kaneo-deployment.yaml | 22 ++++++++++++++++++++++ apps/kaneo/kaneo-smtp-sealed.yaml | 16 ++++++++++++++++ 3 files changed, 52 insertions(+), 6 deletions(-) create mode 100644 apps/kaneo/kaneo-smtp-sealed.yaml diff --git a/apps/kaneo/README.md b/apps/kaneo/README.md index 02927cb..212ae3d 100644 --- a/apps/kaneo/README.md +++ b/apps/kaneo/README.md @@ -31,6 +31,7 @@ management — deployed on the BasicStack Kubernetes cluster. | `kaneo-db-credentials-sealed.yaml` | Postgres user password (SealedSecret). | | `kaneo-app-secrets-sealed.yaml` | `AUTH_SECRET` (Better Auth JWT secret, ≥32 chars). | | `kaneo-oidc-secret-sealed.yaml` | OIDC client id + secret from Pocket ID. | +| `kaneo-smtp-sealed.yaml` | SMTP submission credentials for `kaneo@basicstack.de` (SealedSecret). | | `kaneo-deployment.yaml` | Kaneo app deployment (pinned to `fsn1`). | | `kaneo-service.yaml` | ClusterIP service on port 80 → container 5173. | | `kaneo-ingress.yaml` | Traefik ingress + `letsencrypt-prod` cert. | @@ -45,9 +46,16 @@ management — deployed on the BasicStack Kubernetes cluster. ## SMTP -SMTP env vars are intentionally not wired. Once a -`kaneo@basicstack.de` mailbox exists in Stalwart, add -`SMTP_HOST/SMTP_PORT/SMTP_USER/SMTP_PASSWORD/SMTP_FROM` via -`kaneo-smtp-sealed.yaml` and reference them from the deployment. Set -`DISABLE_EMAIL_OTP_SIGN_IN=true` so users continue to sign in via SSO -rather than email codes. +Outbound SMTP is wired to the Stalwart submission relay at +`mail.basicstack.de:587` (STARTTLS) using the `kaneo@basicstack.de` +mailbox. Credentials live in the `kaneo-smtp` SealedSecret +(`kaneo-smtp-sealed.yaml`) with keys `smtp-user` and `smtp-password`. + +SMTP is used only for workspace invites and notifications; +`DISABLE_EMAIL_OTP_SIGN_IN=true` remains set so users still sign in via +Pocket ID SSO, not email codes. + +To rotate the mailbox password: update it in Stalwart, re-seal +`kaneo-smtp` with the new value, commit, and let Argo apply. The +existing pod picks up the new secret on next restart +(`kubectl -n kaneo rollout restart deploy/kaneo`). diff --git a/apps/kaneo/kaneo-deployment.yaml b/apps/kaneo/kaneo-deployment.yaml index b8932bb..fda2be1 100644 --- a/apps/kaneo/kaneo-deployment.yaml +++ b/apps/kaneo/kaneo-deployment.yaml @@ -112,6 +112,28 @@ spec: value: openid,profile,email,groups - name: CUSTOM_AUTH_PKCE value: "true" + # SMTP: outbound only, used for workspace invites / notifications. + # Sign-in still requires OIDC (DISABLE_EMAIL_OTP_SIGN_IN=true above). + - name: SMTP_HOST + value: mail.basicstack.de + - name: SMTP_PORT + value: "587" + - name: SMTP_SECURE + value: "false" + - name: SMTP_REQUIRE_TLS + value: "true" + - name: SMTP_USER + valueFrom: + secretKeyRef: + name: kaneo-smtp + key: smtp-user + - name: SMTP_PASSWORD + valueFrom: + secretKeyRef: + name: kaneo-smtp + key: smtp-password + - name: SMTP_FROM + value: "Kaneo " resources: requests: cpu: 100m diff --git a/apps/kaneo/kaneo-smtp-sealed.yaml b/apps/kaneo/kaneo-smtp-sealed.yaml new file mode 100644 index 0000000..925407b --- /dev/null +++ b/apps/kaneo/kaneo-smtp-sealed.yaml @@ -0,0 +1,16 @@ +apiVersion: bitnami.com/v1alpha1 +kind: SealedSecret +metadata: + creationTimestamp: null + name: kaneo-smtp + namespace: kaneo +spec: + encryptedData: + smtp-password: AgByMIhrSeQbPJezoqPf4jtTCx/b/R+TGZPHjjvUcdZJimgZY8XO72BA2nI/419UWqY3rBmWyquYMnEFJT0/48Rn0Nk4aFxBwBIxVuiG9y1+f5yXIhT2JuOqGoBnImYezCCtYOcgn4Byo6Twldce1ElRCqwH6grsVOLKtogZvLJC0sz6EWbqPfLrDuGyOFz2wg5P3Cjmy8W9ZgcTDTpVI4JxZh2JKbIJpq4kGDQD0miW8Av0BOmSi75uvT2PvaV/uinJ72VJFLP/GTHWjf/9kpOiIC2TL4B+Kk0HtMeWSzNF79itsD53ow7bya/bq//zUiwdaIeSaAcSJL8XqL9q38LIEL0Vr9ccXN9xsPZttLw836NDeLsryE+RhF3pIK2vEs76YIeO03AEnXNjEYOcwy7ePGYh6Y/Uf/B75QNzbzrq8H4B5lKFVmQgTBLJnvxTzOc6Sd/Yssgl1wJw90jgw2HYcLHXt/eQrB4cGKWSwrh2x6fnU79UpSGatdTqIyP2Q8vbgKmxqqmg6NDzjgeatT6ADKOqJKAjnXfrr8Bm3NjvAVWOGWuIfWdS0wHiEOhAoUNNAQ+bD7f/SbJE24q8W6juhzTmRLuU1BM2K51YPHA3BqyEpzygaboSi/bgHVOuoIAEAt7jAM6mbW5RQBwiNglF/C2Oem8J3LOdDlndJoSMaWKm5p1lKc3M59jr47jaDXm9HKM4ypC58cqty3varqxBwwdZHirZ6No0Ar4Sd78I4jo4kXk9zu33UjCcR/X2NX1abIYZ8eNoUga+I9AOkpM= + smtp-user: AgAq1mT9fzt9/VHmcbn0Yzr/8HWadEBe1XjJOTonao7Tdc3EO1PvCgEE9nBkrqOK5x2uDP1jZuP98XxJXr6mHuCnEOn8SHMN93TqK5rLhsKir1ImdNWKC+ruVI3TPQfTkeEz5m3u0DjHWSymva7BjmTIIW5gE4SDt/7WOFrsWbX1fLqQKfuB/k1qIBd+rFL7rVSe3XnRzxxwwrIbYfczSCknMbOot65FRcR+pC6ox7hOYC7pMIU76WMrVYx0cmDfAZAidcOQP9+K/H4LY0vkwPnaNk7+Is5gJifWR37lTnCkjRknMWB+yyDZF3BkmmdHNvXE6OlMcBF8l/jrO7S0rTtkCDaXllpRt1tWoSY2Kyr2DTaLt9QQvd1v8Rz2mw1qeDZg0mO/BswPF10SEKwjD3RlGFkA6mK9hZE5G+eDpgMH9u5HEKftI6jD/wdzElY+GdEFhlmj/ATZuNk+oC+eVnHGHUnY39lQYX+7PEtOujsKAjsuCPBaMDMkTP+f+LOUguuaRaanpLctmRAnT5BK19dmNuJtZPZAPgzCLu44884BH1qpKpVXkaUZSUbYA1RpKflcf1+uWJaqp7oBOZLSVoVSLiVG8ypGv7IPeTiILQcWQK27z6H0VxiAZ0S8yzNcCmeTWg8/wUGVzk0VJ9imPIShpiq515X6GuU1v1LsMiuJtFfL3EpNdDln04dLFWVb0ghIdt4Hn4U3IpJRIcP+XEEpv4+6 + template: + metadata: + creationTimestamp: null + name: kaneo-smtp + namespace: kaneo +---