31. pepsi-stage-aliases

Expand envelope recipients through an alias / mailing-list map.

31.1. Role

pepsi-stage-aliases rewrites a message’s envelope recipients through a mapping file before delivery: every recipient that matches an entry in the map is replaced by that entry’s target addresses, recipients that match nothing are left unchanged, the resulting list is de-duplicated so each address is delivered to at most once, and the message advances to NEXT_STAGE. It is the classic /etc/aliases / virtual-domain expansion step, and is normally placed just before local delivery. It loads only the envelope and state — never the headers or body — and never pauses, fails or finishes a message. Reference: pepsi-stage-aliases(1).

31.2. Features

  • Postfix-style map file. ALIASES names a human-readable file parsed like a Postfix virtual(5) table: each non-blank line maps one key — a full address, an @domain catch-all, or a *-glob such as sales-*@example.org — to one or more comma/whitespace-separated target addresses (kept verbatim; targets may not themselves contain a wildcard). A key with no targets is ignored, so a recipient is never silently deleted.

  • Most-specific match wins. A recipient is lower-cased and looked up verbatim; on a miss the @domain catch-all is tried, then the most specific matching * wildcard (a narrow sales-*@example.org beats a broad *@example.org beats a bare *). Sub-address (+tag) detail is not stripped, so a specific list address can be aliased on its own.

  • Transitive expansion with loop breaking. When a target is itself a key it is expanded in turn, so nested distribution lists resolve to their leaf addresses; a cycle is broken by resolving the repeated key to its literal address rather than recursing forever.

  • mtime-cached, fail-soft. The map is read into a process-global cache and re-parsed only when the file’s modification time changes, so a busy worker does not re-read it per message. A missing or unreadable file is treated as an empty map (and logged), so a momentary misconfiguration does not fail mail. pepsi-setup syntax-checks the file at install time when it exists.

31.3. Delivery Status Notifications

state.dsn.rcpt runs parallel to the recipient list, so it is rebuilt in lockstep with the rewritten recipients. An expanded target inherits the NOTIFY of the original recipient and, following RFC 3461 §5.2.7, carries an ORCPT pointing at that original recipient (its existing ORCPT if any, otherwise rfc822;<original-recipient>). An unexpanded recipient keeps its DSN entry, and message-level RET/ENVID and every other state key are preserved. pepsi-stage-aliases is the only stage that writes a brand-new rcpt_to (via the rewrite_recipients helper); the other recipient helpers only reduce the list.

31.4. Configuration

[stage-<name>]: PROGRAM = pepsi-stage-aliases, the ALIASES map-file path, and the NEXT_STAGE the expanded message advances to. pepsi-setup creates a starter ALIASES template when the file is missing and syntax-checks it when present. See pepsi-stage-aliases(1) and Configuration.

31.5. State

  • Inputs: the envelope rcpt_to and the parallel state.dsn.rcpt.

  • Outputs: a rewritten rcpt_to and matching state.dsn.rcpt (only when an alias applied); no other state is touched.

  • Transitions: advance to NEXT_STAGE (the only transition).

31.6. See also

pepsi-stage-relay-to-maildir, pepsi-stage-relay-to-lmtp, pepsi-stage-if, Supported Features, pepsi-stage-aliases(1).