-
Notifications
You must be signed in to change notification settings - Fork 375
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
MSC4144: Per-message profiles #4144
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
# MSC4144: Per-message profiles | ||
Currently profiles in Matrix are defined by `m.room.member` state events, and | ||
there is no easy way to have different profiles per message. | ||
|
||
## Proposal | ||
The proposed solution is a new field called `m.per_message_profile`, which | ||
contains a displayname and/or avatar URL to override the default profile, | ||
plus an ID to identify different profiles within the same Matrix user. | ||
|
||
```json | ||
{ | ||
"msgtype": "m.text", | ||
"body": "Hello, World!", | ||
"m.per_message_profile": { | ||
"id": "meow", | ||
"displayname": "cat", | ||
"avatar_url": "mxc://maunium.net/hgXsKqlmRfpKvCZdUoWDkFQo" | ||
} | ||
} | ||
``` | ||
|
||
The `id` field is required and is an opaque string. Clients may use it to group | ||
messages with the same ID like they would group messages from the same sender. | ||
For example, bridges would likely set it to the immutable remote user ID. | ||
clokep marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the scope of this |
||
|
||
### Encrypted avatars | ||
Because the profile is inside the ciphertext in encrypted events, the entire | ||
profile can be hidden the server, as long as the avatar is also encrypted. | ||
Encrypted avatars are placed under `avatar_file` instead of `avatar_url`. | ||
The `avatar_file` field has the same schema as the `file` field in | ||
`m.room.message` events. | ||
|
||
<details> | ||
<summary>Encrypted avatar example</summary> | ||
|
||
```json | ||
{ | ||
"msgtype": "m.text", | ||
"body": "Hello, World!", | ||
"m.per_message_profile": { | ||
"id": "meow", | ||
"displayname": "cat", | ||
"avatar_file": { | ||
"v": "v2", | ||
"key": { | ||
"alg": "A256CTR", | ||
"ext": true, | ||
"k": "8dXeBMBMthuXGY5zmUh9Mi0aqC1kndMZ4NCa-0RhELc", | ||
"key_ops": [ | ||
"encrypt", | ||
"decrypt" | ||
], | ||
"kty": "oct" | ||
}, | ||
"iv": "L6zup2cR570AAAAAAAAAAA", | ||
"hashes": { | ||
"sha256": "/cTs+PajUcznbV3h1w5gh1AHnLjrKQVl2jU3xLCqoBI" | ||
}, | ||
"url": "mxc://maunium.net/eKLhozQduElYSgBkWjtwSXoi" | ||
} | ||
} | ||
} | ||
``` | ||
|
||
</details> | ||
|
||
### Behavior of omitted and empty fields | ||
If the `displayname` field is omitted, null, or an empty string, the | ||
displayname from the member event should be used instead. Setting an empty | ||
displayname using a per-message profile is not supported, as there aren't any | ||
clear use cases for it. | ||
|
||
However, there are use cases for setting an empty avatar, so `avatar_url` being | ||
an empty string should be treated as clearing the avatar and falling back to | ||
the client's default blank avatar behavior (e.g. generating one based on the | ||
displayname). If both `avatar_url` and `avatar_file` are omitted or null, the | ||
avatar from the member event should be used instead. | ||
|
||
### Extensible profiles | ||
This MSC is not related to extensible profiles and does not attempt to | ||
implement them. However, in case extensible profiles are implemented as | ||
something that can be referenced (e.g. room IDs), the MSC adding them could | ||
allow per-message profiles to specify which extensible profile is used. | ||
|
||
## Use cases | ||
|
||
### Bridging | ||
Per-message profiles will allow making "lighter-weight" bridges that don't need | ||
appservice access. Currently the only option for such bridges is to prepend the | ||
displayname to the message, which is extremely ugly. Even though they're ugly, | ||
there are still rooms that use bot-based bridges like matterbridge, which shows | ||
there's demand for bridging without requiring server admin access. | ||
|
||
Such bridges would obviously have downsides, like not being able to start chats | ||
via standard mechanisms, and not being able to see the member list on Matrix. | ||
However, those may be acceptable compromises for non-puppeting bridges that | ||
only operate in specific predetermined rooms. | ||
Comment on lines
+94
to
+97
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's the upside of doing it this way? Not needing admin access on the server? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is basically the same question as your first comment. The assumptions in both are correct: per-message profiles would allow bridging without admin access and with more encryption. Beeper is going to switch to local bridges with an encrypted cloud "backup". The backup isn't allowed to leak any metadata, which means the remote user profile info must be encrypted and even user IDs can't be in plaintext. I want to try to keep the room data as Matrix-compatible as possible, hence this MSC. There are rooms that use extremely ugly relaybot bridges even now (matterbridge), so there's clearly some demand for bridging without requiring admin access. This MSC would make those bridges look much nicer. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for explaining! Does this mean that encrypted state (MSC3414?) is another alternative? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To some extent yes, although that'd still leak some kinds of user IDs: even if the state keys were hashes or something, it'd still leak that a different user sent a message, which is more metadata than encrypted per-message profiles. It also wouldn't help with the non-admin-bridges |
||
|
||
This method also allows encrypting profile info, which reduces metadata leaked | ||
by bridging. | ||
|
||
### Feature-parity with other platforms | ||
Other chat applications such as Slack and Discord have "webhooks" which allow | ||
per-message profile overrides. This MSC effectively enables the same on Matrix. | ||
clokep marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
For example, Discord's [execute webhook](https://discord.com/developers/docs/resources/webhook#execute-webhook) | ||
API takes `username` and `avatar_url` as optional parameters. | ||
|
||
### Roleplaying, plural users, etc | ||
Some users want to be able to switch between profiles quickly, which would be | ||
much easier using this MSC. Currently easiest way is to have multiple accounts, | ||
which has other benefits, but is much more cumbersome to manage. | ||
|
||
## Potential issues | ||
Implementing encrypted avatars could cause difficulty for clients that assume | ||
that avatars are always unencrypted mxc URIs. | ||
|
||
## Alternatives | ||
tulir marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reminds me of MSC3464. This is more general than that MSC, though. |
||
### New state events | ||
Per-message profiles could be transmitted more compactly by defining the profile | ||
in a new state event and only referencing the state key in the message event. | ||
However, that approach wouldn't enable encrypting per-message profiles without | ||
inventing encrypted state events. Additionally, even with encrypted state | ||
events, some kind of sender identifiers would be leaked via state keys. | ||
|
||
### Appservices | ||
Appservices work perfectly fine for bridging already now, but they require | ||
admin access to a server, which is not available for everyone. Additionally, | ||
they have similar metadata issues as the "New state events" alternative above. | ||
|
||
For use cases involving a single human user, having multiple mxids (regardless | ||
of whether they're registered manually or via an appservice) complicates things | ||
unnecessarily. | ||
|
||
## Security considerations | ||
|
||
### Preventing impersonation | ||
To prevent impersonation using per-message profiles, clients should somehow | ||
indicate to the user that the message has a per-message profile with an easy | ||
way to see the user's MXID or default profile. For example, a client could have | ||
a small `via @user:example.com` text next to the per-message displayname. | ||
|
||
## Unstable prefix | ||
`com.beeper.per_message_profile` should be used instead of `m.per_message_profile` | ||
until this MSC is accepted. |
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:
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.
Implemented in Honoroit - helpdesk bot will send an unstable MSC4144 profile for each message in operators' room by default