cbowofrivia/dmarc-record-builder
A PHP package for building DMARC TXT records programmatically. Configure policy, subdomain policy, alignment, reporting addresses and percentage, then generate a valid DMARC record string for your DNS zone.
webmozart/assert, illuminate/collections), so adopting it no longer pins us to a Laravel major or pulls transitive packages — it can live in any PHP 8.3+ service, including non-Laravel ones.pct and ri. v4 is standards-current. This forces a product decision: if our UI/API currently exposes pct or interval to customers, we must decide now whether to remove those controls, keep them and pin v3, or wrap the library to keep emitting legacy tags.pct is how most organizations ramp from p=none to p=reject safely. v4 cannot express it. That's a real capability gap for the next 12–24 months of DMARCbis transition, and it should be scoped explicitly rather than absorbed silently.parse() now treats pct/ri as unknown tags and drops them on re-cast. Any flow that reads a customer record, edits it, and republishes will silently erase their staged rollout. This needs a product guard (preserve original string, or block edit-rewrite until DMARCbis readiness is decided).Consider adopting (or upgrading) when:
rua/ruf, bad policy values, malformed addresses).Look elsewhere, or deliberately stay on v3, when:
pct/ri for phased enforcement. v4 cannot express them, and dropping them changes customer-facing behavior.Executives: This is a small, single-purpose library that removes a maintenance liability. v4 has zero runtime dependencies — it no longer pins us to a Laravel version or drags in transitive packages, which is one less item in supply-chain review and one less blocker at framework upgrade time. It also puts us ahead of DMARCbis (RFC 9989), the standards revision that retires the pct and ri tags. The upgrade cost is bounded and mechanical: PHP 8.3, delete pct()/interval() calls, adjust one catch block. Generated records are otherwise unchanged.
Engineering: v4 is a clean break but a shallow one. The API surface we depend on — builder, create(), parse(), validation — is intact apart from pct()/interval(), which are gone along with their constructor/create() arguments and $record->pct/$record->interval properties. Validation now throws CbowOfRivia\DmarcRecordBuilder\Exceptions\InvalidDmarcRecordException, which extends \InvalidArgumentException with unchanged messages — so catching \InvalidArgumentException is a no-op migration; only code catching Webmozart\Assert\InvalidArgumentException by name needs editing. PHP 8.3 is the new floor and CI covers 8.3–8.5. One design caveat to handle deliberately: parse() now drops pct/ri on re-cast, so any read-edit-rewrite path will strip a customer's staged enforcement — preserve the original record string or gate that flow until we settle the DMARCbis posture.
How can I help you explore Laravel packages today?