Skip to content

AUTH-MAIL-001 — Brand and authenticate Firebase Authentication email #119

Description

@daliu

Officer impact: Account verification and password-recovery messages use a recognizable club sender and link domain, reducing confusion and spam placement. Officers have a short, safe way to check delivery without handling passwords or action links.

Officer documentation: Add a plain-language Auth-email procedure under docs/officers/, link it from docs/officers/ACCESS_CONTINUITY.md and docs/officers/EMERGENCY_AND_RECOVERY.md, update the email path in docs/officers/SYSTEM_MAPS.md, and define SPF, DKIM, and DMARC once in docs/officers/GLOSSARY.md.

Deployment evidence: None at issue creation. This is owner/provider configuration. Closure requires private Firebase-console readback, public DNS readback, staging-only synthetic delivery evidence, named approvals, and rollback proof. Do not publish mailbox headers, action links, recipient addresses, DNS-console screenshots, or private provider locators.

User-reported symptom

On 2026-07-12, Firebase sent account mail from noreply@mid-peninsula-running-club.firebaseapp.com, and the message went directly to spam.

The exact spam decision is not proven without redacted authentication headers. Marking one message as not spam is only a temporary personal workaround.

Read-only diagnosis

The app uses Firebase Authentication's built-in verification and password-reset templates. The event-registration email Function is a separate system and cannot repair Auth email delivery.

The default Firebase sender is still active. Public DNS does not currently show an apex SPF policy or _dmarc.runmprc.com; auth.runmprc.com appears unused. Do not add guessed records or replace DNS until every legitimate sender is inventoried and Firebase shows the exact records it requires.

Changing the app's authDomain is not the fix. That setting supports Firebase Auth web flows, while runmprc.com is hosted separately.

Atomic outcome

Configure every Firebase Authentication template to use an owner-approved, authenticated club email domain and action-link domain. A dedicated subdomain such as auth.runmprc.com is the default design candidate because it isolates mail authentication and avoids changing the website's apex/www hosting, but the Firebase/DNS owners must approve the exact domain and records.

This issue covers Firebase-hosted Auth email only. A custom SMTP/mail provider is a separate later design if the hosted path remains inadequate.

Owner decisions required

  • Named primary and backup Firebase owners.
  • Named DNS owner and a second approver.
  • Sender subdomain, display name, reply-to mailbox, and communications owner.
  • Inventory of all legitimate runmprc.com senders before SPF/DMARC changes.
  • Owner-approved SPF, DKIM, and DMARC rollout/rollback policy based on provider-supplied records and observed alignment.
  • Staging Firebase project/subdomain and synthetic test mailboxes.

Procedure boundary

  1. Configure the staging Firebase project first.
  2. Open Authentication > Templates and configure each supported template/domain.
  3. Copy only the exact TXT/CNAME names and values Firebase supplies into the private DNS change record.
  4. Have the second owner review the change and verify it does not alter Netlify apex/www records.
  5. Apply DNS, wait for Firebase to report verification complete, then apply the custom domain to every Auth template.
  6. Use only synthetic staging accounts to test a Gmail and a non-Gmail mailbox.
  7. Redact recipient, Message-ID, codes, and the entire action URL before recording SPF/DKIM/DMARC results privately.
  8. Test a valid link once, reuse, expiration, and rollback in staging.
  9. Repeat the approved configuration in production without sending a synthetic production email. Report production as configured but live behavior unproven until normal approved use supplies private evidence.

Acceptance criteria

  • Every Auth template in staging and production shows the approved custom domain as Verified and Applied.
  • The visible From name/domain and action-link domain match the approved club identity.
  • The exact Firebase-supplied DNS records resolve publicly; no record was guessed or copied from a different environment.
  • Each host has one valid combined SPF policy where applicable; website apex/www and other legitimate senders still work.
  • Staging synthetic messages to two provider families show expected SPF, DKIM, and DMARC alignment in redacted headers.
  • Valid, reused, expired, wrong-environment, and rollback link behavior is verified in staging.
  • Reply handling reaches the approved monitored mailbox or the template clearly says replies are not monitored.
  • No real member, production action link, password, recovery code, full header, or provider secret appears in GitHub, logs, screenshots, or AI tools.
  • A backup owner can follow the documented check and identify when to stop/escalate.
  • Evidence distinguishes DNS configured, Firebase verified, template applied, staging delivery proven, production configured, and production delivery proven.

Dependencies and coordination

Explicitly out of scope

  • Custom SMTP/provider implementation, marketing email, event confirmations, receipts, or bulk mail.
  • Changing authDomain, Netlify records, the website URL, or application login providers.
  • Production test messages, inbox access, real-member addresses, or public message headers/action links.

Claim protocol

Creation is not an engineering or provider claim. Before acting, name the Firebase and DNS owners, record two-person approval privately, assign the issue, and post a timestamped claim. Console and DNS actions require private evidence and an approved rollback window.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:authAuthentication and authorizationarea:firebaseFirebase services and dataneeds-external-configRequires provider console or external configurationpriority:P0Launch blocker or urgent security risksize:SSmall focused issuestatus:blocked-ownerRequires an owner or external decisiontype:operationsOperational setup or runbooktype:securitySecurity or privacy boundary

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions