Skip to content

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.

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.

  • 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

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 (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.

These tell other servers where to deliver mail sent TO c15.io. Our Google Workspace MX records:

c15.io MX 1 aspmx.l.google.com
c15.io MX 5 alt1.aspmx.l.google.com
c15.io MX 5 alt2.aspmx.l.google.com
c15.io MX 10 alt3.aspmx.l.google.com
c15.io MX 10 alt4.aspmx.l.google.com

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

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.

  1. Google Workspace sends email, adds DKIM signature
  2. Receiving server checks SPF (is this IP in c15.io’s SPF record?)
  3. Receiving server checks DKIM (does signature match public key in DNS?)
  4. Receiving server checks alignment (do passing results match the From: domain?)
  5. If DMARC fails, receiving server follows our policy (quarantine → spam folder)
  6. Receiving server sends aggregate report to our rua address

Raw DMARC reports are XML. We use DMARC Report (app.dmarcreport.com) to aggregate them.

  • Compliant: Passed DMARC. Good.
  • Non-compliant: Failed DMARC. Either spoofing or misconfigured sender.
  • SPF/DKIM Aligned: Percentage where that method passed AND aligned.
  • 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.

In DMARC Report, go to Alerts and configure notifications for compliance drops or new senders. Then you don’t need to check manually.

  1. admin.google.com
  2. Apps → Google Workspace → Gmail → Authenticate email
  3. Select c15.io
  4. Should show “Authenticating email”
  1. admin.google.com
  2. Reports → Email log search
  3. Search by sender/recipient/subject

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.

You’ve hit the 10-lookup limit. Remove unused services or use SPF flattening (MXToolbox offers this).

Check in order:

  1. Is DKIM enabled in Google Workspace admin?
  2. Is the DKIM DNS record in Cloudflare?
  3. What does DMARC Report show?
  4. Check email headers (Gmail: More → Show original) for Authentication-Results

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.

We’re at p=quarantine (failures go to spam). The final step is p=reject (failures bounce).

Before switching:

  1. Run at quarantine for 4+ weeks
  2. Verify 99%+ compliance consistently
  3. Confirm all legitimate senders have SPF and DKIM
  4. Consider starting with pct=10 and increasing gradually

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:

  1. admin.google.com
  2. Apps → Google Workspace → Gmail → Compliance
  3. Look for “Append footer”
  4. 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.

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.io routes to admin@ so we can use admin-projectname@ or admin-12345@ and sort/filter by the suffix

To configure:

  1. admin.google.com
  2. Apps → Google Workspace → Gmail → Routing
  3. Add or edit routing rules

You can match on recipient patterns, add headers, change the envelope recipient, or BCC copies elsewhere.

  • Google Admin Toolbox: toolbox.googleapps.com/apps/dig — DNS lookups
  • Cloudflare: dash.cloudflare.com
  • Google Workspace: admin.google.com
  • HubSpot: app.hubspot.com → Settings → Domain & URLs
  • DMARC Report: app.dmarcreport.com

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.