Repository navigation
Email 7/7 (Ops B): Supabase Auth magic links through Resend SMTP #425
Copy link
Copy link
Closed
Labels
enhancementNew feature or requestNew feature or request
Description
Part of #418. Read the parent first. Its Supabase Auth email section explains why. Step 7 of 7. No code.
Goal
Send sign-in mail (magic links) through Resend's SMTP relay. Supabase Auth sends these itself, from its own SMTP settings, so .env does not control them.
Owner and gate
- Owner: maintainer. It needs the Supabase dashboard.
- Gate:
- Email 6/7 (Ops A): production product mail cutover to Resend #424 (Ops A) exit signals have held for 7 days.
- D3 is ruled on Tracking: move email to Resend behind a pluggable provider #418.
- Email 2/7 (Ops 0): Resend teams, domains, records and staging credentials #420 (Ops 0) step 9 proved that the
auth-smtpkey works over SMTP. - CAPTCHA (for example Turnstile) is on for Supabase Auth in production.
- The privacy page names Resend (Email 6/7 (Ops A): production product mail cutover to Resend #424 step 0).
- Run this on a quiet day. Email links are the only sign-in besides Google.
Steps
- Record the current settings. In Authentication > Emails > SMTP Settings, note the host, port, user and sender. In Authentication > Rate Limits, note the email limit. Post them here, without the password.
- Get the current relay password from the old provider's own console, not from the Supabase dashboard. The dashboard may not show a saved password again.
- Keep it in your password manager until this issue closes.
- Send yourself a magic link on the old settings. Confirm it arrives.
- Switch the SMTP settings:
- host
smtp.resend.com - port
465 - user
resend - password: the
auth-smtpsend-only key from Email 2/7 (Ops 0): Resend teams, domains, records and staging credentials #420 (Ops 0) - sender: an address on the D2 auth domain,
no-reply@auth.docs.plus
- host
- Set Rate Limits to the D3 value at once. Saving custom SMTP settings resets the auth email limit to 30 per hour.
- In Authentication > Providers > Email, check that the email OTP expiry is 3600 s or less.
- Send magic links to one Gmail address and one Outlook address.
- Confirm both arrive and both links sign in.
- Confirm both message ids appear in the Resend log of the auth team.
- In Resend, confirm that tracking is still off on the auth domain. A rewritten magic link fails.
Rollback
- Restore the step 1 values, password included.
- Set Rate Limits back to the step 1 value. The save resets it again.
- Send a magic link and confirm it arrives.
- Post what happened here.
Acceptance
- Both magic links arrived and signed in.
- Both message ids are in the Resend log.
- Rate Limits shows the D3 value.
- CAPTCHA is on, and OTP expiry is 3600 s or less.
Exit evidence
Post as a comment here:
- The step 1 values, without the password.
- Both Resend message ids.
- A screenshot of the Rate Limits page.
- Mask your own address in anything you post.
After this issue
When this closes, tick it in Sequence on #418. The closure checks in Done means can then run.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request
Activity
[-]Email 7/7 (Ops B): send Supabase Auth magic links through Resend SMTP[/-][+]Email 7/7 (Ops B): Supabase Auth magic links through Resend SMTP[/+]docs(webapp): name Resend as the email provider on /privacy
HMarzban commentedon Oct 12, 2026
Switched, 2026-10-12
The maintainer switched Supabase Auth to the Resend SMTP relay through Resend's Supabase integration. Domain
mail.docs.plus, per the 2026-10-09 D2 ruling on #418.Step 1, the old state. Custom SMTP was off. Supabase's built-in sender handled sign-in mail, and the auth log shows the email limit was
2/1h. So email sign-in on prod could send only 2 mails an hour before this change. The rollback is: turn custom SMTP off.Settings now (no secret shown):
docs.plus <no-reply@mail.docs.plus>smtp.resend.com/465/resend2/1h→25→100at 09:40:22Z.mail.docs.plusTest 1 (Yahoo), passed with a note.
POST /otpat 09:48:55Z returned 200.GET /verifyat 09:50:40Z returned 303, and the auth log recordsuser_signedup. The link was not rewritten and it signed in.docs.plus, but in Yahoo's Junk folder. It used the default Supabase "Confirm Your Signup" template.Still open:
/privacynow names Resend for sign-in mail:ea1269f74(not pushed yet).docs(webapp): name Resend as the sender of sign-in mail on /privacy
feat(hocuspocus): add a branded confirm-signup template and state the…
docs(webapp): date the legal pages 12 October 2026 and log the privac…
fix(hocuspocus): name the reader in the sign-in mail footers and drop…
docs(hocuspocus): log the sign-in footer change
docs(webapp): state the Resend sign-in sender once on /privacy
fix(hocuspocus): make the confirm-signup notice name who can sign in
docs(hocuspocus): forbid supabase config push against production
docs(hocuspocus): give exact values in the sign-in mail setup steps
HMarzban commentedon Oct 12, 2026
Closing, 2026-10-12
Maintainer ruling, 2026-10-12: no CAPTCHA for now. The current limits are enough for today's traffic: one mail per person every 60 s, 100 mails an hour for the project, and Supabase's per-IP sign-in limit. Turning CAPTCHA on today would break email sign-in, because
apps/webapp/src/components/auth/SignInForm.tsxsends nocaptchaToken. Adding Turnstile is a code change for a later issue, before a launch push (D3 on #418).Acceptance:
2/1h→25→100at 09:40:22Z).Also done:
{{ .Email }}, and carry no fixed year./privacynames Resend for sign-in mail, andLEGAL_UPDATEDis 12 October 2026.docs/self-hosting/configuration.mdhas a "Sign-in mail (Supabase Auth)" section.