Skip to content

Subscriptions and mailinglists

Joshua Thijssen edited this page Jan 3, 2021 · 5 revisions

Because of the need for proof-of-work when sending messages, it will become difficult to set up and manage (large) mailing lists, which in itself are quite a valid way of sending mail.

Current mailing lists have some problems that make the user less in control:

  • easy trivial to add any address to the list without permission
  • removal requests are not always adhered

Most of this results in spam: by harvesting mail addresses, we can create large mailing lists. You can even buy specific sets of emails for your target groups. Trying to unsubscribe to a mailing list often results in more mail, as this is a clear signal for list owners that this address is in use (and being read), which makes the email address more valuable.

The way to combat this, we use a subscription-based system where address owners are 100% in control of adding and/or removing themselves from a list. A subscription is also only valid for that specific user and mailing list, so it cannot be used or exchanged with other lists.

This means that a user (and only the user) can assign a subscription ID to a mailing list. The user (and the list owner) can remove a subscription ID from a mailing list.

Working

The subscription works as follows:

  • A user wants to subscribe to a certain mailing list.
  • The user generates a subscription ID, which is sent to its own mail server and to the mailing list mail server. This is done via signed data with the user's private key for authentication.
  • The recipient will be notified of the subscription ID (or can retrieve a list of subscriptions from their own server). We need a way to send the information to the recipient. Either this is done by the mailserver, or by the client itself.
  • If a list owner wants to send out mail, it will not only use the recipient's address but also their subscription ID.
  • When the mail server sends the message to the recipient, the recipient mail server will check the tuple: <sender hash, recipient hash, subscription id>.
  • If this tuple is valid and known on the server, then no proof of work is needed and the mail can be sent immediately.

Subscribing to a mailing list

Through bm-client:

 $ ./bm-client mailing subscribe --address 'john!' --mailing 697592e4c24a313ed2a5794856d776784378642c1464411f9f6d7fce7f6df1ba  --until 30 days

This will subscribe the account john! to the given mailing (hash), for a period of 30 days. After this period, the subscription becomes invalid.

Underwater, it works the following way:

Step 1: Find out where the mailing list resides (maybe a mailing list is part of the key resolver??)

The user requests a subscription to a specific mailing list:

(on the mailing list server):
POST /mailing/<mailing-hash>/subscription

{
   mailinglist: <hash of the mailing list>
   subscription-id: <uuid>
   subscriber: <hash of subscriber address>
   valid_until: <timestamp>
   signature: sig(hash(subscriber, uuid, timestamp), privkey of subscriber)
}

Then, the user adds the subscription id also to its own server/account:

(on the user mail server):
POST /account/<hash>/mailing/<subscription-id>

{
   mailinglist: <hash of the mailing list>
   subscription-id: <uuid>
   subscriber: <hash of subscriber address>
   valid_until: <timestamp>
   signature: sig(hash(subscriber, uuid, timestamp), privkey of subscriber)
}

This will create the tuple (mailing:recipient:subscription), so it can be used by the mailing list.

Finding all your mailing lists:

  GET /account/<hash>/mailinglists

Finding all subscribers for a specific mailing list:

  GET /mailing/<mail-hash>/subscribers

Expiry time

It might be possible to add an expiry timestamp to the subscription id. This way we can automatically unsubscribe after a certain time.

Sending mailing lists

Because the subscriptions are stored on the mail server, it's possible to bm-client to only send an incoming message to a mailing-list ID. This way, the user does not have to upload anything to the user

On bounces and such

Mail servers are able to send out triggers based on certain actions. This could be used to for instance detect bounces, incorrect deliveries etc.

On the unsubscription

Unsubscribing basically means that instead of directly allowing to send mail, the sender must do proof-of-work. It does NOT mean that no mails could be sent to the user. We can mitigate this by checking for a subscription ID, and if the subscription ID is not valid, the mail is rejected. It will only be rejected AFTER doing proof-of-work, meaning it is not economical to leave expired subscribers on your list.

Metadata on lists

Personalizing mailings will be a bit of a problem: since the content is stored in blocks, and is encrypted only once, they are never different. This is actually a "good thing"(TM): it's not possible to add unique tracking pixels and such for mails this way.

A user still can get a variation of the mailing by reading either an "HTML" block, "text" block, or anything else...

Questions to answer

Q: do we use mailing-hash as an first-class entity? Does it have their own key-resolver entry? Can we somehow send from a mailing-hash or do we need a specific user attached to it?

Q: can we send/receive from mailinglists as well?

Q: How about proxy servers? Who does the proof-of-work in case the subscription check fails?

Clone this wiki locally