devture / matrix-corporal

Matrix Corporal: reconciliator and gateway for a managed Matrix server
GNU Affero General Public License v3.0
143 stars 14 forks source link

Pre-generate E2EE recovery keys / populate 3PIDs #17

Open Programmierus opened 3 years ago

Programmierus commented 3 years ago

Due to mandatory E2EE I have to find some solution to pregenerate keys for my users and store them somewhere in a safe place. Normally they forget passwords on a weekly basis, giving them additional "passphrase" to remember will practically block the entire enterprise :)

In the FAQ I've noticed that you are saying that even with shared_secret_auth it's impossible to submit 3PIDs (e.g. E-Mail) for the users. Is it still actual? From what I see in the Client-Server-API - it's now perfectly possible...

And if yes, what would you think about a possibility to pre-generate E2EE recovery keys?

spantaleev commented 3 years ago

Which Client-Server API are you looking at for adding 3pids? It does require user-interaction and the involvement of an identity server, doesn't it?

For E2EE, we should do something indeed.

What's your idea about key-handling? Pregenerate them and store them where? Do what with them?

Programmierus commented 3 years ago

Which Client-Server API are you looking at for adding 3pids? It does require user-interaction and the involvement of an identity server, doesn't it?

I am sorry I meant the Admin API of course. For this cause it'd be necessary to add a config option to specify the admin user_id for matrix-corporal usage.

Short PoC ### **PUT** - /_synapse/admin/v2/users/@user:domain.com Add 3PID (Email medium) #### CURL ```sh curl -X PUT "https://matrix/_synapse/admin/v2/users/@user:domain.com" \ -H "Authorization: Bearer AdminToken" \ -H "Content-Type: application/json; charset=utf-8" \ --data-raw "$body" ``` #### Header Parameters - **Authorization** should respect the following schema: ``` { "type": "string", "enum": [ "Bearer AdminToken" ], "default": "Bearer AdminToken" } ``` - **Content-Type** should respect the following schema: ``` { "type": "string", "enum": [ "application/json; charset=utf-8" ], "default": "application/json; charset=utf-8" } ``` #### Body Parameters - **body** should respect the following schema: ``` { "type": "string", "default": "{\"name\":\"@user:domain.com\",\"threepids\":[{\"address\":\"test.user@domain.com\",\"medium\":\"email\"}],\"id\":\"@user:domain.com\"}" } ``` ### **PUT** - /_synapse/admin/v2/users/@user:domain.com Remove 3PID (Email medium) #### CURL ```sh curl -X PUT "https://matrix/_synapse/admin/v2/users/@user:domain.com" \ -H "Authorization: Bearer AdminToken" \ -H "Content-Type: application/json; charset=utf-8" \ --data-raw "$body" ``` #### Header Parameters - **Authorization** should respect the following schema: ``` { "type": "string", "enum": [ "Bearer AdminToken" ], "default": "Bearer AdminToken" } ``` - **Content-Type** should respect the following schema: ``` { "type": "string", "enum": [ "application/json; charset=utf-8" ], "default": "application/json; charset=utf-8" } ``` #### Body Parameters - **body** should respect the following schema: ``` { "type": "string", "default": "{\"name\":\"@user:domain.com\",\"id\":\"@user:domain.com\"}" } ```

For E2EE, we should do something indeed.

What's your idea about key-handling? Pregenerate them and store them where? Do what with them?

There are many issues more or less related to E2EE in corporate environment (e.g. 1, 2, 3).

I try to stay a bit pragmatic in this question. E2EE stays, it's hyped and nice to have for common usage. It's default now. I/We have to live with it - OK. Moreover my/our conclusion is that E2EE is not really prohibited (or regulated) in most corporate environments.

The problem is, that it is simply way too complicated for end-user to set it up and maintain (especially in Matrix/Element). Some significant amount of users come to my helpdesk on a weekly basis asking to restore their regular passwords (sic!). One can imagine what would happen with cross-signing encryption recovery keys (assuming they'd manage to set them up at all). And I can't simply "reset" them, loosing them means loss of sometimes crucial conversations history for end-users.

My thoughts so far:

  1. Disable E2EE completely - not really possible at the moment. We have to wait for additional support from Synapse and Element. Workarounds are limited and leave artifacts that are hard to understand for end-users. I personally doubt those issues are in even middle future development pipeline.
  2. Upon account creation create a bot for each account that will permanently stay online and verify all new sessions (possibly under some conditions to harden security, e.g. IP whitelisting). I doubt on reliability and scalability of this "solution"
  3. Upon account creation login through shared auth, initialize cross-signing and key backup, store the recovery key in a secured corporate environment. Provide it to the user on demand for session recovery. IMHO preferred solution

I tried to implement 3 myself - so far unsuccessful. I guess one has to have much more experience in Synapse infrastructure to understand the whole encryption workflow. It's not a matter of a few hours :(

WDYT? :)

spantaleev commented 3 years ago

Indeed!

It feels like E2EE is pushed fairly hard, while it causes so much complication (UX-wise and feature-wise). It also breaks so many clients, bots, etc.. And then there's the human problem. Regular users can barely remember a single password, and now they have at least one more password. And they're asked to use a different one.. No way..

Having worked on translating Element (web / iOS / Android) and having touched encryption a bit myself (with huge reluctance), I'd rather run away from all this, let alone let any of my family or friends deal with it.

I think it'd be nice if corporal could have support for completely disabling E2EE. I don't know if it intercepting requests would be enough though. Clients may be insistent on setting up keys and "secure secret storage".

Although there are things you can set in /.well-known/matrix/client to hint to Element that you'd like to avoid encryption, it's probably not enough. It's certainly not enough when it comes to federation. These settings only instruct what your Element instance should do. If someone else drags you into an encrypted room (and users over federation will certainly do that to you, because most of them are running an overly-E2EE-aggressive Element), you won't be able to run away.

I'm not sure what a good solution to all this would be.. Do we need an MSC that specifies how cross-server-E2EE negotiation should work?

We may be able to solve it for the local use-case and disable encryption for all rooms your own users create (even if Element tries to enable it). Unfortunately, Element (and other clients) will still nag you to set up keys, secret storage, secure backup and whatnot. And you'll still be invited to encrypted rooms over federation.


Another thing is.. matrix-corporal impersonates users and performs actions on their behalf. To do that, it performs a /login, which unfortunately generates a new device right now.. Generating a new device:

This is something else that might be causing problems for us. Possible solutions might be to: