-
Notifications
You must be signed in to change notification settings - Fork 399
MSC4153: Exclude non-cross-signed devices #4153
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implementation requirements:
- Client embodying these values (preferably cross platform).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sharing strategy is defined as part of MSC4153[1]. [1]: matrix-org/matrix-spec-proposals#4153
proposals/4153-invisible-crypto.md
Outdated
### Bots and application services | ||
|
||
This is a special case to the issue above, but seems to be a large enough class | ||
that it deserves its own mention: support for cross-signing in bots and | ||
application services may be less common than in interactive clients. When a | ||
client fully implements this proposal, users will be unable to interact with | ||
bots and application services in encrypted rooms if they do not support | ||
cross-signing. | ||
|
||
TODO: status of cross-signing in bots/application services |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cross-signing in general is relatively easy to implement, but receiving messages from bridges may be a more complicated issue: most encryption-capable bridges (i.e. mautrix-*) only generate keys for the bridge bot, not every ghost, which means messages are sent with a different user than the user who created the megolm session.
We likely have to invent some new mechanism to "delegate" crypto to another user so that clients wouldn't get scared when ghosts send messages encrypted by the bridge bot. Generating keys for every ghost would be ridiculously wasteful, the bridge is a single entity so there's no reason for it to have more than one encryption device.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When you say "most encryption-capable bridges (i.e. mautrix-*) only generate keys ...", are you talking about device keys? Can you explain how megolm session distribution works with mautrix bridges? Is it something like: bridge generates megolm session, bridge bot sends megolm session to recipient, ghost sends encrypted message to room?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, exactly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was some discussion about this in #element-x-ios:matrix.org
For clarity: the wasteful part is not the device key generation itself, but rather the resulting large number of olm sessions when clients have to encrypt megolm sessions for each ghost individually.
Matthew suggested that the ghost could create a device with no identity key (to prevent olm sessions being created) and use it to sign the bot's device.
I'm thinking ghosts will probably need a cross-signing key (because that's the real root of trust). Maybe ghosts could just upload the bot's cross-signing key? They'd have the wrong user_id
, which clients could detect to realize it's a ghost user. The key could also have a special usage
field or something else as an extra ghost identification. Or maybe the user_id
field should be the ghost, but there could be a new bridge_bot_id
field which points at the bridge bot.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, there's also another related annoying part: double puppeting, where bridge logs in with your account to bridge messages you send from the remote network using your real account instead of a ghost. Currently it works the same way as ghosts in terms of encryption: create megolm keys with bridge bot, send with double puppet.
The number of double puppets is generally much lower than the number of ghosts, so technically it would be fine to create a full e2ee session (which the user can then cross-sign normally). However, that would mean the bridge receives decryption keys for messages in all your rooms instead of only its own rooms, which is not great.
I don't think it's worth creating a separate mechanism for trusting double puppets, but at least the "upload bot's cross-signing keys to ghost" mechanism wouldn't work for double puppets. Creating a device without identity keys could work for both though
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that it's a bug that we're accepting messages encrypted using a key that we received from a different user, because that seems bad from a cryptographic point of view. So I'm not too keen to try to work around it. I also don't think that we should have bots upload cross-signing keys of different users.
If the big issue is in receiving encrypted messages, maybe the easier solution would be to add a flag in the device keys object to indicate that the device doesn't want to receive any keys?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The flag to not receive encrypted messages sounds good, that'd at least solve the double puppeting issue of receiving unwanted keys. Sending messages would still require creating olm sessions from every ghost that sends messages though
Technically there's also the option of deciding that appservices were a mistake and switching to MSC4144, but having to build duplicates of a bunch of different mechanisms like member lists and membership actions would be unfortunate
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've written MSC4261 to propose adding a flag to mark devices that don't want to receive room keys.
proposals/4153-invisible-crypto.md
Outdated
Clients should encourage users to cross-sign their devices. This includes both | ||
when logging in a new device, and for existing devices. Clients may even go so | ||
far as to require cross-signing of devices by preventing the user from using | ||
the client until the device is cross-signed. If the user cannot cross-sign | ||
their device (for example, if they have forgotten their Secret Storage key), | ||
the client can allow users to reset their Secret Storage, cross-signing, and | ||
key backup. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If a client enforces cross signing, how would cross signing work without access to other devices or recovery key?
Real scenario that happens to me from time to time:
Not all my accounts have the same powerlevel in rooms, sometimes I need to switch accounts on the go to carry out a moderation action. Worse, most of the moderation bot rooms I interact with on the regular use End-to-End Encryption (usually via Pantalaimon). Additionally, I do not feel comfortable keeping a copy of my Recovery Keys on my phone, or accessible to my phone, nor want to rely on physical devices (eg. security keys) when eg. going to a party, hanging out with friends at an entertainment park, etc.
Element X Android provides a good example here: while I enjoy using sliding sync, using Element X left me unable to carry out moderation actions due to being unable to switch accounts without cross-signing.
I'm currently using Schildichat Next to bypass cross signing requirements, but having multiple copies installed would exacerbate my out-of-memory issues on my phone, which are already preventing me from using it effectively at all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The paragraph says "may even", so enforcing cross-signing when logging in is not a requirement. Moreover, moderation actions are usually state events, which are not E2EE authenticated at the moment, so the situation there should remain unchanged.
Your unsigned device should get ignored for everything that is E2EE authenticated though, and for a good reason—the very concept of unsigned devices is unsound in an E2EE setting, because such devices can be freely added by the server, so in what sense is it E2EE at all? I don't think your scenario has much bearing on that fact.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason why moderation bots is a concern is because they are controlled via regular messages in dedicated rooms. Said room if your using mjolnir is recomended to be Encrypted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While I'm sympathetic to your usecase, I think that we still need the security properties that this MSC gives.
secrets (via Secret Sharing), to non-cross-signed devices by default. When | ||
sending room keys, clients can use a [`m.room_key.withheld` | ||
message](https://spec.matrix.org/unstable/client-server-api/#reporting-that-decryption-keys-are-withheld) | ||
with a code of `m.unverified` to indicate to the non-cross-signed device why it |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moving morguldir's comment here, to discuss whether we should use m.unverified
for this, or use a new code:
I think it would make sense to use a m.room_key.withheld code here, tulir proposed a new code m.not_cross_signed
Adding this would make it easier to separate unverified users and insecure devices, like mentioned in element-hq/element-meta#2621
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The implementation in Element uses m.unverified
, and it seems to be working OK, so we may just stick with that for now. If we find that we want to use a separate code after this MSC has already been accepted, we can add it in a separate MSC.
This comment was marked as resolved.
This comment was marked as resolved.
identity keys for the device and upload them to the homeserver, converting the | ||
device into a cryptographic device and making it subject to the rules given in | ||
this MSC. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Proposed addition:
Updates to documentation
If MSC4161 is merged before
this MSC, the section "Devices (Sessions)" should be replaced with:
### Devices (Sessions)
Instances of a client are called 'devices' or alternatively 'sessions'. All devices taking
part in encryption should have been cross-signed by the user who owns them, and
we call these simply **devices** or **sessions**.
Devices which have published cryptographic keys (thus being visible as "cryptographic devices"
to other users) but which have not been cross-signed are considered an error state. These
devices are referred to as **not secure** or **insecure** and they are ignored for the purposes
of sending or receiving encrypted messages.
> "This device is not secure. Please verify it to continue."
> "Ignoring 5 messages that were sent from a device that is not secure."
> "Confirm it's you" (when asking to verify a device during login)
⚠️ Avoid saying "secure device". All devices are considered secure by default;
the user doesn't typically need to worry about the fact that insecure devices
are a thing, given they should only ever occur in error (or transitional)
scenarios.
⚠️ Avoid saying "trusted device" or "verified device". Devices are not users,
and it is helpful to use different language for users vs. devices. (However, we
do use the verb "verify" to describe how to make a device secure. By using the
same verb, we help users understand the confusing fact that verifying devices
and verifying users are similar processes, but with different outcomes.)
⚠️ Avoid using "cross-signing", which requires a deeper knowledge of
cryptography to understand.
⚠️ Avoid mentioning "device keys". While a device may have keys, the user
is only concerned about whether it is secure or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(As per #4161 (comment) I think it makes sense to leave this material out of MSC4161 and add it when this MSC is merged.)
The following bots support cross-signing: | ||
|
||
- [meowlnir](https://github.com/maunium/meowlnir) | ||
- [Arnie](https://gitlab.com/andybalaam/arnie) | ||
|
||
The following bot SDKs support, or plan to support, cross-signing such that any | ||
bots written using them will support cross-signing: | ||
|
||
- [maubot](https://github.com/maubot/maubot) (planned) | ||
- [mautrix-go](https://github.com/mautrix/go) (planned support for Application Services) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for adding this section, it is what I am most concerned about with the series of invisible crypto MSCs.
It's difficult to do an objective survey of the ecosystem in this regard. I think it would however be prudent to also list here bots/appservices/SDKs assumed to be popular by some measure (github stars? project commit activity? activity in project's rooms?) that do support e2ee but NOT cross-signing, not only those maintained by SCT members.
I do however agree that the mau* suite of projects is very wide spread and one important implementation blocking the ecosystem. Further can be found through the Foundation website https://matrix.org/ecosystem/ and the commonly used Matrix "distro" https://github.com/spantaleev/matrix-docker-ansible-deploy?tab=readme-ov-file#bridges
Some examples that feel significant to me:
- matrix-bot-sdk
- matrix-appservice-bridge
- mautrix/python
- https://github.com/matrix-nio/matrix-nio
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mautrix-python is the same as maubot in this context
mautrix-go has basically full support (Meowlnir is written in Go and supports generating cross-signing keys and recovery keys and self-verifying with an existing recovery key), but verifying bridges depends on the resolution to #4153 (comment)
Rendered
Conflict of Interest declaration: I am a member of the Spec Core Team, and am employed by Element. This MSC was written as part of my work on the Element Cryptography team.