Repository navigation
fix(workflows): keep an existing dmarc record when auto-configuring email dns - #109695
Conversation
…mail dns Cloudflare ignores Domain Connect TXT conflict matching, so applying the email template's dmarc group next to an existing _dmarc record adds a second DMARC record and receivers then ignore DMARC for the domain. The apply URL now includes the dmarc group only when DNS confirms that _dmarc has no DMARC record. An existing record or a failed lookup leaves the group out through the signed groupId parameter. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
😎 Merged successfully - details. |
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. 🧰 Additional context used📚 Code guidelines (6)No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository: PostHog/posthog/.coderabbit.yaml Review profile: QUIET Plan: Enterprise Run ID: 📒 Files selected for processing (2)
Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 10 remain after this review. 📝 WalkthroughWalkthroughEmail context resolution checks the sender domain for a DMARC TXT record and selects template groups based on the lookup result. It stores the selected group IDs in the context and passes them to apply URL generation. When group IDs are present, generated URLs include a comma-separated Priority: ➖ Normal Merge Risk: ⚪ Minimal · up to Confirmed DMARC absence still allows the DMARC template, while existing records and lookup failures exclude it without invalid TXT data blocking URL generation. No concrete current merge risk remains. Security Architecture ReviewSecurity architecture risk: 🔵 Low · up to The change conservatively excludes DMARC when an existing record is found or its lookup fails, and protects the selection when request signing is enabled. No introduced security regression was established. Actual provider enforcement and behavior when DNS changes between URL generation and application remain unverified. Retained concerns Security review detailsSecurity Blast Radius
Security Findings and Attack Paths
Trust Boundaries and Controls
Resilience and Maintainability Implications
Hardening Proposals
🚥 Pre-merge checks | ✅ 1✅ Passed checks (1 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to GitHub limitations.
🟡 Minor · Handle non-UTF-8 TXT values conservatively. · domain_connect.py:384
posthog/domain_connect.py:384
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick winHandle non-UTF-8 TXT values conservatively.
When
_txt_valueevaluates a non-UTF-8 TXT segment, it raisesUnicodeDecodeErroroutside_dmarc_absence_confirmed's error handling. The endpoint converts this to a validation error, so the process does not crash, but email apply URL generation stops instead of using the conservative non-DMARC fallback.Move the normalization into the
tryblock so decoding failures returnFalse, and add a regression test with a non-UTF-8 TXT value.Suggested fix
try: answers = dns.resolver.resolve(f"_dmarc.{domain}", "TXT", lifetime=5) + return not any(_txt_value(rdata).lower().startswith("v=dmarc1") for rdata in answers) except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer): return True except Exception: logger.warning("DMARC lookup failed for %s", domain, exc_info=True) return False - return not any(_txt_value(rdata).lower().startswith("v=dmarc1") for rdata in answers)
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository: PostHog/posthog/.coderabbit.yaml
Review profile: QUIET
Plan: Enterprise
Run ID: 51683b47-a7f2-4b9c-8ff5-76779f4ed518
📒 Files selected for processing (1)
posthog/domain_connect.py
Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 11 remain after this review.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
@coderabbitai Fixed in 3652b28: TXT parsing now runs inside the |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
ast-grep outline posthog/domain_connect.py --match 'dmarc|txt|resolve' --view expanded
ast-grep outline posthog/test/test_domain_connect.py --match 'test_email_resolver_variables_match_template' --view expanded
rg -n -C 20 'def _.*dmarc|def .*txt|_dmarc|UnicodeDecodeError' posthog/domain_connect.py
rg -n -C 35 'non.utf|\\xff|test_email_resolver_variables_match_template' posthog/test/test_domain_connect.pyLength of output: 7733 🏁 Script executed: #!/bin/bash
set -euo pipefail
sed -n '434,470p' posthog/test/test_domain_connect.pyLength of output: 1578
You are interacting with an AI system. |
mayteio
left a comment
There was a problem hiding this comment.
Nice! LGTM man, thanks 😄
Problem
_dmarcrecord is added next to the existing one.Changes
dmarcgroup only when DNS confirms that_dmarc.<sender domain>has no DMARC record.groupId=verification,dkim,spf,mailfrom, so the provider applies every other record.groupIdsits inside the signed query string, as the Domain Connect spec requires.Note
Cloudflare's docs do not list
groupIdamong the parameters it ignores, but a live Cloudflare apply was not run. If Cloudflare turns out to ignore it, the fallback is to hide auto-configure when_dmarcalready exists.How did you test this code?
Test rationale: two existing tests in
posthog/test/test_domain_connect.pywere extended rather than adding new ones.test_email_resolver_variables_match_templategains four parameterized DNS outcomes: no record, no answer, an existing record, a timeout. It catches the duplicate coming back, a lookup failure that fails open, and a template group rename thatgroupIdwould no longer match.test_url_with_signingnow verifies the signature over a query that carriesgroupId. It catchesgroupIdbeing appended after signing, which the provider would reject.Release status
Automatic notifications
Docs update
None. No doc under
docs/covers email domain setup.🤖 Agent context
Autonomy: Human-driven (agent-assisted)
Agent: Claude Code, Claude Opus 5.5 (1M context)
/writing-tests,/writing-code-comments,/reviewing-with-coderabbit,/writing-pr-descriptions.dmarc domain connect,groupId domain_connect) found no open PR.🤖 Generated with Claude Code