Skip to content

Email 7/7 (Ops B): Supabase Auth magic links through Resend SMTP #425

Closed

Description

@HMarzban

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

Steps

  1. 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.
  2. Send yourself a magic link on the old settings. Confirm it arrives.
  3. Switch the SMTP settings:
  4. Set Rate Limits to the D3 value at once. Saving custom SMTP settings resets the auth email limit to 30 per hour.
  5. In Authentication > Providers > Email, check that the email OTP expiry is 3600 s or less.
  6. 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.
  7. In Resend, confirm that tracking is still off on the auth domain. A rewritten magic link fails.

Rollback

  1. Restore the step 1 values, password included.
  2. Set Rate Limits back to the step 1 value. The save resets it again.
  3. Send a magic link and confirm it arrives.
  4. 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.

Activity

  1. self-assigned this
    on Oct 6, 2026
  2. added theissue type on Oct 6, 2026
  3. changed the title [-]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[/+] on Oct 6, 2026
  4. HMarzban commented on Oct 12, 2026

    @HMarzban
    CollaboratorAuthor

    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):

    Setting Value
    Custom SMTP on
    Sender docs.plus <no-reply@mail.docs.plus>
    Host / port / user smtp.resend.com / 465 / resend
    Password the integration's key "Supabase Integration", Sending access
    Minimum interval per user 60 s (the integration set 1 s; changed back)
    Rate limit for sending emails 100 per hour (D3). The auth log shows 2/1h → 25 → 100 at 09:40:22Z.
    Email OTP expiration 3600 s (was 86400)
    Resend tracking on mail.docs.plus none configured, so click and open tracking are off
    Resend TLS Opportunistic

    Test 1 (Yahoo), passed with a note.

    • POST /otp at 09:48:55Z returned 200. GET /verify at 09:50:40Z returned 303, and the auth log records user_signedup. The link was not rewritten and it signed in.
    • The mail arrived from docs.plus, but in Yahoo's Junk folder. It used the default Supabase "Confirm Your Signup" template.

    Still open:

    • A second test at Gmail or Outlook, with the Resend message ids.
    • Brand the Supabase Auth templates (Confirm signup, Magic Link, and the rest). The default template is a bare link, which spam filters distrust on a new domain.
    • CAPTCHA on Supabase Auth (gate on this issue).
    • /privacy now names Resend for sign-in mail: ea1269f74 (not pushed yet).
  5. HMarzban commented on Oct 12, 2026

    @HMarzban
    CollaboratorAuthor

    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.tsx sends no captchaToken. Adding Turnstile is a code change for a later issue, before a launch push (D3 on #418).

    Acceptance:

    • Magic links arrived and signed in: Yahoo (Confirm signup, signed in at 09:50:40Z) and Gmail (Magic Link, in the inbox).
    • Both message ids in the Resend log. The maintainer checked the sends in Resend; the ids were not posted here.
    • Rate limit shows 100 per hour (auth log: 2/1h → 25 → 100 at 09:40:22Z).
    • OTP expiry is 3600 s. CAPTCHA is waived by the ruling above.

    Also done:

    • The three branded templates are pasted in Supabase: Magic Link, Confirm signup and Change Email Address. They state "expires in 1 hour", name the reader with {{ .Email }}, and carry no fixed year.
    • /privacy names Resend for sign-in mail, and LEGAL_UPDATED is 12 October 2026.
    • docs/self-hosting/configuration.md has a "Sign-in mail (Supabase Auth)" section.
    • Shipped in deploy run 38239392350.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions