70.1.20. pepsi-stage-auto-whitelist

whitelist recipients of outgoing mail

Manual section:

1

70.1.20.1.1. Name

pepsi-stage-auto-whitelist - the recipient-recording stage of the Pepsi pipeline.

70.1.20.1.2. Synopsis

pepsi-stage-auto-whitelist [GLOBAL-OPTIONS] worker

70.1.20.1.3. Description

This stage defaults to FUSION = yes: when stage fusion is enabled ([pepsi] ALLOW_FUSION, the default) and this stage is folded into the unified pepsi binary, a predecessor may run it in its own worker process instead of dispatching it separately. See pepsi-dispatch(1) and pepsi.conf(5).

pepsi-stage-auto-whitelist is a stage program run by pepsi-dispatch(1) as a persistent worker reading message ids on standard input. It loads that pepsi.ingress row (refusing to act unless its status is running) and reads its [stage-<stage>] section. It is the write-side counterpart of pepsi-stage-check-whitelist(1): as an outgoing message passes through, it records every envelope recipient (rcpt_to) in a named whitelist, so that when that person later replies, pepsi-stage-check-whitelist(1) recognises their From: header and lets the reply skip the anti-spam payment gate. Place it on the outbound path (for example, ahead of a relay stage).

The whitelist lives in the pepsi.whitelist table, shared with pepsi-stage-check-whitelist(1) — this stage only INSERTs into it, so it needs no schema of its own. Each recipient address is stored as a whitelist_regex: the address is lower-cased, every non-alphanumeric character is backslash-escaped so it matches literally, and the result is anchored on address boundaries (the start/end of the value, or any character that is not part of an address token). The check stage matches that regex case-insensitively (PostgreSQL’s ~* operator) against a reply’s whole From: header, so "Bob" <bob@example.com> matches while bob@example.com.evil does not.

Each inserted row carries two condition flags that govern when a future reply counts as whitelisted:

  • dkim_required is set from the stage’s DKIM_REQUIRED option (default yes): when true, the reply is only trusted if its DKIM or ARC signature verified.

  • signature_required is set to true when the outgoing message’s state has encrypted: true (the message was end-to-end encrypted), otherwise false. No stage produces ``state.encrypted`` yet — it is reserved for a future encryption stage, so today this is always false.

Every row is written with match_field = 'from': what this stage records is an address a reply will arrive from. It never writes the list-id rows pepsi-stage-check-whitelist(1) also understands — recognising that a user has joined a mailing list is a different inference over different headers, and is today done by hand with pepsi-whitelist add-list (see the ROADMAP).

Existing rows are left untouched (the insert is ON CONFLICT DO NOTHING on the UNIQUE(whitelist_name, match_field, whitelist_regex) constraint), so reprocessing a message is harmless. The stage then advances the message to NEXT_STAGE. It never modifies the message’s own state and never drops, bounces or pauses a message; a message with no recipients simply advances.

70.1.20.1.4. Configuration

Options live in the stage’s own [stage-<name>] section (PROGRAM = pepsi-stage-auto-whitelist): the required WHITELIST_NAME group to populate, DKIM_REQUIRED (default yes) and a NEXT_STAGE. They are documented in pepsi.conf(5).

70.1.20.1.5. State

Inputs: the envelope recipients come from the rcpt_to column; state.encrypted sets the stored signature_required flag. That key is written by pepsi-stage-encrypt(1) when the outgoing message really was encrypted to a recipient key, and by pepsi-stage-decrypt(1) when a message arrived encrypted — so a correspondent reached under encryption is later held to the same standard.

Outputs: none on the message itself — the message state is left untouched. The side effect is one pepsi.whitelist row per recipient. The state layout is described in pepsi.state(7).

Transitions: always advances to NEXT_STAGE — after inserting one whitelist row per envelope recipient, or unchanged when there are none. There is no branch; the stage never pauses, fails, reroutes or finishes.

70.1.20.1.6. Commands

worker

Run as a persistent pepsi-dispatch(1) worker, reading message ids on standard input.

70.1.20.1.7. Global Options

-c FILE, –config FILE

Read the configuration from FILE instead of searching the default locations.

-L LOGLEVEL, –log LOGLEVEL

Set the logging verbosity (default info).

-v, –verbose

Show log messages from all sources.

-h, –help; -V, –version

Print a usage summary / the version and exit.

70.1.20.1.8. Exit Status

0

The message was processed (recipients recorded and the message advanced).

1

An error occurred (message not found or not running, misconfigured stage — e.g. a missing WHITELIST_NAME — or a database error). The reason is written to the log.

70.1.20.1.9. Examples

Record the recipients of message 42 (it must be running):

pepsi-stage-auto-whitelist -c /etc/pepsi/pepsi.conf 42

An outbound pipeline section that whitelists everyone we mail, requiring their replies to be DKIM/ARC-signed:

[stage-auto-whitelist]
PROGRAM = pepsi-stage-auto-whitelist
NEXT_STAGE = srs
WHITELIST_NAME = trusted-senders
DKIM_REQUIRED = yes

70.1.20.1.10. See Also

pepsi-config(1), pepsi-stage-check-whitelist(1), pepsi-stage-anti-spam(1), pepsi-stage-arc(1), pepsi-dispatch(1), pepsi.conf(5), pepsi.state(7), pepsi-setup(1)

70.1.20.1.11. Bugs

Report bugs to the Pepsi issue tracker.