47. pepsi-stage-auto-whitelist

Record the recipients of outgoing mail so they can always reply.

47.1. Role

pepsi-stage-auto-whitelist is the write-side counterpart of pepsi-stage-check-whitelist. As an outgoing message passes through, it inserts each envelope recipient (rcpt_to) into a named whitelist, so that when that person later replies, the check stage recognises their From: header and lets the reply through without payment. Place it on the outbound path (e.g. before a relay stage). It only writes whitelist rows and advances — it never modifies the message or drops, bounces or pauses it. Reference: pepsi-stage-auto-whitelist(1).

47.2. Features

  • Shared whitelist table: writes the same pepsi.whitelist table the check stage reads, so no schema of its own is needed; the WHITELIST_NAME option selects the whitelist_name group to populate.

  • All envelope recipients: every address in rcpt_to is recorded in a single round-trip, idempotently (ON CONFLICT (whitelist_name, match_field, whitelist_regex) DO NOTHING); the rows are written with match_field = from.

  • Fully anchored patterns: each address is lower-cased, regex-escaped and wrapped in ^/$, so the stored whitelist_regex matches that address and nothing else. The check stage evaluates it (case-insensitively, with the ~* operator) against the addr-spec parsed out of a reply’s From: header, not the raw header value — so bob@example.com (Bob) still matches the row for bob@example.com, while bob@example.com.evil and (bob@example.com)x@attacker.test do not. The anchoring is load-bearing: a boundary class enumerating the characters an address may contain would let an attacker find one character outside it and sit on either side of a whitelisted address inside a local part of their own.

  • Whose whitelist: on the outbound path the per-address layers are looked up for the envelope sender. The operator may name any whitelist in the INI file, pepsi.config_override at any scope, or a pepsi.settings row written with pepsi-settings, a list shared by every local user included. An account owner who may edit the stage by mail (pepsi-stage-edit-settings) may only choose a list in their own <login>/... namespace, or keep the operator’s; anything else would let them fill a shared or foreign list with addresses of their choosing.

  • Per-row conditions:

    • dkim_required is set from the DKIM_REQUIRED option (default yes).

    • signature_required is set to true iff the message state has encrypted: true — which pepsi-stage-encrypt sets when a recipient’s copy really was encrypted. A correspondent reached under encryption is thereby held to the same standard when they reply. This only works with the stage placed after the encrypt stage; it changes no content, so it may sit between encrypt and pepsi-stage-dkim-sign, which is where the setup wizard puts it.

47.3. Configuration

[stage-<name>]: PROGRAM = pepsi-stage-auto-whitelist, WHITELIST_NAME (required — the single whitelist_name group to populate, a literal name: placeholders are not expanded and are refused), DKIM_REQUIRED (boolean, default yes) and NEXT_STAGE (required — the stage records the recipients and always hands the message on). Neither the headers nor the body are loaded. See pepsi-stage-auto-whitelist(1).

47.4. State

  • Inputs: the envelope recipients from the rcpt_to column, and state.encrypted — set by pepsi-stage-encrypt, earlier on the same outbound path, when the outgoing message really was encrypted to a recipient key — which sets the stored signature_required flag, so a correspondent reached under encryption is later held to the same standard.

  • Outputs: none on the message — its state is untouched; the side effect is one pepsi.whitelist row per recipient.

47.5. See also

pepsi-stage-check-whitelist, pepsi-stage-anti-spam, pepsi-stage-arc, Supported Features, pepsi-stage-auto-whitelist(1).