35. pepsi-stage-dkim-sign¶
Prepend DKIM signatures before delivery.
35.1. Role¶
pepsi-stage-dkim-sign DKIM-signs the message and advances it to a delivery
stage. Separating signing from message construction lets
pepsi-stage-bounce build an unsigned DSN and point its NEXT_STAGE
here, so a generated bounce is signed before it is sent. Reference:
pepsi-stage-dkim-sign(1).
35.2. Features¶
Dual-signature DKIM (RFC 6376): prepends both an RSA-2048 and an Ed25519 (RFC 8463)
DKIM-Signatureheader by default;[pepsi] DKIM_ALGORITHMSnarrows that to one (the largest receivers do not verify Ed25519 and report it asfailin DMARC aggregate reports).Signing domain selection:
SIGNING_DOMAINif set, otherwise the domain of the message’sFrom:header.Full body coverage, always: RFC 6376’s
l=body-length tag is never emitted and cannot be configured. Strict verifiers (mail-auth, Stalwart, and Pepsi’s own) reject anl > 0signature outright, and RFC 6376 §8.2 warns that appended content can replace the original in the reader’s eyes.Prepend-only / single write: signatures are added at the top, so existing signatures lower in the message are undisturbed; only the
headerscolumn is rewritten.Fail-closed: a message is never advanced unsigned. If no signing domain can be determined, or there is no key directory for it, the message is failed (terminal
failed, with the reason instate.last_error), and pepsi-failure-bouncer or the operator decides what happens to it. If the keys exist but cannot be read or used (a half-done rotation, a changed permission), the host is at fault: the message is paused and retried, with the reason instate.last_error, until the stage’sMAX_LIFETIME(default 120 hours) — fix the key and the queue drains by itself.
35.3. Configuration¶
[stage-<name>]: PROGRAM = pepsi-stage-dkim-sign, NEXT_STAGE
(required) and SIGNING_DOMAIN, plus the signature parameters
HEADER_CANONICALIZATION / BODY_CANONICALIZATION
(relaxed — the default — or simple, choosable independently),
SIGNED_HEADERS (the h= set; must include From) and
SIGNATURE_EXPIRATION_DAYS (the x= tag; none by default). Key material and
selectors come from the shared [pepsi] section (KEY_DIR,
DKIM_SELECTOR; the Ed25519 selector is that name with -ed25519 appended;
DKIM_ALGORITHMS). See
pepsi-stage-dkim-sign(1).
35.4. State¶
Inputs: none from
state(domain fromSIGNING_DOMAINor thefrom_headercolumn; body hash from the loaded message).Outputs: none on the signing path — the whole
state, includingstate.dsn, is preserved. Only a failure or a retry writes anything (state.last_error, andstate.temporary_failuresfor a retry).
35.5. See also¶
pepsi-stage-bounce, pepsi-stage-relay-to-internet, Supported Features, pepsi-stage-dkim-sign(1).