Skip to main content

Domain email and MFA

Why Gmail cannot be the From address

Resend only sends from a domain you verify. yonahmartinez30@gmail.com can still be where a human reads mail. It cannot be EMAIL_FROM_ADDRESS.

Same Resend API key, three jobs

  1. Send. Verify YOUR-DOMAIN in Resend. Set EMAIL_FROM_ADDRESS=Invince <hello@YOUR-DOMAIN> and RESEND_API_KEY. Signup confirmation, Watch, invites, and error mail use this.
  2. Public support address. Set NEXT_PUBLIC_SUPPORT_EMAIL=support@YOUR-DOMAIN and EMAIL_SUPPORT_ADDRESS to the same value. In-app Support tickets go there.
  3. Receive. In Resend, enable receiving on that domain, add the MX record they show, create a webhook for email.received pointing at https://YOUR-DOMAIN/api/webhooks/resend, and put the signing secret in RESEND_WEBHOOK_SECRET. Optional: EMAIL_SUPPORT_FORWARD is your Gmail. The webhook stores the message and forwards it from hello@YOUR-DOMAIN with Reply-To set to the customer.

If YOUR-DOMAIN already has MX records for a real inbox, use a subdomain such as mail.YOUR-DOMAIN so you do not steal existing mail.

Confirm signup mail

A first confirmation from Invince <noreply@YOUR-DOMAIN> with subject Confirm your email address and a “Confirm email address” link is Supabase’s default SMTP template. That often works once, then Auth rate-limits later sends.

Do not leave production on that path. Point Authentication → Hooks → Send Email at https://YOUR-DOMAIN/api/auth/send-email, put the hook secret in SEND_EMAIL_HOOK_SECRET (starts with v1,whsec_), and redeploy Cloud Run. Site URL must be https://YOUR-DOMAIN, not localhost.

Custom SMTP (smtp.resend.com) is an alternative, but it still sits behind Supabase’s Auth send limits.

MFA login verify

  1. Profile → Two-factor authentication → scan the QR → type the 6-digit code → Verify.
  2. Save the backup codes shown once.
  3. Next password sign-in goes to /mfa-challenge. Enter the 6-digit code. If you lost the app, use a backup code. That turns the authenticator off so you can enroll again.
  4. After you enroll, workspace pages and Watch require that extra step (aal2). Ingest keys, webhooks, and public Check do not. If the assurance API is down, Invince fails open so you are not locked out.

Backup codes need CREDENTIAL_ENCRYPTION_KEY and the SQL in supabase/manual/apply_support_inbound_and_mfa_backup.sql.

On-call paging

Workspace Settings stores on-call emails and an optional Slack Incoming Webhook. When an alert opens an incident, those channels fire, then repeat on the 15-minute cron until someone acknowledges or the max page count is reached. Email still needs Resend. This is not phone, SMS, or a PagerDuty schedule.

We use only the cookies necessary to keep you signed in. No analytics or advertising cookies are set. Cookie list