Knowledge base

process-x-dkim-options

<source>

Whether to read the X-DKIM-Options header and adjust the signature by it
in the configuration this is a lineprocess-x-dkim-options falseinside the block <source>
Signing settings set for a single message

The default is false. With the permission the engine takes values from the X-DKIM-Options header and signs the message with them — but only if signing is configured for this message at all. The header adjusts the signature, it does not enable it.

The header syntax resembles the tags of the signature itself, separated by semicolons. Chapter 10 lists what you can control:

Tag What it sets Condition
s the selector, the signature’s s= tag the declared key must have this selector
d the domain, the signature’s d= tag the key must have exactly this domain, an asterisk or a matching path in the vault
i the identity, the signature’s i= tag without d, the key must have the same domain or a parent one
q the query method, the q= tag —
key-list which list to take the key from the list must be declared

The point is to pick one key out of several declared ones. If a domain has two keys with different selectors, the header X-DKIM-Options: s=key2 names the second.

For the second signature this method does not work: the manual stipulates this separately. The second signature is configured only with directives.

Without the permission the header is ignored and, as the section says directly, stays in the message.

The main trap is that the header does not enable signing. It chooses among keys already declared. A message from a source that has no signing configured will go out unsigned regardless of what is in the header — and the header itself will travel to the recipient, showing them the names of your selectors.

The other edge of the same trap: the named selector must exist. A typo in the s tag is not “sign however it works out” but a mismatch with a condition the manual sets explicitly.

What the Hub does. It does not write it, that is, it leaves the vendor default false. The Hub lays out keys and selectors across nodes itself and signs by configuration: each “domain plus sending address” pair has its own key, named in its stream. There is no reason to hand the choice of key to the submitting side — it already submits under its own login, which corresponds to exactly one stream.

The practical consequence for us is different: if a submitting platform does set this header, the engine will neither read it nor remove it — the header will reach the recipient.

Recommended values

What to set. There is exactly one question — whether the submitting side chooses the key:

Value When
no (default) the configuration chooses the key — by stream, domain, list
yes a domain has several keys, and only the sender knows which one to take

The second case occurs with intermediaries that sign for many clients with those clients’ keys. There process-x-dkim-key is usually needed as well.

The false default and the caveat about the second signature come from the manual, § 3.3.7.45 and § 10.3.4. The breakdown of the header tags is from § 10.3.3. The “who to give it to” breakdown is ours.
Example configuration
# the header adjusts the signature only where signing is already configured
<source 10.0.0.0/24>
    process-x-dkim-options true</source>
A message from this subnet with the header “X-DKIM-Options: s=key2” will be signed with the domain’s second key. The key must be declared in advance — the header only names it.
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▶

Naming a selector that does not exist

§ 10.3.3

What it costsThe manual states the condition directly: the declared key must have the named selector. A mismatch is not “sign with a different key” but an unmet signing condition.
How to spot itMessages from the source with the permission go out unsigned, while the same messages without the header get signed.
How to do it rightCheck the selectors in the header against the list of declared keys and keep them consistent during rotation.

Expecting the header to configure the second signature

§ 10.3.4

What it costsThe manual stipulates separately: this method is not supported for the second signature. The second signature stays as the directives set it, and values from the header are not applied to it.
How to spot itThe first signature obeys the header, the second does not.
How to do it rightConfigure the second signature with directives prefixed second-, and adjust only the first one through the header.

Leaving the permission off and forgetting about the header

§ 3.3.7.45

What it costsWithout the permission the engine ignores the header — and, as the section says directly, leaves it in the message. The names of your selectors travel to the recipient for no reason.
How to spot itX-DKIM-Options is visible in the delivered message.
How to do it rightEither grant the permission or remove the header on the submitting side. A third way is to strip it with the remove-header directive on the source.
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.
Reference data
Syntax
process-x-dkim-options <boolean>
Values
yes | no | true | false
Default
false § 3.3.7.45
Applying
reload, no restart needed
Queue
will not touch what is already queued
Where to write it
<source>
How many times
once in the block
Everything here comes from the manual, with the section.
Inheritance
The directive lives in <source> and follows source merging: a connection falls under all address blocks that cover it, and a narrow one overrides a broad one. For submission under a login the named block applies, and the line has to be repeated in it — we did not see inheritance from address blocks into a named one on our installation.
How to check on the node
The permission is visible in the configuration; the declared keys are right next to it, and without them the permission is meaningless:
grep -n 'process-x-dkim-options\|domain-key' /etc/pmta/config /etc/pmta/virtualhost.txt
If the permission line is there but there are no declared keys, the header will do nothing. Whether the choice worked is visible from the s= tag in the signature of a delivered message.
In the Hub
Cost of a mistake
reversible: harms only while it is set
Scenarios
Message signing and authentication