X Tutup
Skip to content

MSC4426: User Status Profile Fields#4426

Open
anoadragon453 wants to merge 6 commits intomainfrom
anoa/user_status_profile_fields
Open

MSC4426: User Status Profile Fields#4426
anoadragon453 wants to merge 6 commits intomainfrom
anoa/user_status_profile_fields

Conversation

@anoadragon453
Copy link
Member

@anoadragon453 anoadragon453 commented Feb 25, 2026

Rendered

Disclosure: I am a member of the Matrix Spec Core Team (SCT) and am employed by Element. This proposal is written and published with my Element hat on to improve clarity when messaging users in a team-based environment. I'm also personally excited to advance user-scoped profile information in Matrix, with these fields being just the beginning.

@anoadragon453 anoadragon453 changed the title MSCXXXX: User Status Profile Fields MSC4426: User Status Profile Fields Feb 25, 2026
@anoadragon453 anoadragon453 added improvement A suggestion for a relatively simple improvement to the protocol proposal A matrix spec change proposal client-server Client-Server API kind:feature MSC for not-core and not-maintenance stuff needs-implementation This MSC does not have a qualifying implementation for the SCT to review. The MSC cannot enter FCP. proposal-in-review labels Feb 25, 2026
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implementation requirements:

  • Client (sending)
  • Client (rendering)

Comment on lines +136 to +155
#### Moderation

A free-form, user-controlled text field that can be displayed in clients to
other users is a prime opportunity for spammers and malicious actors. Attacks
include:
* Displaying hate speech
* Linking to malware/phishing content
* With custom emoji support, displaying explicit/illegal imagery by their display name across the app

As user status is tied to a user - rather than a room - simply kicking a user from a room may not immediately solve the issue.

* Clients should take care not to display associated status emoji/text in
membership change messages (i.e. “User 🌴 was kicked from the room).
* The emoji in question may appear in the results of a user search (clients
SHOULD NOT display these by default. Instead, require the user to perform
some explicit action first, e.g. inviting the user to a room or DM.)
* To remove offensive material from the room timeline and members list, a
moderator should kick/ban the user. A client that displays the status
information in the timeline should stop doing so if the user has left/been
kicked from the room.
Copy link
Contributor

@Gnuxie Gnuxie Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concerns about free-text were deferred during the review process of MSC4133 and did not receive proper review or consideration. It's not fair to the first proposer of an MSC with free-text or any user generated content has to solve the problem on their own and also get the burden of me and others writing review about it on their proposal.

When it was always inevitable and clear that the merit of MSC4133 was to handle user generated content

Copy link
Contributor

@Gnuxie Gnuxie Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to see an MSC that allows room moderators or their tooling to review profiles proactively. To start with this would mean an MSC that can trace history and updates to global profiles so that moderators can review them.

Copy link
Contributor

@Gnuxie Gnuxie Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Who reviews profiles, and approves profiles, needs thinking about.

One option is to make the homeserver admin and their tooling responsible for reviewing global profile changes (which would be deferred/assisted by distributed moderation via policy lists). This seems like the easiest place to intervene rather than deferring to room moderators directly.

Copy link
Contributor

@Gnuxie Gnuxie Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes sense to use reasonable metrics like a common direct message to be able to see the profile. Another important rule would be that the moderator of a room in common with the user should always be able to see their profile (unless the user's profile has been blocked on the server, but they will need to know that it has been blocked so they can ban them).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for engaging on this @Gnuxie!

Who reviews profiles, and approves profiles, needs thinking about.

One option is to make the homeserver admin and their tooling responsible for reviewing global profile changes (which would be deferred/assisted by distributed moderation via policy lists). This seems like the easiest place to intervene rather than deferring to room moderators directly.

I agree that doing moderation at a room level for user-scoped data doesn't really make sense. A user's profile can appear through a user search (completely disconnected from a room). You could share multiple rooms with a user, and it'd then be unclear which policyserver to ask.

I like the idea of proactive moderation at the homeserver level. Though I don't think human moderation of all profile updates can really scale. Profiles can appear over through federation transactions (eventually MSC4259) or via manual queries. It's not unreasonable for those to be checked by a locally-configured policyserver before they're sent down to clients.

The recent policyserver system of signing messages doesn't really work here, as every homeserver would probably be using a different policyserver (and wouldn't trust signatures from other ones).

It makes sense to use reasonable metrics like a common direct message to be able to see the profile.

I caution against preventing profiles from being sent to clients entirely. This doesn't matter as much with User Status, but for an m.bio profile field (plus avatar and displayname), I would find that helpful to see before opening a DM with someone, to ensure that I'm messaging the right person. It makes sense for clients to hide this information behind an interaction though.

And in a workplace environment, all users are "trusted" already, so such a barrier likely isn't necessary and will just frustrate people. So it needs to be able to be disabled.

