Raxx · internal docs

internal · gated

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:

bash dig +short TXT google._domainkey.raxx.app | head -c 80

Expected: a non-empty string starting with v=DKIM1.


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.

  1. Open https://admin.google.com → Directory → Groups.
  2. Click Create group.
  3. Fill in: - Name: Raxx Ops - Group email: ops@raxx.app - Description: Internal operations alerts — platform alarms, digest notifications, and ops escalations.
  4. Click Next.
  5. 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)
  6. Click Next, then Create group.
  7. Add kris@moosequest.net as owner: - Click Add members, type kris@moosequest.net, set role to Owner, click Add members.
  8. 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.

  1. Open https://admin.google.com → Directory → Groups.
  2. Click Create group.
  3. Fill in: - Name: Raxx Billing - Group email: billing@raxx.app - Description: Billing receipts and escalations — Stripe invoices, billing alerts.
  4. Click Next.
  5. Access settings: - Who can post: Anyone on the web (required for external billing senders like Stripe) - All other settings: same as ops@ above.
  6. Click Next, then Create group.
  7. Add kris@moosequest.net as owner (same process as Step 1).
  8. 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

  1. Open https://admin.google.com → Directory → Users.
  2. Click Kristerpher's account (kris@moosequest.net).
  3. In the user detail view, scroll to Aliases → click Add alias.
  4. Enter no-reply as the alias prefix — the domain @raxx.app auto-populates if raxx.app is a verified secondary domain.
  5. Click Save.
  6. Wait 1–5 minutes for the alias to propagate through Google's systems.

Step 3b — Add send-as address in Gmail

  1. Open Gmail for kris@moosequest.net.
  2. Go to Settings (gear icon) → See all settings → Accounts and Import tab.
  3. Under "Send mail as", click Add another email address.
  4. 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).
  5. Click Next Step.
  6. 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.
  7. Once verified, no-reply@raxx.app appears in the "Send mail as" list.

If you want any inbound mail to no-reply@raxx.app to receive an auto-reply rather than silently landing in Kristerpher's inbox:

  1. In Gmail → Settings → General → Vacation responder → turn on.
  2. Message: "This address does not accept replies. For support, email support@raxx.app."
  3. 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


Rollback notes