Google Workspace Mailbox Provisioning — ops@, billing@, no-reply@
System: Google Workspace Admin Console
Owner: operator
Purpose: One-time provisioning of ops@raxx.app, billing@raxx.app, and no-reply@raxx.app
Related issue: #1212
Prerequisite: raxx.app fully verified in Google Workspace (DKIM active per #1210)
Last reviewed: 2026-05-19 UTC
Overview
Three @raxx.app addresses need to exist in Google Workspace before automated systems
(CloudWatch alarms, Stripe billing, Postmark outbound) can route to them. All three steps
happen in a single Google Admin console session (~15 minutes total).
Implementation decisions (locked):
| Address | Type | Rationale |
|---|---|---|
ops@raxx.app |
Google Group | Multi-recipient; receives CloudWatch alarms from external senders |
billing@raxx.app |
Google Group | Multi-recipient; receives Stripe + billing alerts from external senders |
no-reply@raxx.app |
Send-as alias on kris@moosequest.net |
Outbound-only; no license consumed; bounce replies go to operator inbox at low v1 volume |
All three decisions are documented in issue #1212 and on the mailbox map in
docs/ops/email-routing.md.
Prerequisites
Before starting this runbook, confirm:
- [ ]
raxx.appshows as Verified in Google Workspace Admin (Domains → Manage domains). If not, complete #1210 first. - [ ]
google._domainkey.raxx.appreturns a DKIM TXT record:
bash
dig +short TXT google._domainkey.raxx.app | head -c 80
Expected: a non-empty string starting with v=DKIM1.
- [ ] No Google Admin session is already in progress for
raxx.appdomain changes (to avoid concurrent modification conflicts).
Step 0 — Convert raxx.app from alias to secondary domain (one-way operation)
This step is only required if raxx.app currently shows as a "Domain alias" in Workspace Admin.
An alias domain cannot host independent Groups — it mirrors the primary domain user list 1:1.
A secondary domain hosts its own independent users and Groups.
Check first:
1. Open https://admin.google.com → Account → Domains → Manage domains.
2. Find raxx.app in the list. Note the Type column.
If Type is "Domain alias":
1. Click raxx.app to open the domain detail.
2. Click Make this a secondary domain (or equivalent — label varies by Workspace edition).
3. Read the confirmation dialog. This is one-way: after conversion, kris@raxx.app will no
longer automatically alias to kris@moosequest.net. If you want to preserve that personal
routing path, add an explicit forward in step 1 of this runbook or set up an alias in Gmail
settings.
4. Click Confirm.
5. Wait 1–2 minutes for the Admin console to finish propagating.
If Type is already "Secondary domain", skip to Step 1.
Step 1 — Provision ops@raxx.app as a Google Group
Purpose: Receives CloudWatch alarm notifications, platform alert digests, and internal ops messages. External senders must be allowed — CloudWatch sends from AWS-owned addresses.
- Open
https://admin.google.com→ Directory → Groups. - Click Create group.
- Fill in:
- Name:
Raxx Ops- Group email:ops@raxx.app- Description:Internal operations alerts — platform alarms, digest notifications, and ops escalations. - Click Next.
- On the Access settings screen: - Who can join the group: Invited members only - Who can view members: Group owners - Who can view conversations: Group members - Who can post: Anyone on the web (required for external CloudWatch senders)
- Click Next, then Create group.
- Add
kris@moosequest.netas owner: - Click Add members, typekris@moosequest.net, set role to Owner, click Add members. - Verify external sender setting: - In the group detail → Settings → Email options → confirm "Allow messages from outside the organization" is On. If it is Off, toggle it on and save.
Test: Send a message to ops@raxx.app from an external address (e.g., your personal Gmail).
Confirm it arrives in the kris@moosequest.net inbox within 2 minutes.
Step 2 — Provision billing@raxx.app as a Google Group
Purpose: Receives Stripe invoices, billing system alerts, and payment-related notifications. External senders must be allowed — Stripe and billing services send from non-Workspace domains.
- Open
https://admin.google.com→ Directory → Groups. - Click Create group.
- Fill in:
- Name:
Raxx Billing- Group email:billing@raxx.app- Description:Billing receipts and escalations — Stripe invoices, billing alerts. - Click Next.
- Access settings: - Who can post: Anyone on the web (required for external billing senders like Stripe) - All other settings: same as ops@ above.
- Click Next, then Create group.
- Add
kris@moosequest.netas owner (same process as Step 1). - Verify external sender setting is On (same as Step 1).
Critical — do not leave billing@ unwatched before Stripe is configured. A blind billing inbox creates a silent failure path for invoices and fraud alerts.
Test: Send a message to billing@raxx.app from an external address. Confirm delivery to
kris@moosequest.net inbox.
Step 3 — Configure no-reply@raxx.app as a send-as alias
Purpose: Outbound sender identity for automated transactional email (Postmark). Not a real inbox. Bounce replies land in Kristerpher's inbox (acceptable at v1 volume).
Option chosen: send-as alias (Option A from email-routing.md). Zero license cost; bounce replies are low-volume signal at pre-launch stage.
Step 3a — Add alias in Google Admin
- Open
https://admin.google.com→ Directory → Users. - Click Kristerpher's account (
kris@moosequest.net). - In the user detail view, scroll to Aliases → click Add alias.
- Enter
no-replyas the alias prefix — the domain@raxx.appauto-populates ifraxx.appis a verified secondary domain. - Click Save.
- Wait 1–5 minutes for the alias to propagate through Google's systems.
Step 3b — Add send-as address in Gmail
- Open Gmail for
kris@moosequest.net. - Go to Settings (gear icon) → See all settings → Accounts and Import tab.
- Under "Send mail as", click Add another email address.
- A dialog opens:
- Name:
Raxx(the display name for outgoing mail) - Email address:no-reply@raxx.app- Uncheck "Treat as an alias" if present (or leave checked — both work here). - Click Next Step.
- Gmail will offer to send a verification email — since this is an alias on a verified domain, Google may auto-verify without sending a code. If a verification code arrives, enter it.
- Once verified,
no-reply@raxx.appappears in the "Send mail as" list.
Step 3c — Set a vacation responder on the alias (optional but recommended)
If you want any inbound mail to no-reply@raxx.app to receive an auto-reply rather than
silently landing in Kristerpher's inbox:
- In Gmail → Settings → General → Vacation responder → turn on.
- Message: "This address does not accept replies. For support, email support@raxx.app."
- Important: do not set this on Kristerpher's primary account — only on a per-alias basis if Gmail supports it, or skip this step and let bounce replies arrive silently at low volume.
In practice at v1 volume, inbound to no-reply@ will be rare (bounce notifications + OOO
auto-replies only). A vacation responder on the primary account is not recommended.
Step 4 — Clear Postmark suppression list
Before ops@raxx.app was provisioned, Postmark may have hard-bounced emails sent to it
(per failure mode B in docs/ops/runbooks/postmark.md). Any suppressed addresses must be
cleared or Postmark will reject future sends.
export POSTMARK_SERVER_TOKEN=$(infisical secrets get POSTMARK_SERVER_API_KEY \
--path /MooseQuest/postmark --env prod --plain)
# Check which raxx.app addresses are suppressed
python3 scripts/ops/postmark_bounce_check.py --suppressions-only
# Clear each suppressed address
python3 scripts/ops/postmark_bounce_check.py --reactivate ops@raxx.app
python3 scripts/ops/postmark_bounce_check.py --reactivate billing@raxx.app
python3 scripts/ops/postmark_bounce_check.py --reactivate no-reply@raxx.app
Verify the suppression list is clean:
python3 scripts/ops/postmark_bounce_check.py --suppressions-only
Expected output: (suppression list is empty) or entries that do NOT include the three new addresses.
Step 5 — Run the post-provisioning verification script
A verification script confirms DNS alignment, mailbox existence signals, and Postmark suppression state from the command line:
export POSTMARK_SERVER_TOKEN=$(infisical secrets get POSTMARK_SERVER_API_KEY \
--path /MooseQuest/postmark --env prod --plain)
python3 scripts/ops/verify_email_provisioning.py
The script checks:
- MX records for raxx.app resolve correctly
- SPF record for raxx.app includes both Google and Postmark
- DKIM records for google._domainkey.raxx.app and pm._domainkey.raxx.app are present
- DMARC record for _dmarc.raxx.app is present and not p=none
- None of the three target addresses appear in the Postmark suppression list
All checks should pass before closing issue #1212.
Post-provisioning checklist
- [ ]
raxx.appis a secondary domain (not alias) in Google Workspace Admin - [ ]
ops@raxx.appGoogle Group created; external senders allowed - [ ] Test message to
ops@raxx.appdelivered tokris@moosequest.net - [ ]
billing@raxx.appGoogle Group created; external senders allowed - [ ] Test message to
billing@raxx.appdelivered tokris@moosequest.net - [ ]
no-reply@raxx.appalias created onkris@moosequest.net - [ ]
no-reply@raxx.appappears as send-as option in Gmail - [ ] Postmark suppression list cleared for all three addresses
- [ ]
python3 scripts/ops/verify_email_provisioning.py— all checks pass - [ ]
docs/ops/email-routing.mdprovisioning state table updated to "Live" - [ ] Comment on issue #1212 confirming each address and closing the card
Rollback notes
- Google Groups can be deleted at any time in Google Admin → Directory → Groups → Delete group.
- The alias on
kris@moosequest.netcan be removed in Google Admin → Users → Aliases → Remove. - The Gmail send-as address can be removed in Gmail → Settings → Accounts and Import → Delete.
- None of these operations affect DNS or Postmark configuration — those are independent.
Related
- Issue: #1212
docs/ops/email-routing.md— authoritative mailbox map (update after provisioning)docs/ops/email-dns-state.md— moosequest.net SPF/DKIM/DMARCdocs/ops/runbooks/postmark.md— Postmark bounce/suppression diagnosticscripts/ops/verify_email_provisioning.py— post-provisioning DNS + suppression checkerscripts/ops/postmark_bounce_check.py— suppression list management