Mail Admin 101
Internal guide for Cadence team. Last updated: December 2025.
This is a programmer’s guide to email infrastructure. We don’t have dedicated sysadmins, so anyone on the team might need to debug delivery issues, add a new sending service, or understand why emails are going to spam.
How We Send Mail
Section titled “How We Send Mail”Google Workspace handles all person-to-person email. When you send from katherine.johnson@c15.io in Gmail, it goes through Google’s mail servers.
HubSpot sends marketing and automated emails. These also come from @c15.io addresses but route through HubSpot’s infrastructure.
Amazon SES handles transactional email from Momentum (via the send.chat subdomain).
Resend sends automated invoices from finops@c15.io (Willdan Invoice Worker).
All sending services need to be explicitly authorized in our DNS, or receiving servers will reject or spam-folder the messages.
We also use Twilio for SMS, which webhooks to cadence-discord-api.cadence-onefive.workers.dev/webhooks/twilio.
Where Things Live
Section titled “Where Things Live”- DNS records: Cloudflare (dash.cloudflare.com)
- Google Workspace admin: admin.google.com
- HubSpot email settings: app.hubspot.com → Settings → Domain & URLs
- DMARC monitoring: app.dmarcreport.com
How Email Authentication Works
Section titled “How Email Authentication Works”When you send an email from katherine.johnson@c15.io, the receiving server has no built-in way to verify it actually came from us. Three systems work together to solve this:
- SPF — A DNS record listing IP addresses allowed to send mail for c15.io
- DKIM — A cryptographic signature added to each email, verified against a public key in DNS
- DMARC — A policy that tells receivers what to do when SPF/DKIM fails, plus reporting
DNS Basics
Section titled “DNS Basics”DNS (Domain Name System) stores records that other servers look up. For email, the relevant record types are:
- MX — Where to deliver incoming mail
- TXT — Text data, used for SPF, DKIM public keys, and DMARC policies
- CNAME — Aliases, sometimes used for DKIM
All our DNS is in Cloudflare at dash.cloudflare.com.
MX Records
Section titled “MX Records”These tell other servers where to deliver mail sent TO c15.io. Our Google Workspace MX records:
c15.io MX 1 aspmx.l.google.comc15.io MX 5 alt1.aspmx.l.google.comc15.io MX 5 alt2.aspmx.l.google.comc15.io MX 10 alt3.aspmx.l.google.comc15.io MX 10 alt4.aspmx.l.google.comThe numbers are priority — lower = tried first.
There’s also an MX record for send.chat subdomain pointing to Amazon SES (feedback-smtp.us-east-...).
A TXT record listing who can send mail FROM c15.io. Ours:
c15.io TXT "v=spf1 include:21122440.spf..."The 21122440 is HubSpot’s SPF include. The full record should also include Google (include:_spf.google.com) and Resend.
- v=spf1 — SPF version 1
- include:_spf.google.com — Trust Google Workspace’s mail servers
- include:[hubspot] — Trust HubSpot’s mail servers
- ~all — Soft fail anything else (treat with suspicion but don’t reject)
SPF has a limit of 10 DNS lookups. Each include costs at least one. If you add too many services, SPF breaks silently.
Each outgoing email gets a cryptographic signature. The receiving server looks up the public key in DNS to verify it.
Each sending service needs its own DKIM record. Ours:
Google Workspace:
google._domainkey.c15.io TXT "v=DKIM1; k=rsa; p=MIIBIjA..."HubSpot:
hs1-21122440._domainkey.c15.io CNAME c15-io.hs09a.dkim.hubspot...hs2-21122440._domainkey.c15.io CNAME c15-io.hs09b.dkim.hubspot...Resend:
resend._domainkey.c15.io TXT "p=MIGfMA0GCSqGSIb3D..."DMARC ties SPF and DKIM together. It’s a TXT record at _dmarc.c15.io:
_dmarc.c15.io TXT "v=DMARC1; p=quarantine; ..."- p=quarantine — Send failures to spam (options: none, quarantine, reject)
- pct=100 — Apply to 100% of messages
- rua=mailto:… — Send aggregate reports here (pointed at DMARC Report)
Alignment
Section titled “Alignment”SPF and DKIM can pass but still fail DMARC if they don’t “align.” Alignment means the domain in the From: header matches the domain that passed SPF/DKIM.
Example: You send from katherine.johnson@c15.io but the DKIM signature is for marketing-platform.com. DKIM passes (signature is valid) but doesn’t align (wrong domain). DMARC fails.
For DMARC to pass, at least one of SPF or DKIM must both pass AND align.
The Authentication Flow
Section titled “The Authentication Flow”- Google Workspace sends email, adds DKIM signature
- Receiving server checks SPF (is this IP in c15.io’s SPF record?)
- Receiving server checks DKIM (does signature match public key in DNS?)
- Receiving server checks alignment (do passing results match the From: domain?)
- If DMARC fails, receiving server follows our policy (quarantine → spam folder)
- Receiving server sends aggregate report to our rua address
DMARC Report Monitoring
Section titled “DMARC Report Monitoring”Raw DMARC reports are XML. We use DMARC Report (app.dmarcreport.com) to aggregate them.
Reading the dashboard
Section titled “Reading the dashboard”- Compliant: Passed DMARC. Good.
- Non-compliant: Failed DMARC. Either spoofing or misconfigured sender.
- SPF/DKIM Aligned: Percentage where that method passed AND aligned.
What the numbers mean
Section titled “What the numbers mean”- 99%+ compliant: Normal. Small failures are usually forwarded emails or spoofing attempts.
- 90-99% compliant: Investigate. Likely a legitimate sender missing from SPF/DKIM.
- Below 90%: Something is misconfigured.
Alerts
Section titled “Alerts”In DMARC Report, go to Alerts and configure notifications for compliance drops or new senders. Then you don’t need to check manually.
Google Workspace Admin
Section titled “Google Workspace Admin”Verify DKIM is enabled
Section titled “Verify DKIM is enabled”- admin.google.com
- Apps → Google Workspace → Gmail → Authenticate email
- Select c15.io
- Should show “Authenticating email”
Email logs
Section titled “Email logs”- admin.google.com
- Reports → Email log search
- Search by sender/recipient/subject
Common Issues
Section titled “Common Issues”New tool, emails not delivering
Section titled “New tool, emails not delivering”The tool is sending as @c15.io but isn’t in SPF or doesn’t have DKIM. Check the tool’s docs for their SPF include and DKIM setup instructions.
SPF PermError: too many DNS lookups
Section titled “SPF PermError: too many DNS lookups”You’ve hit the 10-lookup limit. Remove unused services or use SPF flattening (MXToolbox offers this).
Emails going to spam
Section titled “Emails going to spam”Check in order:
- Is DKIM enabled in Google Workspace admin?
- Is the DKIM DNS record in Cloudflare?
- What does DMARC Report show?
- Check email headers (Gmail: More → Show original) for Authentication-Results
Non-compliant messages in report
Section titled “Non-compliant messages in report”Small numbers (1-5/week) are normal — forwarded emails or caught spoofing attempts. A sudden spike means check Hosted Services in DMARC Report to identify the sender.
Moving to p=reject
Section titled “Moving to p=reject”We’re at p=quarantine (failures go to spam). The final step is p=reject (failures bounce).
Before switching:
- Run at quarantine for 4+ weeks
- Verify 99%+ compliance consistently
- Confirm all legitimate senders have SPF and DKIM
- Consider starting with pct=10 and increasing gradually
Google Workspace Mail Settings
Section titled “Google Workspace Mail Settings”Org-Wide Email Footers
Section titled “Org-Wide Email Footers”These append standard text to all outgoing emails. We use them for:
- Company contact info — Standard footer on all outgoing mail
- Holiday notices — “Our office is closed Dec 23 - Jan 3” during the last two weeks of the year
To configure:
- admin.google.com
- Apps → Google Workspace → Gmail → Compliance
- Look for “Append footer”
- Add your footer text, choose which OUs it applies to
Footers are added server-side, so users don’t see them in their Sent folder, but recipients do.
Mail Routing
Section titled “Mail Routing”Routing rules control what happens to email before or after delivery. We use them for:
- Consultant aliases — Give contractors a c15.io address that forwards to their personal inbox, so they don’t have to check multiple accounts
- Test email routing — Redirect emails that would go to real users in production to test inboxes instead (from back when we tested on prod)
- Dynamic addresses — Pattern matching like
admin-[a-z0-9]+@c15.ioroutes toadmin@so we can useadmin-projectname@oradmin-12345@and sort/filter by the suffix
To configure:
- admin.google.com
- Apps → Google Workspace → Gmail → Routing
- Add or edit routing rules
You can match on recipient patterns, add headers, change the envelope recipient, or BCC copies elsewhere.
Quick Reference
Section titled “Quick Reference”- Google Admin Toolbox: toolbox.googleapps.com/apps/dig — DNS lookups
Logins
Section titled “Logins”- Cloudflare: dash.cloudflare.com
- Google Workspace: admin.google.com
- HubSpot: app.hubspot.com → Settings → Domain & URLs
- DMARC Report: app.dmarcreport.com
Debugging
Section titled “Debugging”Check email headers (Gmail: More → Show original). Look for Authentication-Results to see what passed/failed. If stuck, post in the help chat channel with the headers.
Internal & Confidential: This page is only available in the internal handbook and contains confidential information.
