DKIM overview
A receiving server sees only the domains that a message claims to come from, and claims are easy to forge. DomainKeys Identified Mail (DKIM), defined in RFC 6376, lets a domain take responsibility for the messages sent in its name, in a way that receivers can check. The sending server signs the message body and a selected set of header fields with a private key, and it adds the signature to the message in a DKIM-Signature header. Receiving servers retrieve the matching public key from DNS. With that key, they confirm that the signed content has not been modified in transit.
Stalwart takes part in DKIM on both sides. It signs the messages its users send, and it verifies the signatures on the messages it receives. For domains that use automatic key management, Stalwart also generates the signing keys, publishes them in DNS and replaces them on a schedule.
Signatures, selectors and alignment
Section titled “Signatures, selectors and alignment”Two tags of the DKIM-Signature header identify the key that produced the signature. The d= tag names the signing domain, and the s= tag names a selector. The receiving server combines the two and looks up the public key in the TXT record at <selector>._domainkey.<domain>. Because each key has its own selector, a domain can publish several keys at the same time, for example one per algorithm, or an old and a new key during a key change. The following header is an abbreviated example:
DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=example.com; s=v1-ed25519-20260101; h=From:To:Date:Subject:Message-ID; bh=<body hash>; b=<signature>The signature covers a hash of the body, in the bh= tag, and the header fields listed in h=. Before hashing, both are canonicalised, as the c= tag states. Canonicalisation is a normalisation step: it makes the signature tolerant of the whitespace and line-folding changes that intermediate servers commonly apply. A signature that verifies establishes two things: that the domain in d= signed the message, and that the signed content is unchanged.
A valid signature does not by itself establish that the From address is authentic, because any domain can sign any message. Domain-based Message Authentication, Reporting and Conformance (DMARC), the policy mechanism that receivers apply to the From domain, makes this connection. A DKIM result counts towards DMARC only when the d= domain aligns with the From domain. A message signed by an unrelated domain therefore fails DMARC even though its signature verifies.
Algorithms
Section titled “Algorithms”Stalwart signs with Ed25519 (RFC 8463) and with RSA, both combined with SHA-256. Ed25519 keys are short and fast to verify, but not every receiving server supports them. For this reason, automatic key management creates one key of each type by default, Dkim1Ed25519Sha256 and Dkim1RsaSha256, and each outgoing message carries two signatures. A receiver that does not support Ed25519 ignores that signature and verifies the RSA signature instead. Generated RSA keys are 2048 bits long. RSA-SHA1 is not available for signing, because RFC 8301 declares it obsolete.
Signing outgoing mail
Section titled “Signing outgoing mail”The domain that signs a message is determined by the dkimSignDomain setting of MtaStageData (found in the WebUI under Settings › MTA › Session › DATA Stage). The setting is an expression, a rule that Stalwart evaluates for each message using variables such as the sender’s domain and the authenticated account. When the expression returns a domain name, Stalwart signs the message with every active key of that domain. When it returns false, the message is not signed.
The default expression signs a message only when the sender has authenticated and the sender’s domain is hosted on the server. Messages relayed on behalf of other systems, and messages submitted without authentication, are therefore sent unsigned. To sign these messages as well, adjust the expression as described in Signing. Messages that Stalwart generates itself, such as reports, delivery status notifications and messages sent by Sieve scripts, are not covered by this expression, because each kind has a dkimSignDomain setting of its own.
Verifying incoming mail
Section titled “Verifying incoming mail”Verification of inbound signatures is controlled by the dkimVerify setting of SenderAuth (found in the WebUI under Settings › MTA › Inbound › Sender Authentication). It accepts one of three values and is relaxed by default:
relaxed: verify the signatures and record the result in theAuthentication-Resultsheader.strict: reject the message unless at least one signature verifies, which also rejects unsigned messages.disable: skip verification.
The verification result also feeds the DMARC check and the spam filter. Some signatures are ignored, however. The l= tag limits a signature to the first part of the body, so content appended after the signed part would not invalidate it. Signatures that use this tag are therefore ignored while dkimStrict is enabled, as it is by default. Verifying describes both settings.
Signing keys
Section titled “Signing keys”Each signing key is stored as a DkimSignature (found in the WebUI under Management › Domains › DKIM Signatures) that belongs to a Domain. The dkimManagement setting of the domain decides who maintains the keys: Stalwart or the administrator.
With Automatic management, Stalwart creates a key for each algorithm listed in algorithms, by default Dkim1Ed25519Sha256 and Dkim1RsaSha256. What happens next depends on whether the domain also uses automatic DNS management. When it does, Stalwart publishes each public key before signing with it, and replaces the keys on a schedule, as described in DKIM key rotation. When it does not, the keys sign at once but are neither published nor rotated. Signatures then fail verification until the TXT records listed in the domain’s dnsZoneFile field are added to the zone by hand.
With Manual management, the administrator creates each DkimSignature, supplies the private key and publishes the DNS record, as described in Signing. Manual management suits a key that must be shared with another sending system or kept in an external secret store.
DKIM2 is a successor to DKIM. It extends the signature to the SMTP envelope and links the signatures added at each hop into a chain. A receiver can use the chain to determine which hop modified a message, and whether the message was delivered to the recipients it was originally addressed to. DKIM2 also requires the domain of the From header field to be the signing domain or a subdomain of it.
Stalwart signs and verifies DKIM2 alongside DKIM, with the same dkimSignDomain expression. DKIM2 keys are DkimSignature objects of type Dkim2RsaSha256, Dkim2Ed25519Sha256 or Dkim2MlDsa44, the last the post-quantum ML-DSA-44 algorithm. Automatic key management creates DKIM2 keys only when these types are added to algorithms. DKIM2 describes signing and verification, and the specification defines the protocol.