All DigitalRCC mail — Moodle notifications, Supabase authentication mail and
portal student mail — now leaves as no-reply@digitalrcc.com through the
Google Workspace relay, authenticated with SPF, DKIM and DMARC. Nothing sends as
*.tcecure.com any more.
No credential belongs on this page. SMTP app passwords, service-role keys and
API tokens live only in the Moodle config, Vercel/Supabase environment and the
secret store.
| Item | Value |
|---|---|
| From address | no-reply@digitalrcc.com |
| From display name | DigitalRCC |
| Reply-To / support | support@digitalrcc.com |
| SMTP host | smtp.gmail.com:587, STARTTLS |
| SMTP authentication | Google Workspace app password for admin@digitalrcc.com, with no-reply@ as a verified Send mail as alias |
| SPF | TXT @ → v=spf1 include:_spf.google.com ~all (Namecheap) |
| DMARC | TXT _dmarc → v=DMARC1; p=none; rua=mailto:admin@digitalrcc.com |
| DKIM | Google Workspace signing for digitalrcc.com |
Verified against real delivered headers: envelope sender and From both
no-reply@digitalrcc.com, DKIM d=digitalrcc.com, sent from Google's outbound
range covered by the SPF include.
Verified against the live systems (Supabase auth config, Vercel production
environment, Moodle config, Wiki.js settings, AWX API, DNS) and by real
delivery tests, not by grepping the repositories.
| Address | What it actually is | Used by |
|---|---|---|
admin@digitalrcc.com |
The only real mailbox on the domain | SMTP authentication for Supabase, portal and Moodle; DMARC rua destination |
no-reply@digitalrcc.com |
Alias on admin@, and a verified Send mail as identity |
From address on all five templates |
support@digitalrcc.com |
Alias on admin@, and a verified Send mail as identity |
Reply-To on all student mail; Moodle support address |
cyberlab@tcecure.com |
Monitored destination on the tcecure side | Portal support-ticket notifications (SUPPORT_NOTIFY_EMAIL) |
Delivery test, sent from admin@digitalrcc.com: mail to support@ and
no-reply@ arrived in the admin@ mailbox, mail to cyberlab@tcecure.com
arrived in the monitored box, and a deliberately non-existent
digitalrcc.com address bounced — which is what proves the first two are
aliases that deliver rather than addresses being silently dropped.
Note that Gmail's submission server returns 250 at RCPT TO for any
recipient, including addresses that do not exist. SMTP probing cannot be used
to test whether an address is real; send a message and watch for the bounce.
Every other address appearing in the repositories — admin2@, approver@,
dev@, analyst@, student03@digitalrcc.com, labadmin@, student@,
jane@tcecure.com — is test fixture or documentation, not a mailbox.
Nothing else on the platform sends mail: AWX has zero notification templates
(its only account carries a placeholder address), Wiki.js has no SMTP
configured, and Guacamole sends none. Wiki.js accounts are
admin@cyberlab.tcecure.com, eddie.barlow@, tina.williams@,
christopher.green@ and devin.bot@tcecure.com.
Decision: forward, do not create a group. Google will not let a group own
an address that is an alias on a user account, so a support@ group would
require removing the alias first and re-verifying the Send mail as entry
(the verification mail then lands in the group inbox). A group is only worth
that if several people must monitor a shared archive independent of the
admin@ account.
The forward, configured in admin@digitalrcc.com's Gmail:
cyberlab@tcecure.com as asupport@digitalrcc.com → Forward it to cyberlab@tcecure.com, plusCaveats: a filter only applies to mail arriving after it is created, and Gmail
does not forward messages it classifies as spam.
DMARC aggregate reports still go to admin@; they are deliberately left out of
the monitored box so it stays human mail only.
| Setting | Value |
|---|---|
| Site full name | Digital Resilience Community Clinic |
| Site short name | DigitalRCC |
| No-reply address | no-reply@digitalrcc.com |
| Support name / address | DigitalRCC Support / support@digitalrcc.com |
| "via" suffix | Disabled — the From reads plainly DigitalRCC <no-reply@digitalrcc.com> |
The old display name came from a noreplyname language override in
/var/moodledata/lang/*_local/moodle.php on the LMS host (backed up before
editing). The chat server host and hub contact address were also moved off the
old domain.
Analytics insights: Moodle's no_recent_accesses model mails course
teachers, not site admins — the recipients are enrolled users holding
moodle/analytics:listinsights (teacher, editingteacher, manager,
pgctc_admin, pgctc_teacher, pgctc_helpdesk, pgctc_helpdeskv2). Plain site
admins with no course role are excluded. Left enabled by decision; the portal's
Live Operations view supersedes it for real inactivity tracking.
EMAIL_DELIVERY_MODE=live in Vercel. Student mail is sent by the portal over
the same Workspace relay (SES was never provisioned and is not used), queued in
the email_jobs table and visible at /admin/email-jobs. A worker route
drains the queue and is also triggered by Vercel cron; both are protected by
CRON_SECRET.
Three are edited in the Supabase dashboard (Authentication → Email Templates)
and two are rendered by the portal. All five share the branded HTML shell:
dark navy #0d1b2f panel, the DigitalRCC logo hosted at
https://my.digitalrcc.com/brand/, detail rows, a CTA button and a plain-text
alternative.
| Template | Where | Subject | Purpose |
|---|---|---|---|
| Invite user | Supabase | Welcome to the DigitalRCC Lab Companion | Portal account activation → /auth/invite?token_hash=… |
| Reset password | Supabase | Password reset | Recovery link → /auth/recovery |
| Confirm signup | Supabase | Confirm your email | Signup confirmation → /auth/confirm |
student_lab_queue_confirmation |
Portal | You are in the queue | Confirms the learner is queued for a cohort |
student_lab_seat_assigned |
Portal | Your DigitalRCC lab access is ready | Names the pod, lab username and access window |
Source of the portal-side templates and the Supabase HTML files:
supabase/email-templates/{invite,recovery,confirmation}.html in
tcecure/drcc-lab-companion. Supabase takes several minutes to pick up an
edited template — verify with a live invite to a throwaway address rather than
assuming.
The Supabase auth sender name is DigitalRCC, matching portal mail.
Supabase's mailer_otp_exp governs how long the invite, recovery and
confirmation links stay valid. It was 3600 s (1 hour), which expired the
current cohort's invites before two of the three students opened them — they saw
"This invitation is invalid or has expired" on the login page. It is now
172800 s (48 hours). Expiry is evaluated when the link is clicked, so
raising it also revives links already sitting in inboxes.
Links are also single-use: a student who clicks an activation link twice
gets the same message on the second click. If they have already set a password,
send them to Forgot password rather than a new invite. Re-invite with the
Supabase admin POST /auth/v1/invite, which reissues the link for an existing
unconfirmed account — note this invalidates the token in any earlier invite,
so only resend when the student no longer has a usable one.
Lab passwords are never emailed. The seat email points the student at the
portal; the portal-managed credential store that will show it is still to be
built (Backlog).
| Page | Purpose |
|---|---|
| Portal Integration | Import, seating and the email jobs view |
| Backlog & Known Issues | Outstanding credential work |