So bottom line: I'm interested in proactive tooling, and am curious what the spec can do here to enable that (another policyserver endpoint?). Currently, I could see implementations mostly solving this on their own by hooking into the profile set/fetch endpoints and sending the request off to a policyserver before allowing/denying the request. The policyserver would be configured in the homeserver config, instead of in room state.


Another important rule would be that the moderator of a room in common with the user should always be able to see their profile (unless the user's profile has been blocked on the server, but they will need to know that it has been blocked so they can ban them).

Future plans in this area involve only sharing a profile with certain users (i.e. your family vs. your more excentric friends). This invites the possibility to hide one profile from room moderators, while showing it to users. However, other messaging apps do allow this (i.e. Telegram) and I'm not aware of this being a problem (perhaps the reporting system works well enough?). You can even change your avatar based on who's looking.

Something to think about for a future "multi-profile" / "profile privacy" MSC.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How would CSAM reach the client? Via a link in a status message? Would tooling follow links and check for images and scan those?

Yes potentially and there are other MSCs such as #4427 where this is more relevant.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Future plans in this area involve only sharing a profile with certain users (i.e. your family vs. your more excentric friends). This invites the possibility to hide one profile from room moderators, while showing it to users. However, other messaging apps do allow this (i.e. Telegram) and I'm not aware of this being a problem (perhaps the reporting system works well enough?). You can even change your avatar based on who's looking.

Actually, this is also possible with this proposal by federating one status to one homeserver, and a different one to another.

Copy link
Contributor

@Gnuxie Gnuxie Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However, other messaging apps do allow this (i.e. Telegram) and I'm not aware of this being a problem (perhaps the reporting system works well enough?). You can even change your avatar based on who's lookin

Multiple profiles might not be a problem but user generated content in profiles is a problem and we shouldn't just settle when all the other companies have way more resources than we do to fire hose profiles down than we do. And also the reputational clout and inertia to soak up things going wrong. The direction matrix is heading in at the moment with policy server genuinely makes it close to being a leader in safety. And we should keep going. Yeah no other protocol might not take profiles as seriously as i am proposing here but we should and we should lead.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can write this proposal. But please let's stop looking for excuses out of solving the problem.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, please do!

@Half-Shot Half-Shot self-requested a review February 25, 2026 20:54
emoji, even if it’s valid to the client and other clients.


## Alternatives
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about presence? That is what other clients already use and if you start sending out profile change events every time you start or end your call in addition to possible status messages about what song you are currently listening to, you likely have the same performance characteristics as presence events.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Presence was initially considered for this project (and should indeed be listed in the alternatives here). It would not take much to re-use the status_msg field and add a status_msg_emoji field beside it.

But profile fields have a few advantages:

  • They have simple semantics for multiple, distinct fields. This proposal introduces m.status and m.call. But if you eventually add m.music, m.application/game, m.holiday etc. you'd end up with quite a fat presence object with no way for clients to selectively query (or opt-in to selective updates via /sync) parts of it. You'd need to build out those semantics as well.
  • Presence currently exists, but is disabled everywhere. Part of using presence is a political problem: you need to convince everyone to turn it back on. Many homeserver implementations and distributions disable it by default, which would significantly slow the roll-out of any feature built on top of it.
  • Profile fields are a burgeoning feature, but haven't quite crossed the threshold of being widely used yet. We wanted this work to help push it over that line.

I actually initially wanted to build this on presence; finally a reason to refactor it and make it usable! But the above eventually muddied that vision.

I do still want to improve presence - but that's probably best left to an effort specifically targeting/optimising for its featureset (quick online/offline/busy indicators).

And on the performance front:

  1. (We discussed before) that profile updates will generally be much less frequent than presence updates by default. Of course you can limit profile or presence updates however you like on your own homeserver/client. Profile fields make it easy to set different rate-limits/debouncing logic for each field ID, e.g. you could limit m.call updates much more strictly than m.music.
  2. I think limiting who can see which profile will significantly cut down on the traffic. A mechanism for allowing anyone to see your avatar/displayname, but only friends seeing your current song, would go a long way. Presence didn't have such a granular level of user-controlled recipients. I currently have a draft MSC for profile privacy fleshing this out, and will publish it soon.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I expanded on the performance discussion over on the Profile Fields federation MSC: https://github.com/matrix-org/matrix-spec-proposals/pull/4259/files#r2858835260

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And wrote a summary on the MSC itself: d1b8f85.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe an appropriate method of doing this is more akin to the Discord API's custom status system - the "Type" is one of PLAYING/WATCHING/LISTENING TO/STREAMING/etc and then there's free form text. They don't need to be separate fields I feel.

Users should not put security sensitive information in `m.status`. Clients MAY
wish to remind them of this.

## Privacy Considerations
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Access control for profile look-ups is configured by the homeserver admin and, I think, clients have no way of knowing what the configuration is. Is there a risk here that anyone on the same server could spy on your availability updates?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Access control for profile look-ups is configured by the homeserver admin and, I think, clients have no way of knowing what the configuration is.

It will depend on the homeserver implementation. The spec recommends that 403 always be returned, whether profile lookup is denied or the user does not exist. But Synapse will return a 404 in the latter case.

Is there a risk here that anyone on the same server could spy on your availability updates?

The spec currently requires that profile information should be shared with those users you share a room with. This is based off the old notion that a profile is only an avatar and displayname. It makes sense to always share those with users you share a room with.

Currently I think this is fine, even if you're on matrix.org. I'd want to share my availability with any user that might message me, and that means those users whom I share a room with.

Critically you should not allow sharing profile information if you've only been invited to a room. That would allow anyone to start a DM with you and then fetch your profile without your consent. Homeserver implementations already have this limitation in place this for profiles, though.


There is certainly room for further restricting the circle of who you'd want to share your availability with (just work colleagues, on a public homeserver), but this MSC doesn't aim to address that. An separate MSC I have in the works does, though!

Copy link
Contributor

@Johennes Johennes Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The spec currently requires that profile information should be shared with those users you share a room with.

Yes, I think that is totally sensible. What I'm trying to say is that the spec only declares this as the minimum. It doesn't prevent home servers from allowing profile look-ups regardless of room membership though. The client has no way of knowing what policy the server enforces. So my availability might be made available to anyone on the same server.

This is a problem of profile data in general of course. It just feels like the status introduced here is something that as user I would explicitly not want to share with just anyone.

Maybe a compromise could be to introduce a way for clients to find out what look-up rules the server enforces on profiles, e.g. through a capability?

| Field | Type | Required | Description | Example |
| :---- | :---- | :---- | :---- | :---- |
| `text` | `string` | Yes | The user’s chosen status text. Does not support HTML. Clients MAY choose to linkify links. | “On holiday in …” |
| `emoji` | `string` | Yes | The user’s chosen status emoji. | 🌴 |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Being able to set an emoji is cool but I feel like what's missing is a status category a la available, away, etc. I think it would be a lot more useful if you could tell at a glance whether somebody is available or not without having to decipher the meaning of their status emoji.

Here's what Teams does, for instance:

Image

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels like it's treading on the toes of presence a smidge, but unsure. If so, we could potentially standardize on some "m." status messages which helps with a11y-ing.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Different companies and communities will have different cultures. I'm not sure if we need to standardise on a set of emojis and messages for every use case ever. At Element, we usually use: 🤒 (sick), 🌴 (holiday), 👶 (m/paternity leave), etc. But other companies probably have their own set.

It makes sense for certain clients to have certain (configurable) defaults - or even have the homeserver suggest some via /capabilities. But I've specifically avoided hardcoding defaults into the spec. It makes more sense to leave it up to specific enterprises, apps, etc.

If so, we could potentially standardize on some "m." status messages which helps with a11y-ing.

I touched on internationalisation in the MSC:

### Internationalisation
Often a user may set their status in one language, and it will be viewed by a
user who primarily uses another language. This MSC explicitly does not include a
method for setting multiple statuses in multiple languages:
1. This would expand the scope of implementation noticeably.
2. A UI where a user could set multiple statuses in different languages is not
something users are familiar with in messaging apps today.
Clients are free to provide some suggested default status texts and emoji, and
they may do so based on the user's chosen language in the application.
A future MSC may allow setting a different status *per-community*, which would
be a more familiar way for users to communicate in different languages with
different social groups.

Having a specific set of statuses would be a requirement, and the above explains why I don't think that's necessary in practice (maybe it will be after implementation and people try it, who knows!).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't necessarily mean to switch to a fixed set of status messages and emojis. Rather to add another field a la category = available | do_not_disturb | away | ... that would let others quickly recognize the type of availability.

It feels like the freeform text and emoji could introduce quite a bit of ambiguity. For instance, I might be feeling sickly while still working, thus using 🤒, or I might actually be working from the beach, thus using 🌴. There is value in being able to express that via the status. What I really need in a work context though is more of a binary "can I reach this person" cue.


| Field | Type | Required | Description | Example |
| :---- | :---- | :---- | :---- | :---- |
| `call_joined_ts` | `number` | No | The time that the user joined the call. Unix timestamp in seconds. This allows users to see how long someone has been in a call. | 1770140640 |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While we're here, maybe we could add an optional presenting field indicating whether the user is currently screen sharing? The rationale is that somebody who's presenting will most definitely not read your messages while being in a call while somebody who's not presenting might.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That feels a little weak to me. For instance, I could be leading a meeting without screen sharing; or I could be sharing a slide deck for someone else who's narrating it, while I'm just listening for the word "next" to hit a button.

It's also a slight metadata leak.

Matrix clients could include this information already, if you're in the room with the call (but not necessarily in the call yourself). MatrixRTC defines events for screen-sharing which your client could pick up in the background and display in a user's profile UI. That eliminates the metadata leak concern as well.

Copy link
Contributor

@Johennes Johennes Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Teams has this feature for whatever that's worth and I've personally found it useful. It's not a definite metric, true. But it gives you another hint of what the chances are that the other person will read and respond to your message.

I don't see this as a material metadata leak when we're already sharing that you are in a call and since when. I would also see it as an optional property so clients could still choose whether or not to fill it.

All that being said, I don't think this is a critical feature. It might as well be offloaded to a separate proposal if it is deemed controversial.

with more than one grapheme. This is due to Unicode byte to grapheme definitions
being continuous added over time.

`m.call`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems weird that this a separate field if it is tied this close to status?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another advantage of the separate field is that it gives a hint to Matrix clients that you're on a call. They can then display that fact separately from your status - or try and pull in more information about the call (title, join link, etc.) if you happen to share a room with the user and they're using MatrixRTC.

The same goes for the theoretical m.holiday field. If a user is explicitly on holiday, you may want to display a much louder warning when trying to message them. See this example from Google Doc's comments UI:


image

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not a field under the m.status though?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that the fields are largely related, and typically if a client wants one of these fields, they probably want both.

But it might still be useful to be able to refer to them separately. Perhaps a company wants to allow their employee to share some pre-defined statuses to partner companies, but keep whether someone is on a call internal-only. Assuming that's realistic, having these be separate fields makes configuring that easier.

The argument is stronger for other field types (such as m.holiday above). Google Docs would only query for m.holiday when you type a comment - not m.status. Or in a world of scoped access tokens, you'd only want to give your HR software access to modifying m.holiday. Perhaps the same argument can be made for separate calling software (e.g. Element Call) and not allowing it to read/modify m.status.

Having these be separate fields out of the gate does set a precedent in that direction, at the very least.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was confused about the split, too, but I think the shape of the profile API (where you read and write by top-level key) and the ability to restrict access to parts of the profile in future are good arguments. 👍

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds like this needs to be included in the MSC then.

Comment on lines +50 to +53
Applications SHOULD NOT automatically update this field. It’s intended to be
controlled by the user manually, and it may be confusing for most users if their
manually-set status is overridden by an application they may have no control
over.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can be pretty helpful to automatically clear this field out or for the server to set it automatically, this paragraph seems to say these things should not happen.

Additionally, was it considered to add an "end time" to the status?

Copy link
Member Author

@anoadragon453 anoadragon453 Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@clokep both of your comments (link) are intertwined. m.call as a separate field makes it easier for calling software to avoid accidentally overwriting your manually-set status as you join/leave meetings. As such, m.call is primarily meant to be updated automatically.

Whereas I put the no-automation warning on m.status to dissuade applications from building on it as a mechanism for showing public information about a user (which may then trample on top of a user's manually set status).

The warning is currently quite broad (discouraging automatic updates). And you're right - it does prevent the use case of "please clear this status after I come back from holiday on 08/25" or "after 30m", etc. Which are really nice to have!

So I think this needs to be rewritten or removed. Perhaps we can just trust that applications won't cause bad experiences for users... because then they wouldn't be popular?

Comment on lines +7 to +9
When working in a team, it can be useful to share more rich information. A short
blurb about what you’re currently up to, whether you’re currently on holiday, or
if you’re in a meeting and won’t be looking at messages for a short while.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this what the status field in presence was for? This feels more like duplication?

Comment on lines +217 to +218
Neither of these fields need to be particularly *real-time* either, so waiting a
bit for updates before publishing them to other users can also be effective.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels valid for general status information such as OoO, sick, etc. For calls, however, would you not actually want to know whether somebody is in another call right now? Otherwise you may call them yourself only to realize that they're blocked and the server just hasn't published the information, yet.

added. It is already sent proactively to clients and over federation to other
homeservers.

But profile fields have a few advantages:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Profiles also have disadvantages, the most prominent one being that the data needs to be queried on demand. This makes it infeasible for clients to use the status in room or member lists (where many other messaging systems appear to be including availability information). Maybe it would help to make the intended scenarios in which a client would fetch and display the data a little more explicit?

| Stable identifier | Unstable identifier |
| :---- | :---- |
| `m.status` | `org.msc4426.status` |
| `m.call` | `org.msc4426.call` |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you a word there

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

client-server Client-Server API improvement A suggestion for a relatively simple improvement to the protocol kind:feature MSC for not-core and not-maintenance stuff needs-implementation This MSC does not have a qualifying implementation for the SCT to review. The MSC cannot enter FCP. proposal A matrix spec change proposal proposal-in-review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants

X Tutup