feat(mail): derive every sender from one sending-domain variable #283

Sammanfogat
supernaut sammanfogade 1 incheckning från feat/113-single-mail-domain-source in i main 2026-07-31 12:56:35 +00:00
Ägare

Part of gitborg/gitborg-web#113 — the infra half. The portal half is gitborg/gitborg-web#117.

The duplication being removed

The sending domain was written out four times with nothing asserting they agreed:

Location Was
group_vars/all/vars.yml forgejo_mailer_from: bitborg <no-reply@mail.gitborg.se>
roles/monitoring/defaults alert_email_from: alerts@mail.gitborg.se
roles/monitoring-agent/defaults monitoring_probe_mail_from: alerts@mail.gitborg.se
bitborg-web hardcoded EMAIL_FROM constant

On the email.gitborg.se → mail.gitborg.se move, the three in this repo were updated and the portal's was not. Every portal mail was rejected by the provider while the apply reported success — a wrong-account API key then masked it further as a bare HTTP 422.

The change

mail_sending_domain in group_vars/all/vars.yml is now the single source; all three in-repo senders derive from it. A domain move is one line here.

It is also passed to the portal:

Environment=EMAIL_ALLOWED_SENDER_DOMAINS={{ mail_sending_domain }}

bitborg-web keeps its own hardcoded EMAIL_FROM — deliberately, since an env-set From could send as an unverified domain — but now validates it against this list and refuses to send, loudly, on a mismatch. The cross-repo disagreement becomes detected instead of silent. That is the actual fix for #113; deduplicating within this repo is the smaller half.

Verified behaviour-neutral

--check --diff --tags web,forgejo,monitoring-agent against production:

changed:
  web : Install bitborg-web container Quadlet unit
  web : Enable and start bitborg-web (restart on unit change or image drift)

+Environment=EMAIL_ALLOWED_SENDER_DOMAINS=mail.gitborg.se

Forgejo's app.ini shows no change, and neither does the monitoring probe script — the derived values render byte-identically to the literals they replaced. So the refactor cannot have altered a sender by accident; the only functional diff is the new environment line.

ansible-lint passes on the production profile (183 files); --syntax-check clean.

Impact on apply

A brief bitborg-web restart (sub-second, measured earlier today — the image layer is already local). No Forgejo or Kanidm restart.

Ordering with the portal PR

Either order is safe. bitborg-web treats an unset allowlist as "infra has not told us yet" and still sends, so applying this before the portal deploys — or after — cannot break mail. Only a populated list that excludes the portal's domain refuses, which is the misconfiguration we want caught.

Note

The two monitoring role defaults keep | default('mail.gitborg.se') so those roles still render standalone, outside these group_vars.

Part of gitborg/gitborg-web#113 — the infra half. The portal half is gitborg/gitborg-web#117. ## The duplication being removed The sending domain was written out **four times** with nothing asserting they agreed: | Location | Was | | --- | --- | | `group_vars/all/vars.yml` | `forgejo_mailer_from: bitborg <no-reply@mail.gitborg.se>` | | `roles/monitoring/defaults` | `alert_email_from: alerts@mail.gitborg.se` | | `roles/monitoring-agent/defaults` | `monitoring_probe_mail_from: alerts@mail.gitborg.se` | | **bitborg-web** | hardcoded `EMAIL_FROM` constant | On the `email.gitborg.se` → `mail.gitborg.se` move, the three in this repo were updated and the portal's was not. Every portal mail was rejected by the provider **while the apply reported success** — a wrong-account API key then masked it further as a bare HTTP 422. ## The change `mail_sending_domain` in `group_vars/all/vars.yml` is now the single source; all three in-repo senders derive from it. A domain move is one line here. It is also passed to the portal: ``` Environment=EMAIL_ALLOWED_SENDER_DOMAINS={{ mail_sending_domain }} ``` bitborg-web keeps its own hardcoded `EMAIL_FROM` — deliberately, since an env-set From could send as an *unverified* domain — but now validates it against this list and refuses to send, loudly, on a mismatch. The cross-repo disagreement becomes **detected** instead of silent. That is the actual fix for #113; deduplicating within this repo is the smaller half. ## Verified behaviour-neutral `--check --diff --tags web,forgejo,monitoring-agent` against production: ``` changed: web : Install bitborg-web container Quadlet unit web : Enable and start bitborg-web (restart on unit change or image drift) +Environment=EMAIL_ALLOWED_SENDER_DOMAINS=mail.gitborg.se ``` **Forgejo's `app.ini` shows no change, and neither does the monitoring probe script** — the derived values render byte-identically to the literals they replaced. So the refactor cannot have altered a sender by accident; the only functional diff is the new environment line. `ansible-lint` passes on the production profile (183 files); `--syntax-check` clean. ## Impact on apply A brief `bitborg-web` restart (sub-second, measured earlier today — the image layer is already local). No Forgejo or Kanidm restart. ## Ordering with the portal PR Either order is safe. bitborg-web treats an **unset** allowlist as "infra has not told us yet" and still sends, so applying this before the portal deploys — or after — cannot break mail. Only a populated list that excludes the portal's domain refuses, which is the misconfiguration we want caught. ## Note The two monitoring role defaults keep `| default('mail.gitborg.se')` so those roles still render standalone, outside these group_vars.
supernaut lade till 1 incheckning 2026-07-31 12:19:34 +00:00
feat(mail): derive every sender from one sending-domain variable
Alla kontroller lyckades
ci / ci (pull_request) Successful in 1m31s
5f640e94ed
Part of gitborg/gitborg-web#113 — the infra half.

The sending domain was written out four times: forgejo_mailer_from here, both
monitoring roles' alerts@ addresses, and a hardcoded EMAIL_FROM constant in
gitborg-web. Nothing asserted they agreed. On the email.gitborg.se →
mail.gitborg.se move the three in this repo were updated and the portal's was not,
so every portal mail was rejected by the provider while the apply reported success.

Introduces mail_sending_domain in group_vars/all/vars.yml and derives all three
in-repo senders from it, so a domain move is a one-line change here.

Also passes it to the portal as EMAIL_ALLOWED_SENDER_DOMAINS. gitborg-web keeps its
own hardcoded EMAIL_FROM deliberately — an env-set From could send as an unverified
domain — but now checks it against this list and refuses to send, loudly, on a
mismatch. The disagreement becomes detected rather than silent.

The two monitoring role defaults keep a `| default('mail.gitborg.se')` so those
roles still render if used without these group_vars.

Verified behaviour-neutral: a --check --diff over web, forgejo and monitoring-agent
shows NO change to Forgejo's app.ini and none to the monitoring probe script — the
derived values render byte-identically to the literals they replaced. The only diff
is the new Environment line, which restarts gitborg-web.

Verify a new domain in Sweego (DKIM CNAME at sweego1._domainkey.<domain>) before
changing mail_sending_domain.
supernaut sammanfogade incheckning c4ea4fcbf1 till main 2026-07-31 12:56:35 +00:00
supernaut tog bort grenen feat/113-single-mail-domain-source 2026-07-31 12:56:35 +00:00
Logga in för att delta i denna konversation.
Inga granskare
Ingen milstolpe
Inget projekt
Inga tilldelade
1 deltagare
Notiser
Förfallodatum
Förfallodatumet är ogiltigt eller utanför gränserna. Använd formatet "åååå-mm-dd".

Inget förfallodatum satt.

Beroenden

Inga beroenden satta

Referens
bitborg/bitborg-infra!283
Ingen beskrivning angiven.