Knowledge base

How the node signs messages and chooses a key

critical

DKIM key selection
The key is chosen by the message, not by a setting

Signing is enabled with a dkim-sign line for the receiver, while the key is chosen by the message itself. The node looks at the sending domain — taking it from the Sender header, or from From if there is none — and looks for a matching key among the domain-key declarations.

The search goes from top to bottom, and the first match wins. A declaration matches if its domain equals the sending domain or is its parent: a key for example.com will sign messages from mail.example.com; the reverse is not true.

Stream keys are stronger than general ones. If matching declarations exist both at the node level and inside a VirtualMTA, the ones inside win.

If none is found, the message leaves unsigned. Silently: no error, no log entry.

The main trap is an asterisk above specific declarations. A declaration with the * domain fits any message, and the search goes from top to bottom — so it will also intercept messages for which an exact key lies further down. The manual explicitly advises keeping the asterisk last.
What the Hub does. It manages keys on the domain card in the “DNS → Domains and zones” section, publishes the records and distributes the declarations across the nodes. The Hub arranges the order of declarations itself — exact domains higher, the asterisk lower — so no interception happens.
Example configuration
# exact domains higher, the asterisk last — otherwise it intercepts everything
domain-key m, mail.port25.com, /etc/pmta/m.pem
domain-key k1, example.org, /etc/pmta/k1.example.org.pem
domain-key base, *, /etc/pmta/base.pem
<domain *>
    dkim-sign yes
</domain>
Swap the lines — and the highlighted one will sign everything with its key, while the two exact declarations will never run even once.
yellow — — directive names, blue — blocks. They are highlighted the same way in the text of the card.
▲

Common mistakes and problems

what people get wrong and how it ends3 mistakes▶

Putting the asterisk declaration first

§ 3.3.1.55.1

What it costsIt fits any message, and the search goes from top to bottom. All the exact declarations below never run even once, and all mail is signed with one key.
How to spot itAll messages have the same selector in the signature header.
How to do it rightKeep the asterisk last — that is exactly what the manual advises.

Creating a key for a subdomain and expecting it to sign the parent

§ 3.3.1.55.1

What it costsMatching goes one way: a declaration for example.com fits messages from mail.example.com, but not the other way around. Messages from the parent domain are left without a key.
How to spot itSome messages are not signed, even though the key exists.
How to do it rightRegister the key on the signing domain or on its parent.

Assuming the signing domain is the receiver's domain

our experience

What it costsThe key is looked up by the sending domain from the message headers, while dkim-sign is set for the receiver. If you configure the key by receiver, you will not find a match for a single message.
How to spot itSigning is enabled for all receivers, yet there are no signed messages.
How to do it rightThe key goes on the domain from Sender or From, enabling goes on the receiver.
Compatibility
PowerMTA 6.0
described in the manual of this version · platform: any
The vendor does not state the first version for every directive — there is no note here. The name also appears in the 5.0 edition of the manual.
How to check on the node
Which key a message got shows in its signature header — the selector and the domain are right there:
dig +short TXT k1._domainkey.example.org
grep -i 'DKIM-Signature' /var/log/pmta/pmta.log | tail -5
In the signature header the selector is in the s= field and the domain in d=: that is how you check whether the right declaration won. The Hub arranges the order of declarations itself.
In the Hub
Cost of a mistake
reversible: harms only while it is set
Scenarios
Key rotation · Message signing and authentication
Priority
critical