Building a Domain-Isolated Payment Logging System: Tenant Portal Security & Email Architecture
What Was Done
We implemented a complete domain isolation for a rental property tenant portal, including credential distribution, a payment logging pipeline, and automated Zelle payment forwarding via email. The system enables landlords to forward bank payment notifications to a secure inbox alias, which automatically logs payments in the tenant hub without manual intervention.
Domain Isolation & Infrastructure Decisions
The critical requirement was complete separation from queenofsandiego.com. The tenant portal previously sent emails through that domain, creating compliance and operational issues. We implemented everything under the dangerouscentaur.com domain instead.
Why this matters: Domain reputation affects email deliverability. Mixing unrelated business entities under one domain degrades sender authentication scores and creates confusion in email headers. By isolating to dangerouscentaur.com, we established a clean, property-specific sending domain with proper SPF/DKIM records.
Infrastructure components:
- CloudFront Distribution:
3028fiftyfirststreet.92105.dangerouscentaur.comwith S3 origin for the tenant hub HTML/JS - S3 Bucket: Hosts the tenant portal index.html and static assets
- Lambda Functions:
lambda-receipt-action– Processes payment logging requests with admin token validationlambda-email-parser– Handles incoming email forwarding and command parsing
- SES Domain:
dangerouscentaur.comwith verified DKIM tokens in Route53 - ImprovMX Alias: Custom inbox alias for receiving forwarded payment notifications
Credential Management & Portal Deployment
We generated fresh temporary passwords for both tenants and embedded them in the tenant portal alongside hashed credentials stored in a JSON configuration file.
File modified: /repos/sites/dangerouscentaur/demos/3028fiftyfirststreet.92105.dangerouscentaur.com/index.html
The credentials table was embedded directly in the HTML (not transmitted over the network separately). After updating the portal:
aws s3 cp index.html s3://dangerouscentaur-tenant-portal/index.html --profile [profile]
Then invalidated the CloudFront distribution cache to force immediate propagation:
aws cloudfront create-invalidation --distribution-id [DIST_ID] --paths "/*" --profile [profile]
Email Delivery via SES
Credential emails were sent through AWS SES using an ImprovMX alias configured on dangerouscentaur.com:
- Sender:
noreply@dangerouscentaur.com(ImprovMX alias) - Recipient: Tenant email addresses (sourced from local records)
- Content: Portal URL + temporary password + setup instructions
This replaced the previous queenofsandiego.com sender, ensuring email headers and authentication records point to the correct domain.
Payment Logging Pipeline Architecture
The most interesting technical challenge was automating Zelle payment logging without manual data entry. We built a three-stage pipeline:
Stage 1: Email Forwarding
The landlord forwards Zelle notifications (from their bank) to payments@dangerouscentaur.com (the ImprovMX inbox alias). This triggers:
ImprovMX → Lambda Webhook → lambda-email-parser function
Stage 2: Email Parsing (lambda-email-parser)
File: /repos/sites/dangerouscentaur/demos/3028fiftyfirststreet.92105.dangerouscentaur.com/scripts/lambda-email-parser/lambda_function.py
This Lambda extracts:
- Sender email (identifies tenant)
- Payment amount (via regex parsing of Zelle message body)
- Transaction timestamp
- Confirmation code (if present)
Then calls the receipt-action Lambda's admin endpoint with these details:
POST /admin/log_payment
Authorization: Bearer [ADMIN_TOKEN]
Content-Type: application/json
{
"tenant_id": "3028-51st",
"amount": 1500.00,
"method": "zelle",
"confirmation_id": "BANK_CONFIRMATION_123",
"timestamp": "2024-01-15T14:32:00Z"
}
Stage 3: Receipt Logging (lambda-receipt-action)
File: /repos/sites/dangerouscentaur/demos/3028fiftyfirststreet.92105.dangerouscentaur.com/scripts/lambda-receipt-action/lambda_function.py
This Lambda validates the admin token (environment variable ADMIN_TOKEN) and appends the payment entry to receipts.json in S3:
receipts.json:
{
"payments": [
{
"tenant_id": "3028-51st",
"amount": 1500.00,
"method": "zelle",
"logged_at": "2024-01-15T14:32:00Z",
"confirmation_id": "BANK_CONFIRMATION_123"
}
]
}
The tenant portal's JavaScript dashboard reads this file and displays the payment in the "Receipts" section of the hub in near real-time (with CloudFront cache considerations).
Google Apps Script Integration (GAS)
File: /repos/sites/queenofsandiego.com/WarmLeadResponder.gs
We added a secondary handler in the GAS command system that detects Zelle payment emails and triggers the logging action. This provides a backup pipeline if direct email forwarding isn't convenient.
The GAS script checks incoming emails for Zelle keywords and calls:
UrlFetchApp.fetch(lambdaUrl, {
method: "post",
headers: {
"Authorization": "Bearer " + adminToken,
"Content-Type": "application/json"
},
payload: JSON.stringify(paymentData)
});
Security Considerations
- Admin Token Validation: The
ADMIN_TOKENenvironment variable on both Lambdas ensures only authorized systems can log payments - Domain Isolation: All systems operate under
dangerouscentaur.com`, preventing credential/data leakage to other domains - Email Authentication: DKIM/SPF records for
dangerouscentaur.comprevent spoofing