fix(mail): replace the Sweego API key with one from the correct account #273

Sammanfogat
supernaut sammanfogade 1 incheckning från fix/sweego-api-key-account in i main 2026-07-31 01:35:43 +00:00
Ägare

Replaces vault_sweego_api_key with a key issued from the correct Sweego account.

Symptom

After #272 applied, Forgejo's SMTP test mail delivered fine and the received headers showed
dkim=pass for mail.gitborg.se. But a real sign-up produced no email, and the portal logged:

[signup] setup-link email failed (status 422)

Root cause

The portal and Forgejo authenticate to Sweego by different credentials:

Path Credential Result
Forgejo vault_forgejo_mailer_* (SMTP relay) ✅ delivered, DKIM passed
Portal vault_sweego_api_key (HTTP API) ❌ HTTP 422

Only the SMTP credentials came from the right account. The previous API key belonged to a
different Sweego account — so it authenticated successfully, which is precisely why the failure
was 422 and not 401, but that account has no verified mail.gitborg.se sending domain. Sweego
accepted the request and rejected the sender.

The status code was the tell: a revoked or malformed key gives 401/403. A 422 means "I know who you
are, and you may not send this."

Effect: sign-up completed and provisioned the Kanidm account, but the credential-reset link was
never delivered — silent from the user's side, since portal email is best-effort by design so as not
to fail a sign-up that already succeeded.

Note on the dry-run

web : Create the web Sweego API key podman secret reports skipping under --check, because
podman commands do not execute in check mode. The dry-run is therefore structurally blind to this
change and shows only the consequent restart. Expected, but worth knowing: a check-mode diff cannot
confirm a secret rotation here.

Two gaps this exposes — not fixed here

  1. The failure reason was discarded. sendEmail in bitborg-web records res.status and throws
    away the response body, so the 422's explanation never reached the logs. Diagnosis required
    account knowledge rather than evidence.
  2. Nothing verifies the key's account can send from EMAIL_FROM's domain. A valid key for the
    wrong account passes every check we have — CI, the health gates, and the apply itself. This is
    the same class of defect as gitborg/gitborg-web#113: a credential and a sender that must agree,
    with nothing asserting they do.

Verification

Sign-up end-to-end after this applies, and confirm the setup-link mail arrives with dkim=pass and
d=mail.gitborg.se.

Replaces `vault_sweego_api_key` with a key issued from the **correct** Sweego account. ## Symptom After #272 applied, Forgejo's SMTP test mail delivered fine and the received headers showed `dkim=pass` for `mail.gitborg.se`. But a real sign-up produced no email, and the portal logged: ``` [signup] setup-link email failed (status 422) ``` ## Root cause The portal and Forgejo authenticate to Sweego by **different credentials**: | Path | Credential | Result | | --- | --- | --- | | Forgejo | `vault_forgejo_mailer_*` (SMTP relay) | ✅ delivered, DKIM passed | | Portal | `vault_sweego_api_key` (HTTP API) | ❌ HTTP 422 | Only the SMTP credentials came from the right account. The previous API key belonged to a **different Sweego account** — so it authenticated successfully, which is precisely why the failure was **422 and not 401**, but that account has no verified `mail.gitborg.se` sending domain. Sweego accepted the request and rejected the sender. The status code was the tell: a revoked or malformed key gives 401/403. A 422 means "I know who you are, and you may not send this." **Effect:** sign-up completed and provisioned the Kanidm account, but the credential-reset link was never delivered — silent from the user's side, since portal email is best-effort by design so as not to fail a sign-up that already succeeded. ## Note on the dry-run `web : Create the web Sweego API key podman secret` reports `skipping` under `--check`, because podman commands do not execute in check mode. The dry-run is therefore structurally blind to this change and shows only the consequent restart. Expected, but worth knowing: a check-mode diff cannot confirm a secret rotation here. ## Two gaps this exposes — not fixed here 1. **The failure reason was discarded.** `sendEmail` in bitborg-web records `res.status` and throws away the response body, so the 422's explanation never reached the logs. Diagnosis required account knowledge rather than evidence. 2. **Nothing verifies the key's account can send from `EMAIL_FROM`'s domain.** A valid key for the wrong account passes every check we have — CI, the health gates, and the apply itself. This is the same class of defect as gitborg/gitborg-web#113: a credential and a sender that must agree, with nothing asserting they do. ## Verification Sign-up end-to-end after this applies, and confirm the setup-link mail arrives with `dkim=pass` and `d=mail.gitborg.se`.
supernaut lade till 1 incheckning 2026-07-31 01:33:34 +00:00
fix(mail): replace the Sweego API key with one from the correct account
Alla kontroller lyckades
ci / ci (pull_request) Successful in 1m30s
04e0e59554
The portal's sign-up mail failed with `[signup] setup-link email failed (status
422)` while Forgejo's SMTP test mail delivered fine with DKIM passing.

The two paths use different credentials, and only the SMTP ones came from the
right place. The previous `vault_sweego_api_key` belonged to a *different*
Sweego account, so it authenticated successfully — which is why the failure was
422 and not 401 — but that account has no verified `mail.gitborg.se` sending
domain, so Sweego accepted the request and rejected the sender.

Effect: sign-up completed and provisioned the account, but the credential-reset
link was never delivered. Silent from the user's side.

Two gaps this exposes, neither fixed here:

- `sendEmail` records `res.status` and discards the response body, so the 422
  reason was unavailable — the diagnosis needed account knowledge rather than
  logs.
- Nothing verifies at deploy or boot that the API key's account can actually
  send from EMAIL_FROM's domain. A valid key for the wrong account passes every
  check we have.
supernaut sammanfogade incheckning b87fd7a577 till main 2026-07-31 01:35:43 +00:00
supernaut tog bort grenen fix/sweego-api-key-account 2026-07-31 01:35:43 +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!273
Ingen beskrivning angiven.