70.1.25. pepsi-stage-edit-settings¶
change per-address settings from a control e-mail
- Manual section:
1
70.1.25.1.1. Name¶
pepsi-stage-edit-settings - the settings-by-e-mail stage of the Pepsi pipeline.
70.1.25.1.2. Synopsis¶
pepsi-stage-edit-settings [GLOBAL-OPTIONS] worker
70.1.25.1.3. Description¶
pepsi-stage-edit-settings 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), reads its
[stage-<stage>] section, and decides whether the message is a
settings-control message an account owner sent to change their own per-address
settings (the pepsi.settings overrides described in pepsi-settings(1)).
A message is a control message only when all of these hold:
it is locally originated (
state.local_originistrue);its
Subject:is exactly SUBJECT (defaultPepsi); andone of its envelope recipients is
<CONTROL_LOCAL_PART>@<domain>(default local partpepsi) for adomainthe instance accepts ([pepsi-ingress] ACCEPTED_DOMAINS).
Any other message is advanced unchanged to NEXT_STAGE, so the stage is safe to place anywhere on the local-submission path.
Deciding whether a message is a control message — locally originated, the right
Subject, addressed to the control local part at an accepted domain — needs only
the message metadata, never the body. This stage therefore takes part in stage
fusion (see pepsi-dispatch(1)) with a data-dependent gate: it defaults to
FUSION = yes and a predecessor fuses it in-process for every non-control
message (which it just advances), but declines fusion for a genuine control
message, which is then committed and dispatched as its own worker so the full body
is loaded for parsing. The optimisation is thus free for the common case and never
skips the body when it is actually needed; set FUSION = no to opt out.
The address whose settings are edited is the envelope sender — the owner edits their own settings, and the reply is mailed back to them. (The operator’s submission authentication must therefore bind the envelope sender; otherwise an authenticated user could edit another address’s settings.)
70.1.25.1.4. The body¶
The message body is read as a lenient INI snippet: [stage-<name>] section
headers and OPTION = value assignments. Blank lines, comments
(#/%/;), a leading greeting, and a trailing signature (a -- line)
are ignored, so an ordinary e-mail containing the configuration works. Each
assignment adds or overrides the stored override for that stage’s option; an
assignment whose value is empty (OPTION =) removes the override, reverting
the option to its INI default.
Only sections whose stage name appears in EDITABLE_STAGES may be changed; a body addressing any other section is rejected.
For safety, an assignment that sets a stage’s PROGRAM is only accepted when its
value is a pepsi-stage-* command (with no path component), so an account owner
cannot redirect a stage at an arbitrary executable. Setting
UNRESTRICTED_UNSAFE_STAGES = YES in the stage’s configuration lifts this
restriction (unsafe; the default is NO).
The resulting combined settings — the INI defaults, plus the address’s existing overrides, plus the new assignments — are validated by running each affected stage’s own configuration parser. If anything is invalid, no change is made and a human-readable reply explains every problem. If everything is valid, the merged overrides are stored and a reply quotes the full effective option set (defaults plus overrides) of every editable stage, in INI syntax.
Either reply carries Subject: SUBJECT, the null envelope sender <>
(RFC 3834, so it is never itself gated or bounced), and is injected at
RESPONSE_STAGE (where it is DKIM-signed and relayed like any outbound mail).
The control message itself is then removed.
The framing prose of both replies is localised: it is rendered from the
operator-customizable edit-settings.<lang>.body Mustache template under
[pepsi] TEMPLATE_DIR, choosing <lang> from the sender’s detected
language(s) (the state.language Accept-Language string set by
pepsi-stage-detect-language) and always falling back to English
(edit-settings.en.body). The template’s {{#success}} / {{^success}}
branches frame, respectively, the effective-settings echo and the problem list.
This stage loads the message body but does not modify it.
70.1.25.1.5. Configuration¶
Options live in the stage’s own [stage-<name>] section
(PROGRAM = pepsi-stage-edit-settings): the EDITABLE_STAGES allowlist, the
RESPONSE_STAGE the reply is injected at, a NEXT_STAGE for ordinary mail,
the SUBJECT/CONTROL_LOCAL_PART/RESPONSE_FROM control parameters, and
the UNRESTRICTED_UNSAFE_STAGES safety switch. They are documented in
pepsi.conf(5).
70.1.25.1.6. State¶
Inputs: state.local_origin (gates whether the message is a control
message), and the envelope sender/recipients and Subject: header.
Outputs: the stage rewrites the pepsi.settings row of the envelope sender
and injects a reply; it does not modify the state of the original message
(which it removes). The state layout is described in pepsi.state(7).
Transitions:
an ordinary message (not locally originated, or not matching SUBJECT / CONTROL_LOCAL_PART) → advance to NEXT_STAGE unchanged;
a control message → inject the reply (the INI echo on success, or the error on a rejected/invalid edit) at RESPONSE_STAGE and finish (the original row is deleted).
The stage never pauses, fails or reroutes.
70.1.25.1.7. Commands¶
- worker
Run as a persistent pepsi-dispatch(1) worker, reading message ids on standard input.
70.1.25.1.8. 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.25.1.9. Exit Status¶
- 0
The message was processed (passed through, or applied/rejected with a reply).
- 1
An error occurred (message not found or not
running, misconfigured stage, or a database error). The reason is written to the log.
70.1.25.1.10. Examples¶
A pipeline section that lets owners edit their whitelist and language policy, replying via the outbound path:
[stage-edit-settings]
PROGRAM = pepsi-stage-edit-settings
EDITABLE_STAGES = check-whitelist, block-language
RESPONSE_STAGE = dkim-sign
NEXT_STAGE = srs
A control e-mail body (Subject: Pepsi, To: pepsi@example.org) that sets a
whitelist and clears a language blacklist:
[stage-check-whitelist]
WHITELIST_NAME = my-contacts
[stage-block-language]
BLACKLIST =
70.1.25.1.11. See Also¶
pepsi-settings(1), pepsi-config(1), pepsi-dispatch(1), pepsi-stage-check-whitelist(1), pepsi-stage-block-language(1), pepsi.conf(5), pepsi.state(7), pepsi-setup(1)
70.1.25.1.12. Bugs¶
Report bugs to the Pepsi issue tracker.