Skip to content

DMARCbis: remove pct sampling, add t tag support (RFC 9989) #366

Description

@thegushi

RFC 9989 removes the pct tag entirely (now marked historic in the IANA registry) and replaces it with a binary t (testing) tag:

  • t=y -- testing/monitoring mode; analogous to the old pct=0. Receivers should apply monitoring but not enforce policy.
  • t=n (or absent) -- full enforcement; analogous to the old pct=100.

The rationale (RFC 9989 Appendix A.6) is that intermediate pct values were implemented inconsistently across receivers and rarely applied correctly in practice. RFC 9989 explicitly notes that only pct=0 and pct=100 were ever reliably implemented.

Backward compatibility with pct=

OpenDMARC will still parse pct= when present in a DMARC record, but:

  • pct=0 -> treated as t=y (monitoring only, no enforcement)
  • pct=100 -> treated as t=n (full enforcement; no behavior change)
  • pct=1-99 -> discarded; treat as full enforcement (t=n)
  • t= takes precedence over pct= when both are present

This means domain owners running pct=1-99 with p=reject or p=quarantine will see full enforcement from OpenDMARC once this is implemented. Per RFC 9989, those values were already being applied inconsistently across the ecosystem.

Required changes

Filter (opendmarc.c):

  • Remove the random() % 100 < pct sampling blocks in the DMARC_POLICY_REJECT and DMARC_POLICY_QUARANTINE cases
  • Parse and honor the t tag: when t=y, skip enforcement regardless of p= value (treat as monitoring-only)
  • Map pct=0 -> t=y during the transition

Library (libopendmarc):

  • opendmarc_policy_query_dmarc() needs to parse the t= tag from the DNS record and expose it via a new accessor (or extend an existing one)
  • Continue parsing pct= but normalize it to the two meaningful values (0 and 100) before exposing it; discard 1-99

Aggregate reports (opendmarc-reports.in):

  • RFC 9990 <policy_published> block: replace <pct> element with whatever RFC 9990 specifies for the t tag

Related

  • RFC 9989 Appendix A.6 (removal rationale)
  • Supersedes the old pct handling throughout the codebase

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions