Repository navigation
feat(infra): send Cognito mail from no-reply@branchaccounting.org - #419
Merged
Merged
Conversation
us-east-2 was granted SES production access (case 179201951700548) and the branchaccounting.org identity reads DKIM and MAIL FROM Verified, so flip enable_ses_email. Cognito switches from COGNITO_DEFAULT (shared no-reply@verificationemail.com, 50/day, unauthenticated for our domain) to DEVELOPER mode sending as "BRANCH <no-reply@branchaccounting.org>", which is DKIM-signed and DMARC-aligned. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Auto-formatted .tf files with terraform fmt - Updated README.md with terraform-docs Co-authored-by: nourshoreibah <nourshoreibah@users.noreply.github.com>
nourshoreibah
marked this pull request as ready for review
October 17, 2026 11:32
mailer.ts sends approve/deny notices from process.env.SES_FROM_ADDRESS, which
no Terraform ever set, so it fell back to no-reply@branch.org. SES rejected
every send ("Email address is not verified ... no-reply@branch.org", seen in
branch-expenditures logs on 2026-10-15) and the handler's try/catch swallowed
it, so submitters never got a notice. Point it at the same verified
"BRANCH <no-reply@branchaccounting.org>" sender Cognito now uses.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
Terraform Plan 📖
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Flips
enable_ses_emailtotrue. Cognito'semail_configurationchanges fromCOGNITO_DEFAULT(sharedno-reply@verificationemail.com, capped at 50 a day, can't authenticate for our domain, so mail lands in spam) toDEVELOPERmode sending asBRANCH <no-reply@branchaccounting.org>through our SES identity.Preconditions (verified 2026-10-17, account 404813129370, us-east-2)
GRANTED(case 179201951700548), 50k/day, 14/sbranchaccounting.orgidentitySUCCESS(Easy DKIM), MAIL FROMmail.branchaccounting.orgSUCCESSBOUNCE,COMPLAINTDEVELOPERmode sends through theAWSServiceRoleForAmazonCognitoIdpservice-linked role. It doesn't exist yet: Cognito creates it during the apply, usingbranch-ci-apply(admin, so it hasiam:CreateServiceLinkedRole). No SES identity policy is needed; that's only forCOGNITO_DEFAULTwith a custom From address. (AWS docs)Compliance (internal, transactional-only tool)
include:amazonses.com) on the apex andmail., DKIM signedd=branchaccounting.org, DMARC published (p=none). Both DKIM and SPF (through themail.subdomain, relaxed) align with the From domain, which covers the Gmail/Yahoo/Microsoft bulk-sender rules even though we're far below their 5,000/day threshold.Also: expense approve/deny emails (
SES_FROM_ADDRESS)The expenditures lambda emails the submitter when an expense is approved or denied (
apps/backend/lambdas/expenditures/mailer.ts, sent directly through SES, not Cognito). It reads its sender fromSES_FROM_ADDRESS, which Terraform never set, so it fell back tono-reply@branch.org. Every send failed, and the handler's try/catch swallowed the error. Frombranch-expenditureslogs, 2026-10-15:The recipient half was the sandbox, which production access fixed. The sender half is fixed here:
lambda.tfsetsSES_FROM_ADDRESS = "BRANCH <no-reply@branchaccounting.org>"on all six functions (the env block is shared; preview stacks copy it). The lambda role already hasses:SendEmail. No code change or lambda redeploy needed: the apply updates the env and the next invocation picks it up.Plan should show
Plan: 1 to add, 7 to change, 0 to destroy:aws_ses_domain_identity_verification.app[0]created,aws_cognito_user_pool.branch_user_pool(email_configuration) and the sixaws_lambda_function.functions[*](+ SES_FROM_ADDRESS) updated in place.After merge
Approve the
terraform-applyrun, then send a test invite or password reset and approve or deny a test expense, and confirm both emails arrive fromBRANCH <no-reply@branchaccounting.org>and the headers showdkim=pass,spf=pass,dmarc=pass.🤖 Generated with Claude Code