Features

difuzio covers the whole chain of a mailing list: receive, decide, transform, deliver, then handle what comes back. This page describes what is actually implemented and covered by the project's test suite.

Mail reception

Mail comes in over LMTP from a front mail server, or by polling an IMAP mailbox at a hosting provider.

An address classifier recognises the service-address grammar: post to the list, subscribe, unsubscribe, contact the owners, VERP bounce, feedback-loop complaint. It follows the reserved-suffix and longest-list-match rule, so a list named announce-tech and a list named announce coexist without ambiguity.

List policies

Every list decides who may write to it: open to anyone, subscribers only, moderated, or owners only. On top of that come first-post moderation for new subscribers, temporary suspension of the list, and an attachment policy.

Items awaiting moderation are visible in the console, actionable there or from the command line, and every decision leaves a trace in the audit log.

Message transformation

Before delivery, the pipeline applies what the list asks for: subject tag, footer, complete List-* headers, RFC 8058 one-click unsubscribe, and a feedback identifier for the large mailbox providers.

Two behaviours are worth knowing about, because they change what subscribers receive:

Subscriptions and consent

Subscribing happens by mail or from the list's public pages. Either way, confirmation is requested at the address concerned, with a single-use token of limited lifetime. An anonymous web form proves nothing, so double confirmation is enforced there even on an open list.

Also included: bulk CSV import, delivery modes (message by message or periodic digest), automatic disabling of an address that bounces, removal by a manager, and one-click unsubscribe from the mail client's own button.

The messages difuzio writes itself - confirmation, welcome, farewell, sign-in link

Deliverability and reputation

Web console and public pages

The administration console covers domains, lists, members, moderation, API keys and the audit log, with dashboards that adapt to the role of the person signed in.

A list's public pages - help, subscription form, archives - are served by the same service. Archives mask addresses, rate-limit per IP and declare themselves to crawlers according to the list's setting. Sessions, anti-CSRF tokens and content sanitising are part of the foundation, not of an option.

REST API and webhooks

The /api/v1 API is authenticated by key, described by an OpenAPI 3.1 document served by the application itself and checked in continuous integration against a versioned golden file. It exposes domains, lists, members, moderation and sends.

An idempotency header protects replayed creations. Outgoing webhooks are HMAC signed, delivered at least once with retries, and the HTTP client refuses internal addresses so it never becomes a relay into your private network.

Isolation and roles

One deployment hosts several domains without them seeing each other. Roles range from super administrator to moderator, by way of domain administrator and list owner. Every read is filtered by the scope of the person signed in, and anything out of scope answers "not found" rather than "forbidden": that is the only way not to reveal the existence of another tenant's list.

Compliance and personal data

Erasing a person walks every table, including indirect traces, and deletes the relevant message bodies from disk, not just their metadata. Proof of consent is recorded at subscription time. Archives have a per-list retention period, applied automatically.

Operations

Three processes share one configuration: the web interface and API, mail reception, and the worker that drains the queues and runs periodic tasks. Run several workers for throughput.

What difuzio does not do

Better said here than discovered in production.

Going further

The operator manual covers each of these points with the matching configuration: administration documentation (in French).