Sorry for the delay in replying.  Response inline below.

On Fri, May 29, 2026 at 7:23 AM Tobias Herkula <tobias.herkula=
[email protected]> wrote:

> Hey Wei,
>
> I remember a discussion were someone also wanted to assert ADMD boundaries
> and after reading your proposal and also re-reading Richards, I would like
> to propose a third way of solving the issue at hand (i.e. enablement of
> multi-hop in same ADMD signing for forwarders and single-hop multi-signing
> for differentiation between brands and sender infrastructures) and also
> provide a way to cryptographically assert ADMD boundaries itself.
>
> A DKIM2 signature i=n could explicitly assert the signing domain expected
> to produce DKIM2 signature i=n+1. Alternatively, a DKIM2 signature i=n
> could explicitly assert the signing domain of DKIM2 signature i=n-1 as the
> domain it continues from. In both cases, the assertion MUST be covered by
> the DKIM2 signature instance that makes it and therefore protected against
> modification.
>
>
>    - If DKIM2 signature i=n asserts the signing domain of DKIM2 signature
>    i=n+1, DKIM2 signature i=n+1 may omit the mf and rt fields and inherit
>    their effective values from DKIM2 signature i=n.
>    - If DKIM2 signature i=n asserts the signing domain of DKIM2 signature
>    i=n-1, DKIM2 signature i=n-1 may omit the mf and rt fields and inherit
>    their effective values from DKIM2 signature i=n.
>
>
A risk is an adversary trying to hide from the RCPT TO and MAIL FROM
check.  To prevent, I think i=n-1 approach is probably better. It also
means less walking for the verifier.

I see you are using "nd=" to define the relationship within an ADMD in a
forwarding i.e. i=n to i=n+1 direction.  I think this is doable.  The risk
is an adversary claiming a relationship with a prior ADMD, which I think
this covers, though others should opine if there is any risk here.  This is
similar to Richard's proposal except it uses an explicit new tag "nd=" for
the within the ADMD relation.

A relationship between two DKIM2 signature instances MUST be asserted in
> exactly one direction. If both signature instances assert the same
> relationship, the relationship is invalid. This keeps the chain of custody
> unambiguous and reduces replay opportunities by ensuring that each link has
> exactly one authoritative assertion. This can be repeated across multiple
> DKIM2 signature instances, creating a chain of signed relationships between
> consecutive signing domains. If either mf or rt changes between DKIM2
> signature instances, the DKIM2 signature instance reflecting the change
> MUST explicitly assert the new value. Omission is only valid when the
> effective values remain unchanged. A receiver remains free to apply local
> policy when evaluating a relationship assertion that directly references
> the receiver's DKIM2 signature instance, or when inheriting omitted mf or
> rt values from the immediately related DKIM2 signature instance. If the
> receiver does not accept such a relationship or inheritance, the DKIM2
> chain MUST be treated as invalid.
>
> The examples are always from the perspective of the next entity that would
> add a new instance of the signature header.
>
> *Bulk Sender Example (simple)*
> Simple if I'm the hop after i=2 it's easy to understand that i=2 was
> authorized by i=1 to send this and a possible rejection later in this chain
> would go back to [email protected]
>
> DKIM2-signature: i=2 d=esp.example
> DKIM2-signature: i=1 d=brand.example [email protected]
> [email protected] nd=esp.example
> From: [email protected]
> To: [email protected]
>
>
> *Bulk Sender Example (extended)*
> Also simple same result as before. I=1 and i=2 asserted the next hops and
> I'm as theoretic i=4 am mbp.example and ca deliver that message fine
>
> DKIM2-signature: i=3 d=esp.example
> DKIM2-signature: i=2 d=agency.example nd=esp.example
> DKIM2-signature: i=1 d=brand.example [email protected]
> [email protected] nd=agency.example
> From: [email protected]
> To: [email protected]
>
>
> *Enterprise example from a Bulk Mailer with Forwarding and an SEG*
> The enterpise example also works fine, i=4 can easily validate the chain
> and gets the mail from [email protected] and i=5 then allows the
> un-aligned domain change afterwards by asserting the last hop. If I'm now
> somewhere later in the chain this works out,
>
> DKIM2-signature: i=5 d=enterprise.example [email protected]
> [email protected] ld=security.example
> DKIM2-signature: i=4 d=security.example [email protected]
> [email protected]
> DKIM2-signature: i=3 d=esp.example
> DKIM2-signature: i=2 d=agency.example nd=esp.example
> DKIM2-signature: i=1 d=brand.example [email protected]
>  [email protected] nd=agency.example
> From: [email protected]
> To: [email protected]
>
>
> This approach effectively reduces header clutter while remaining simple to
> understand and implement. The relationship between signature instances is
> explicit and easy for both humans and machines to parse. Expressing
> multiple signing domains within the same construct introduces additional
> complexity, as a signature is no longer associated with a single signing
> domain and additional semantics are required to describe the relationship
> between domains. The proposed approach keeps that relationship explicit. My
> late reply to this comes from the time I tried to find a way to abuse this
> explicitly, I'm aware that any attacker could add hops with assertions, but
> this is the whole idea, if an attackers asserts the previous hop, he takes
> ownership and will be punished for spam, and if an attacker asserts the
> next hop a receiver can easily decide to not accept the message if he is
> not aware of such a relationship.
>
> --
>
> Best regards,
> Tobias Herkula
>
>

