65. pepsi-helper-token-refresh¶
Refresh OAuth access tokens for the smarthost relay stage.
65.1. Role¶
A smarthost MTA configured with AUTH = oauth (see
pepsi-stage-relay-to-smarthost) authenticates with a SASL bearer token the
relay stage reads, fresh per delivery, from a TOKEN_FILE. Those access tokens
are short-lived, so the file must be refreshed out of band.
pepsi-helper-token-refresh does that: for every
[pepsi-stage-relay-to-smarthost-mta-<name>] with AUTH = oauth it pairs the
MTA’s TOKEN_FILE/USERNAME with a secret section
[pepsi-helper-token-refresh-<name>] (the OAuth client credentials, kept in a
separate @inline-secret@ file readable only by this service), requests a fresh
token from the provider’s TOKEN_ENDPOINT, and writes it atomically to the
token file. It supports the RFC 6749 refresh-token grant (e.g. Google) and the
client-credentials grant (e.g. Microsoft 365 app-only); a rotated refresh token
is persisted to a private state directory.
It is not a stage and is deliberately not part of pepsi.target — it
is one implementation of the external refresh contract described in
Extending the Pipeline, and a site may substitute its own. Reference:
pepsi-helper-token-refresh(1).
65.2. Security¶
The service runs as the dedicated pepsi-helper-token-refresh account, the
sole reader of the client secrets. It writes token files into a directory that is
SGID the pepsi-token group (default /var/pepsi/tokens), mode 0640; the
relay stage binary is installed SGID pepsi-token so the dispatcher’s pepsi
worker can read them. See Extending the Pipeline for the full contract.
65.3. Modes¶
service (the default) — a long-lived process that refreshes each token proactively, ahead of expiry by
REFRESH_MARGIN, retrying a failing target with back-off while leaving its previous token in place. Runs untilSIGINT/SIGTERM.–once — refresh every target a single time and exit (a manual run, a systemd timer, or cron); non-zero exit if any target failed.
65.4. See also¶
pepsi-stage-relay-to-smarthost, pepsi-setup, pepsi-helper-token-refresh(1), pepsi.conf(5).