Knowledge base

process-x-dkim-key

<source>critical

Whether to read the private signing key from a message header
in the configuration this is a lineprocess-x-dkim-key falseinside the block <source>
A permission that decides whether the key leaks

The default is false. With the permission the engine extracts a private key in PEM format from the X-DKIM-Key header, signs the message with it and strips the header before sending.

One permission is not enough. A selector is needed — it is passed in a separate X-DKIM-Options header, which means a permission for it is needed too: process-x-dkim-options. It never takes fewer than two lines.

Next comes the part that makes this page worth reading to the end. The manual says directly: if the permission is not set, the engine does not remove the header, — and advises checking your installation so that private keys do not leak. That is, the absence of the permission does not protect: it does exactly the opposite and leaves the key in the message.

The neighboring section about retaining the same header says the opposite: with both directives false, the header is supposedly stripped anyway. Follow the manual’s own advice — check.

The main trap is that “not enabled” does not mean “safe” here. The permission is off by default, and people usually stop there. But per § 3.3.7.46, it is precisely the disabled permission that leaves the header in the message — with the private key inside.

Most dangerous is a combination that is easy to arrive at without any ill intent: the submitting platform can pass the key in the message, someone enabled that on its side, and the permission is not set on the node. The key travels the whole way and reaches the recipient.

And the second half: even with the permission enabled, the key travels to the node inside the message — through the submitting side’s queues, its logs, intermediate storage. Stripping the header protects the recipient, not that path.

What the Hub does. It neither writes nor uses it: the Hub keeps signing keys on its side and distributes them across nodes itself, and in the node configuration it names them with the key directive on the right stream. Passing a private key in a message is the opposite of this design.

It is still worth checking whether such a header arrives from submitting platforms: without the permission, by the letter of § 3.3.7.46, the engine will not strip it.

Recommended values

What to set. Both sides of the choice are unpleasant, and that is normal for a directive like this:

Value When
no (default) keys are declared in the configuration — the usual case, ours included
yes an intermediary signs for many clients with their own keys, and all the keys cannot be kept on the node

The second case is justified only where the entire path from the submitting application to the node is fully yours. Through someone else’s network, through an intermediate relay, through a shared queue — no.

Whatever you choose, retain-x-dkim-key must stay false.

The false default, the selector requirement and the warning about the header not being removed come from the manual, § 3.3.7.46. The breakdown of cases is ours.
Example configuration
# without the second line the key is useless: the selector arrives in a separate header
<source 10.0.0.0/24>
    process-x-dkim-key true    process-x-dkim-options true
</source>
The message must carry both headers: one with the key in PEM format, the other with the selector. Both permissions are needed too — neither works on its own.
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▶

Treating the disabled permission as protection

§ 3.3.7.46

What it costsBy the letter of the section it is the other way around: without the permission the engine does not remove the header, and the private key travels to the recipient. It is no accident that the manual advises checking the installation here — this is the only place in the chapter where such advice is given at all.
How to spot itA message that reached the seed mailbox shows X-DKIM-Key.
How to do it rightCheck how your engine version behaves on your own mailbox. Regardless of the result, do not let submitting platforms pass keys in messages.

Enabling the permission without the permission for signing options

§ 3.3.7.46

What it costsThe selector is passed in another header, and without a permission for it there is nothing to sign the message with. Meanwhile the key has already traveled all the way to the node — in vain and at risk.
How to spot itMessages with a key in the header leave unsigned.
How to do it rightGrant both permissions as one pair of lines and in one block.

Granting the permission to a wide block

our experience

What it costsAnyone who can submit a message gets the right to sign it with an arbitrary key. Your node appears as the signing party, and it is your domain that will have to deal with the receiving servers.
How to spot itThe permission is in the 0/0 block or in a block with a whole network.
How to do it rightGrant it only to a specific submission address and only where the path to the node is entirely yours.
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-key <boolean>
Values
yes | no | true | false
Default
false § 3.3.7.46
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 obeys source merging: a connection falls under all the address blocks that cover it, and the narrow one overrides the wide one. Here this rule has a price of its own: a permission granted in the 0/0 block goes to everyone who can submit a message — that is, the right to sign in your name with an arbitrary key.
How to check on the node
Permissions are checked in the configuration, a leak in a delivered message:
grep -n 'process-x-dkim-key\|retain-x-dkim-key' /etc/pmta/config /etc/pmta/virtualhost.txt
No lines means the vendor default, not safety: per § 3.3.7.46 it is precisely with the permission off that the header stays in the message. There is only one real check — send a message with such a header to your own mailbox and see whether the key arrived.
In the Hub
Cost of a mistake
dangerous: effects outlast a rollback
Scenarios
Message signing and authentication · Node security
Priority
critical