PS: a correction in my example.  My Section 11.1 cited below is
accidentally from the -08 draft.  It should really be the latest -02 draft
which is Section 8.1
<https://datatracker.ietf.org/doc/html/draft-ietf-dkim-dkim2-spec-02#name-add-any-necessary-message-i>
.
-Wei


> ------------------------------
> *From:* Wei Chuang <[email protected]>
> *Sent:* 26 May 2026 21:39
> *To:* [email protected] <[email protected]>
> *Subject:* [Ietf-dkim] DKIM2 Multiple Domain Signatures Proposal
>
>
> One problem we've observed in the current DKIM2 proposal is that the
> synthetic headers described in *Section 11.1*
> <https://www.ietf.org/archive/id/draft-clayton-dkim2-spec-08.html#name-add-any-necessary-message-i>
>  imply
> SMTP boundaries where non-existed.  These are needed for enterprise or bulk
> sender flows to maintain the chain of custody with the added synthetic
> headers used to link together the mf= and rt= tag with the headers
> representing actual ADMD boundaries.  While they are easily generated and
> verified, other systems interpreting them may be confused such as NDR
> bounce handling, and seem to be an unnecessary artifact of the protocol.
> Can we find an approach that does not require these synthetic headers?
>
> First what are those synthetic headers:
> Enterprise Forwarding Problem
>
> Broken forwarding because the chain of custody is not maintained through
> the mf= and rt=:
>
> From: orig@orig
>
> DKIM2-signature: i=1; d=orig; mf=orig@orig; rt=recv@recv
>
> DKIM2-signature: i=2; d=forw; mf=forw@forw; rt=dest@dest
>
> "Fixed" by adding a i=2 synthetic DKIM2 signatures as described in *Section
> 11.1*
> <https://www.ietf.org/archive/id/draft-clayton-dkim2-spec-08.html#name-add-any-necessary-message-i>
>  to
> link mf= and rt=.
>
> From: orig@orig
>
> DKIM2-signature: i=1; d=orig; mf=orig@orig; rt=recv@recv
>
> DKIM2-signature: i=2; d=recv; mf=recv@recv; rt=forw@forw
>
> DKIM2-signature: i=3; d=forw; mf=forw@forw; rt=dest@dest
>
> Further the bulk sender pattern implies a synthetic email address where
> non-existed before.
> Proposed Multiple Domain Signatures
>
> Instead let's collapse the synthetic header into the header generated at
> the ADMD boundary.  We can do this by moving the domain d= into the
> signature s= and skip generating the synthetic header.  If we do this, it
> implies a set of changes in the DKIM2 signature and chain of custody
> algorithm.
>
>    -
>
>    Move d= domain into the s= signature and drop d=
>    -
>
>       Each of these signatures signs for the same hash but varies by
>       signing algorithms or private keys
>       -
>
>    "d=domain; s=selector:rsa-sha256:sigdata" => "s=domain
>    :selector:rsa-sha256:sigdata"
>    -
>
>       For a given DKIM2 signature header, defines a set of valid domains
>       D across all signature selectors and algorithms
>
>
> Modified chain of custody algorithm
>
>    -
>
>    For the i= instance number of DKIM2 signature header, there is an
>    origination i=1 and the highest numbered i=n.  These instance numbers of
>    DKIM2 signatures form a continuous sequence of 1..n without skips.
>    -
>
>    For each DKIM2 signature header i=m in 1..n
>    -
>
>       mf= domain is DMARC aligned with a domain in the set of DKIM2
>       signatures D
>       -
>
>    For each DKIM2 signature header i=m in 1..n-1
>    -
>
>       rt= domain is DMARC aligned with a domain in the set of member of
>       DKIM2 signatures D at i=m+1
>       -
>
>    For the DKIM2 signature header at i=n, the receiver checks
>    -
>
>       rt= address must be an exact match to the address of RCPT TO
>       -
>
>       mf= address must be an exact match to the address of MAIL FROM
>       -
>
>       Receiver accepts delivery for RCPT TO address (effectively i=n+1)
>       -
>
>    For a given DKIM2 signature header, if there is more than one
>    signature provided then they MUST all be checked if the verifier is able to
>    do so.
>    -
>
>       If any signature fails then an error SHOULD be reported
>       -
>
>       If more than two domains are present then an error SHOULD be
>       reported
>       -
>
>       The verifier SHOULD check at least 6 signatures (or some TBD
>       reasonable number) in a DKIM2 signature header.  Six is supposed to 
> support
>       three algorithms with either the enterprise or bulk sender use case.  
> This
>       is to support some hypothesized new PQC algorithms that haven't been
>       selected but likely to happen.  This is in addition to rsa-sha256 and
>       ed25519-sha256 algorithms already specified.
>       -
>
>       Each domain must have at least one passing signature, with
>       non-passing results only permitted for unknown algorithms.
>
> Usage
>
> There are scenarios where we want multiple signatures to be associated
> with a given ADMD that can map to a single DKIM2 signature header.  Three
> cases:
>
>    -
>
>    Different algorithms
>    -
>
>    Forwarder with different receiver and sending domains that occurs with
>    enterprise flows
>    -
>
>    Bulk senders with multiple signatures to get feedback reports
>
>
> #1 Different Algorithms
>
> From: orig@orig
>
> DKIM2-signature: i=1; s=orig::rsa-sha256:; s=orig::ed25519-sha256:;
> mf=orig@orig; rt=recv@recv
>
> #2 Enterprise forwarding
>
> From: orig@orig
>
> DKIM2-signature: i=1; s=orig:::; mf=orig@orig; rt=recv@recv
>
> DKIM2-signature: i=2; s=forw:::; s=recv:::; mf=forw@forw; rt=dest@dest
>
> #3 Bulk sender multiple signers
>
> From: brand@brand
>
> DKIM2-signature: i=1; s=brand::; s=platform:::; mf=platform@platform;
> rt=recv@recv
>
> In this bulk sender case, the platform i.e. bulk sender may wish to handle
> bounces on behalf of the brand.
> Security Discussion
>
> This approach still demonstrates to receivers that the forwarder actually
> handled the message by signing the message.  A subsequent receiver can
> validate the signatures, and checks for domain alignment using the above
> process.
> Alternative Approach
>
> Richard Clayton proposes a different approach to identify synthetic
> headers and addresses without the large changes above.  This would keep the
> synthetic headers generated in *Section 11.1*
> <https://www.ietf.org/archive/id/draft-clayton-dkim2-spec-08.html#name-add-any-necessary-message-i>.
> To paraphrase him, hopefully correctly, he proposes that the synthetic
> forwarder addresses in the synthetic headers not specify a local-part.  The
> chain of custody tag matching of mf= and rt= would check for domain
> alignment only.  The examples below illustrate how they might look.  Note
> the synthetic headers with missing the local-parts are designated as
> @domain.
>
> #1 Different Algorithms
>
> From: orig@orig
>
> DKIM2-signature: i=1; d=orig; s=::rsa-sha256:; s=::ed25519-sha256:;
> mf=orig@orig; rt=recv@recv
>
> #2 Enterprise forwarding
>
> From: orig@orig
>
> DKIM2-signature: i=1; d=orig;   mf=orig@orig; rt=recv@recv
>
> DKIM2-signature: i=2; d=recv;  mf=recv@recv; rt=@forw
>
> DKIM2-signature: i=3; d=forw;  mf=forw@forw; rt=dest@dest
>
> #3 Bulk sender multiple signers
>
> From: brand@brand
>
> DKIM2-signature: i=1; d=brand;      mf=brand@brand; rt=@platform
> DKIM2-signature: i=2; d=platform;  mf=platform@platform; rt=recv@recv
>
> Thanks,
> -Wei
>
_______________________________________________
Ietf-dkim mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to