Building a Domain-Isolated Payment Logging System: Decoupling Tenant Infrastructure from Corporate Identity
What Was Done
We completed a critical infrastructure refactor for the dangerouscentaur.com tenant management system, addressing a fundamental security and operational concern: the tenant portal was sending credentials and communications from the queenofsandiego.com domain, creating an inappropriate coupling between the corporate brand and tenant-facing systems. This work involved:
- Establishing dangerouscentaur.com as a completely independent email identity within AWS SES
- Building a forward-to-Lambda payment logging pipeline that captures Zelle transfer confirmations and automatically records them in the tenant hub
- Deploying a new Lambda function (
lambda-email-parser) to parse forwarded bank emails and extract payment metadata - Wiring Google Apps Script to intercept payment emails and invoke the new logging system
- Regenerating and resending tenant credentials via the proper domain sender
Technical Architecture
Email Domain Isolation
The fundamental issue was that SES was configured to send from queenofsandiego.com, creating a brand association problem. We needed to:
- Register dangerouscentaur.com as a verified SES sending domain
- Establish DKIM tokens and configure DNS records at the domain registrar (Namecheap)
- Set up an ImprovMX email alias to receive forwarded payment confirmations
The key insight here was using ImprovMX as a lightweight email routing layer rather than running a full mail server. This keeps operational complexity minimal while providing a stable inbound address for bank notifications.
Payment Logging Pipeline
We implemented a three-stage system:
- Email Receipt: A forwarded Zelle confirmation arrives at the ImprovMX alias and is routed to Google Apps Script
- Parsing: The new Lambda function
/scripts/lambda-email-parser/lambda_function.pyextracts payment details (sender, amount, timestamp, reference) from raw email body - Persistence: The existing
lambda-receipt-actionfunction receives the parsed data and appends it toreceipts.jsonin the S3 bucket
The lambda-email-parser uses regex patterns to identify Zelle payment confirmation language and extract key fields:
def parse_zelle_payment(email_body):
# Extracts: sender name, amount, timestamp, reference text
# Returns dict for lambda-receipt-action to persist
patterns = {
'amount': r'\$[\d,]+\.\d{2}',
'sender': r'from\s+([A-Za-z\s]+)',
'timestamp': r'sent on\s+(.+?)[\.\n]'
}
Receipt Action Lambda Enhancement
The existing lambda-receipt-action function at /scripts/lambda-receipt-action/lambda_function.py was extended with a new admin action: log_rent_payment. This function:
- Validates the request using an
ADMIN_TOKENenvironment variable (prevents unauthorized payment logging) - Reads the current
receipts.jsonfrom the S3 bucket - Appends the new payment record with tenant ID and timestamp
- Writes the updated file back to S3
- Triggers a CloudFront cache invalidation so the hub immediately reflects the new payment
The ADMIN_TOKEN is stored in Lambda environment variables and known only to the Apps Script execution context, preventing external payment spoofing.
Google Apps Script Integration
The WarmLeadResponder.gs script was extended to detect forwarded payment emails by pattern matching the subject and body for Zelle language. When a payment email is detected:
- It extracts the email content
- Calls the
lambda-email-parserto normalize the data - Invokes
lambda-receipt-actionwith theADMIN_TOKENand parsed payment details - Logs the action to the GAS execution log for audit purposes
This creates a clear audit trail: original email → GAS log → Lambda execution logs → receipts.json update.
Infrastructure Details
S3 and CloudFront
The tenant hub is hosted at:
- S3 Bucket: Deployed at
s3://3028-fiftyfirst-street-92105-dangerouscentaur/ - CloudFront Distribution: Maps
3028fiftyfirststreet.92105.dangerouscentaur.comto the S3 origin - Index File:
/index.htmlcontains the hub dashboard, credentials table, and receipts viewer
After updating credentials and payment records, we invalidate the CloudFront cache:
aws cloudfront create-invalidation \
--distribution-id [DISTRIBUTION_ID] \
--paths "/*"
Full path invalidation ensures tenants always see current data within seconds of updates.
Lambda Function URLs
Both Lambda functions are configured with function URLs (HTTP endpoints) for direct invocation:
lambda-receipt-action: HandlesGET /receiptsto fetch current payment records andPOST /log_paymentto record new paymentslambda-email-parser: ExposesPOST /parseto normalize email content into structured payment data
Both require the ADMIN_TOKEN in request headers, validated before any operation.
SES Configuration
DKIM verification was completed for dangerouscentaur.com in SES. The domain registrar (Namecheap) was updated with DKIM tokens to enable SPF/DKIM signing on outbound mail. This prevents deliverability issues and ensures tenant emails arrive in primary inboxes rather than spam folders.
Key Architectural Decisions
Why Forward Emails Instead of Manual Entry?
Requiring the owner to manually type payment confirmations into a chat interface creates friction and audit risk. By accepting email forwards, we leverage existing banking workflows and create an immutable audit trail (the original email). The parsing Lambda normalizes these into structured records.
Why Admin Token Authentication?
Without token validation, anyone who discovers the Lambda URL could forge payment records. By requiring a token only known to the Apps Script execution context, we restrict payment logging to our controlled automation pipeline.
Why Complete Domain Separation?
Tenants should never see queenofsandiego.com in their communications. The corporate brand and tenant management system must be visually and operationally distinct. This also simplifies future scalability—multiple property groups could each have their own domain without brand confusion.
Deployment Commands