Skip to content
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

MSC4133: Extending User Profile API with Key:Value Pairs #4133

Open
wants to merge 56 commits into
base: main
Choose a base branch
from
Open
Changes from 13 commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
0e85b3b
Extended profile fields
tcpipuk Sep 1, 2024
0f373db
Unstable client features
tcpipuk Sep 1, 2024
c5a3015
Clarification on limits
tcpipuk Sep 5, 2024
c8a5a1a
Warning about avatar_url and displayname limits
tcpipuk Sep 5, 2024
3157982
Error code clarification
tcpipuk Sep 5, 2024
b8ed87a
Whitespace fixes
tcpipuk Sep 6, 2024
a81f21f
Adjusted size limits
tcpipuk Sep 11, 2024
e688eb1
Clarified Canonical JSON
tcpipuk Sep 11, 2024
39d5fa2
Clarifications
tcpipuk Sep 13, 2024
e160c71
Clarifications
tcpipuk Sep 13, 2024
a9546aa
Remove UTF-16
tcpipuk Sep 13, 2024
0c43f50
Clarify key persistence
tcpipuk Sep 13, 2024
613411a
Out of date line
tcpipuk Sep 13, 2024
4a9557f
Clarify only `u.*` namespace is limited to 512 bytes
tcpipuk Sep 16, 2024
fbb4e44
Include read-only fields in capability
tcpipuk Sep 16, 2024
591999f
Change missing capability behaviour
tcpipuk Sep 16, 2024
15a0bd1
Typo correction
tcpipuk Sep 17, 2024
26c59f7
Privacy clarification for T&S
tcpipuk Sep 24, 2024
30e82aa
Consolidation and rewrite
tcpipuk Sep 25, 2024
2966c85
Whitespace fix
tcpipuk Sep 25, 2024
d97189e
Safety and security updates
tcpipuk Sep 25, 2024
ae19725
Clarify servers can hide fields
tcpipuk Sep 25, 2024
23a3a62
References to MSC4201 and MSC4202
tcpipuk Sep 26, 2024
f32932c
Clarify redacted `m.room.member` events
tcpipuk Sep 30, 2024
4afb8b8
Error codes and redundant instructions
tcpipuk Oct 1, 2024
bb4fc76
Removing custom fields
tcpipuk Oct 2, 2024
09318e8
Typo fix
tcpipuk Oct 11, 2024
9b4741e
Clarifications and readability
tcpipuk Oct 16, 2024
068d44e
Correct key length error to match common grammar limit
tcpipuk Nov 4, 2024
fa381da
Remove PATCH/PUT.
clokep Dec 20, 2024
b373a55
Merge pull request #1 from clokep/user-prof-fields
tcpipuk Dec 20, 2024
3349123
Removed redundant sections after `PUT` and `PATCH` methods removed
tcpipuk Jan 3, 2025
9fa0096
Re-add client feature for managing profile fields
tcpipuk Jan 4, 2025
da0a791
Update proposals/4133-extended-profiles.md
tcpipuk Jan 5, 2025
a948f5d
Clarify 403 error scenarios
tcpipuk Jan 5, 2025
c82dab6
Add section on caching behaviour under S-S API
tcpipuk Jan 5, 2025
21ad83f
Link to Canonical JSON in current spec
tcpipuk Jan 5, 2025
1726ef3
Cut down instructions for clients on when to display content from fed…
tcpipuk Jan 5, 2025
30d203e
Revert c82dab67d114ded78ef4b6a5a1f9f264002d6666
tcpipuk Jan 5, 2025
43e1e1a
Clarify caching and freshness challenges
tcpipuk Jan 5, 2025
af87bbe
Adjust abuse section
tcpipuk Jan 5, 2025
f686090
Authentication/rate-limiting/guest access requirements
tcpipuk Jan 5, 2025
17cc30b
Un-revert accidental revert of af87bbeb26c6d33725d970676009b52056a87f96
tcpipuk Jan 5, 2025
d620259
Simplify caching recommendations
tcpipuk Jan 7, 2025
c1b419a
Up to clients whether they check capability
tcpipuk Jan 10, 2025
4b3a8ed
Technically correct is the best kind of correct
tcpipuk Jan 10, 2025
0f41c82
Link to current federation profile endpoint
tcpipuk Jan 10, 2025
1b98d40
Mention check for spec version when using profile fields
tcpipuk Jan 10, 2025
9b2918e
Attempt to clarify what servers should not enforce about key naming
tcpipuk Jan 10, 2025
e00d2e9
Fix line wrapping after 9b2918e3735f5aec02f6309fcbc81feaca985804
tcpipuk Jan 10, 2025
a11286a
Add `M_MISSING_PARAM` error
tcpipuk Jan 13, 2025
2a86235
Clarify where errors apply
tcpipuk Jan 13, 2025
c4fa474
Merge branch 'matrix-org:main' into main
tcpipuk Jan 20, 2025
7ca83db
Clarify optional ability to not always federate every field
tcpipuk Jan 20, 2025
c7bb382
Fix inconsistent line wrapping
tcpipuk Jan 20, 2025
3843f27
Offer suggestions for hiding extended fields when member event redacted
tcpipuk Jan 21, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
398 changes: 398 additions & 0 deletions proposals/4133-extended-profiles.md
turt2live marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Member

Choose a reason for hiding this comment

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

Moving to a thread for discussion to take place - @MTRNord said:

So I am still not sure if this is a good idea.

I do like that we can represent timezones. I do not (and I am aware this was moved to $later) think this msc works well for many other fields. Pronouns for example are by nature freetext which means that MSC reintroduces one of the core issues which this MSC initially had. Imho dropping it here just delays this concerns but did not address it.

I am also not sure why there was no move towards instead “forking”/continuing the profiles as rooms instead. Why do we need to do it like this and compromise extremely on this? Why couldn't the time have been used on the other thing?

Missing is also how unstable/client specific namespaced fields can be moderated by room admins. This brings me back to my past concerns in my other comments. This again essentially allows unmoderated freetext fields which even more confusing may only show up in some clients. So it could a) target specific user groups and b) a room admin may not even see it and have people complain. This makes T&S quite a bit harder for room admins. For server admins it obviously is not an issue.

Last but not least I fear feature creep with this. Will we have now a UI related MSC for every field here? If I want to for example want to have my gender in this would this need to be another MSC because other want this? This feels like we are starting to micro manage the spec and I am not sure this is a good idea.

Copy link
Member

Choose a reason for hiding this comment

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

I'm failing to understand how this MSC creates problems for pronouns specifically. This MSC defines a generic key/value structure, where the value can be pretty much any type. This could be a user-supplied string, an object, or a boolean value depending on the key's requirements. If you have specific concerns with how the MSC is interfering with other MSCs, like pronouns, please leave inline comments for review.

This MSC also states it complements profiles as rooms, which is true: one of the concerns with profiles as rooms is it tries to do too much. By accepting this MSC, we're agreeing that arbitrary key/value pairs should be supported, which makes other MSCs easier to land. In essence, this is already a continuation of the work, just at an earlier stage than the current MSCs in the area. Forking the effort feels incorrect, given all the authors involved would like to work with each other towards a solution. If there's specific language which doesn't feel in line with this, please leave an inline comment for review.

As for room moderation: profile fields are deliberately kept at the user level in this MSC. A future MSC may introduce them to the room/member level as well. This makes the T&S model one where the server admin is responsible for the user's profile, not the rooms they are participating in. Room admins still have the option to eject users they don't feel fit their room's purpose, and can operate bots which scan profiles for potentially abusive content if they wish. Meanwhile, abusive users and their profiles should be reported to the homeserver admin, which this MSC calls out as the preferred mechanism for dealing with issues. A future, unrelated, MSC will make this easier. If there's specific areas which could be improved further, inline comments are appreciated for further review.

Creating an MSC for every feature may be what happens at the start of the transition towards this key/value system, but as we gain experience in reviewing these MSCs we'll be better able to calibrate the types of things which should be in the spec and which are best covered as unstable extensions. For example, we may prefer a general m.bio field over lots of fields for gender, websites, contact info, and interests. Or we may prefer to have a dedicated field for gender, and combine the rest under m.bio. These types of concerns are best expressed on the individual MSCs which get opened after this MSC lands - the influx is expected, and something we'd need to manage regardless.

Copy link
Contributor

Choose a reason for hiding this comment

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

I am currently on the move and cant draft a full reply in the meanwhile many of my concerns also have been raised by gnuxie at #4133 (comment) which likely answer some of the questions. I will write a proper reply once i am back at a computer :)

Copy link

@TheArcaneBrony TheArcaneBrony Jan 23, 2025

Choose a reason for hiding this comment

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

I am also not sure why there was no move towards instead forking/continuing profiles as rooms instead.

You mean #4201? Which exists just to give PaR another try.

Copy link
Member

Choose a reason for hiding this comment

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

@Gnuxie wrote:

Why is this MSC being considered in isolation of any specified custom profile field?

  • All fields contain user generated content.

  • No custom profile field has sufficiently demonstrated itself (via the spec process or otherwise).

  • There are no fields defined in this MSC

  • All fields used in the implementation are currently under review in other MSCs and have not demonstrated themselves.

Copy link
Member

Choose a reason for hiding this comment

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

Whilst we do make an effort to avoid speccing stuff that doesn't have a demonstrated purpose, there is a balance to make between that, and allowing things to land in manageable pieces. Historically, some features have struggled to make it through the spec process because their scope was just too broad. (MSC1849 was an example of that.)

Reviewing large MSCs is really hard (as is reviewing a large PR of any kind), just because everybody has to keep lots of context in their head for weeks or even months, and breaking them up helps build stable foundations before moving onto the next storey.

Further: in the case of this particular MSC, I see it mostly as a generalisation of the existing API. Even if we never end up landing anything like MSC4175, it doesn't feel like this MSC is adding undue clutter to the API.

Copy link
Member

Choose a reason for hiding this comment

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

@Gnuxie wrote:

The MSC does not propose anything in itself except a place to store user generated content... without demonstrating consideration for user generated content, especially free-text content.

  • Free-text content was originally part of the MSC, but got moved out to another proposal (MSC4208) to "resolve" numerous blocking concerns about it. But these concerns will appear in almost every single follow-up MSC related to specifying any field that builds on this proposal.

  • The MSC still has a provision to display and enter custom fields:

    Clients MAY provide a UI for users to view and enter custom
    fields, respecting the appropriate namespaces.

  • The demonstrated implementation uses MSC4175 which is a parsable field with a very narrow range of values. But this proposal is clearly intended to be followed up with fields for unparsable user generated content. And we expect there to be many more unparsable fields than restricted and narrowly defined ones.

I believe the MSC should be modified to address the concerns with free-text content. And also demonstrate implementation within a client that does add free-text fields.

The discussion will have to happen with subsequent MSCs unless they define fields that are both very limited and restricted, which is obviously not the intent of this proposal. So it does not make sense to discuss this proposal in isolation of those concerns.

Copy link
Member

Choose a reason for hiding this comment

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

I don't think I really understand the concern here. It feels like you're arguing against this MSC because you're concerned that people may, in the future, use it as a basis for other MSCs which bring problems. You've acknowledged yourself that such problems are not inherent by pointing to MSC4175, so it seems inappropriate to express your concerns on this MSC. If you have concerns with MSC4208, then they belong on MSC4208, not here.

  • Free-text content was originally part of the MSC, but got moved out to another proposal (MSC4208) to "resolve" numerous blocking concerns about it. But these concerns will appear in almost every single follow-up MSC related to specifying any field that builds on this proposal.

Yeeess, but then the time to discuss them is on those MSCs, not here.

  • The MSC still has a provision to display and enter custom fields:
    > Clients MAY provide a UI for users to view and enter custom
    > fields, respecting the appropriate namespaces.

To be clear, I'm reading this as: "clients MAY provide a UI for users to view and enter their own profile fields". On that basis, it's hard to see why this, on the face of it, is any different to, say, allowing users to send freetext events.

I must admit I'm not that familiar with the T&S space, so it's entirely possible I'm missing something here, but in discussions I've had with people who are more familiar with it than me, they've not been concerned about letting users set profile data: it's when clients start showing the profile data of other users that you need to be concerned. I'd be happy to be set straight here.

Copy link
Member

@ara4n ara4n Jan 24, 2025

Choose a reason for hiding this comment

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

I've just reread this MSC again, and would agree that we should defer abuse concerns for specific field formats in the MSC which defines that specific field. In terms of the custom fields in this MSC (e.g. someone publishing m.nasty.stuff: true on their profile) then yes, some clients may expose that to other users, and then it would surely be handled like any other abusive avatar or displayname today: you'd ignore or otherwise moderate the user. So, we can use the abuse potential of today's displayname/avatars as a precedent for how you'd handle this, and don't need to block on defining new mechanisms.

In other words, rather than waiting on future MSCs for new profile field types to land which flesh out antiabuse considerations which might then inform this MSC, let's keep some forwards momentum and actually land this as is - we can always have a future MSC for "antiabuse mechanisms common to different extensible profile fields" or something, if needed.

Copy link
Author

Choose a reason for hiding this comment

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

If it helps, that's roughly what I'm looking to achieve with #4208 and Jim has offered to help shape it, so I'm hoping we're off to a good start.

The hope is that we can define the dependencies for freetext content in profiles to be commonly allowed in clients, then other profile field MSCs have an easy reference to quote (or use as a dependency) to make sure they're also safe.

As always, I welcome feedback and would love to gather different perspectives so I can start translating that into firm technical requirements, then figure out whether MSCs already exist (or need to) for the dependencies.

Copy link
Contributor

@Gnuxie Gnuxie Jan 26, 2025

Choose a reason for hiding this comment

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

You've acknowledged yourself that such problems are not inherent by pointing to MSC4175, so it seems inappropriate to express your concerns on this MSC

But MSC4175 is a very simplified example, and it would be fair to suggest that MSC4133 would not be considered in the same way if its only function was to provide the timezone field or similar narrowly defined fields, such as a flag for whether a user is a bot. Therefore it does seem appropriate for me to express these concerns on this MSC.

it's hard to see why this, on the face of it, is any different to, say, allowing users to send freetext events.

Because there is already a significant amount of safety tooling for handling user generated content in events and all clients have been built with that in mind. With the profiles we are creating a new surface and new ways for users to interact. @turt2live has rightfully suggested in another comment #4133 (comment) that bots can scan profiles for abusive content, but this isn't something anyone has implemented at the moment. And we don't yet understand from this proposal and its implementations how profiles will be used for spam or abuse in Matrix's public rooms.

they've not been concerned about letting users set profile data: it's when clients start showing the profile data of other users that you need to be concerned.

Yes this is true, but it is clear that clients will need to display profile data for this MSC to have utility.

Copy link
Member

Choose a reason for hiding this comment

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

@Gnuxie wrote:

Why is there urgency to merge this MSC?

  • Clients can currently use the proposal to implement custom fields under the unstable namespace without any changes or hindrance. Some of them already have done, so there should be no urgency to get this merged.
  • Similar Concerns have been suppressed in Matrix rooms as bikeshedding or blocking the MSC. All developers are free to implement the proposal as is under the unstable flag. When the proposal becomes part of the specification it does not change the number of implementations, nor does it allow dependant MSCs to make any further progress.

Copy link
Member

Choose a reason for hiding this comment

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

Firstly, I'm sorry if your concerns haven't been heard. I don't think I've seen the discussions you refer to, and I wasn't aware of them before you raised them here. This is one reason we ask that concerns on MSCs be raised as comments on the MSC itself: conclusions in Matrix rooms get lost. Thank you for doing so now.

Secondly: I don't really see this as "urgency". The MSC has been 9 months in the making, and it feels like a relatively incremental change to the existing API. Honestly, it felt ready to land. I'll refer you to my earlier points that it can be very helpful to land MSCs incrementally rather than having a large amount to review all at once.

As the SCT, we've also had feedback in the past that it can be unreasonably difficult to get simple changes to the spec through the MSC process. There are numerous anecdotes from people who have just found the MSC process too arduous and have walked away in frustration. We have a balance to pick between rushing things into the protocol without due diligence, and letting the protocol ossify because changing it is just to damn hard.

All that said, you're right that this isn't actively blocking anything, and it's certainly not our goal to steamroller it through against significant opposition. On that basis: thank you again for raising your concerns. This is the FCP working as it should: we've put the FCP timer at least on hold for now and we'll see what can be done to address the concerns.

Whilst we can't promise that everyone is going to be delighted by every MSC that is accepted, it is important to make sure that members of the Matrix community have the opportunity to voice their concerns and that we take the time to consider those concerns properly.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'll refer you to my earlier points that it can be very helpful to land MSCs incrementally rather than having a large amount to review all at once.

I think this is what I mean by urgency. It does make sense that you would want to review MSCs in smaller pieces. And it does seem like at the moment the only formal tool to review and freeze MSCs is by landing them into the specification.

As the SCT, we've also had feedback in the past that it can be unreasonably difficult to get simple changes to the spec through the MSC process. There are numerous anecdotes from people who have just found the MSC process too arduous and have walked away in frustration. We have a balance to pick between rushing things into the protocol without due diligence, and letting the protocol ossify because changing it is just to damn hard.

Yes, this is a valid concern. Though I think there is another factor at play here, which is that clients may implement Matrix features selectively regardless of whether the features are specified in a spec release or an MSC. And at least some frustration comes from lack of implementation in a range of clients. Now I could misunderstand what people's frustrations have been, but to me that seemed to be close to the root.

The thing is this MSC does not bring any feature directly to the end user in Matrix clients. Do we believe that landing MSC4133 in specification will make a difference to the uptake of the dependent MSCs (which are still iterating) that will? It just seems unlikely to me.

On the other hand, we do need to keep MSC authors satisfied that their work is making progress, is valued. And I will concede that while contribution is scarce an optimistic merge makes sense. But there could be other ways of assuring and rewarding authors.

Original file line number Diff line number Diff line change
@@ -0,0 +1,398 @@
# MSC4133: Extending User Profile API with Key:Value Pairs

*This proposal aims to enhance the usability and richness of user profiles within the Matrix
ecosystem by introducing additional, customisable fields. This feature will facilitate the sharing
of more diverse user-defined public information across the federated network. The primary goal is
to enable users to publish a wide variety of possible information, such as preferred communication
languages, pronouns, public-facing organisation roles, or other relevant public details, thereby
enriching the user interaction experience without impacting existing functionalities.*

## Proposal

The Matrix protocol's current user profile structure supports very limited fields (`avatar_url` and
`displayname`). This proposal suggests expanding this structure to include custom fields, allowing
for a more versatile user profile. Specifically, it redefines the existing `avatar_url` and
`displayname` endpoints to be more flexible, while attempting to maximise compatibility with
existing clients and servers to help speed adoption.

Likewise, this proposal is designed to complement rather than replace
[MSC1769](https://github.com/matrix-org/matrix-spec-proposals/pull/1769) (Extensible Profiles as
Rooms). While [MSC1769](https://github.com/matrix-org/matrix-spec-proposals/pull/1769) offers a
more complex solution for extensible profiles, this proposal focuses on enabling the storage of
small, arbitrary key:value pairs at the global level.

This proposal does not seek to enforce the exact content or usage of these fields but rather to add
a framework for users to have extra data that can be further clarified and extended in the future
as community usage of these fields grows.

Homeservers could disable the ability for users to update these fields or require a specific list
of fields, but the intention of this proposal is that users will be presented with a form to enter
their own free-text fields and values. After using these very flexible fields, the community may
opt to request a further extension to promote one or more fields to be specified per-room via
tcpipuk marked this conversation as resolved.
Show resolved Hide resolved
member events.

### Client-Server API Changes

1. **GET `/_matrix/client/v3/profile/{userId}/{key_name}`**: This endpoint extends the existing
profile API to allow clients to retrieve the value of a specified `key_name` in a user's profile:

```json
{
"key_name": "field_value"
}
```

For example, requesting `/_matrix/client/v3/profile/@alice:matrix.org/displayname` would return:

```json
{
"displayname": "Alice"
}
```

2. **PUT `/_matrix/client/v3/profile/{userId}/{key_name}`**: This endpoint allows clients to set
the value of a specified `key_name`:

```json
{
"key_name": "new_value"
tcpipuk marked this conversation as resolved.
Show resolved Hide resolved
}
```

For example, setting `/_matrix/client/v3/profile/@alice:matrix.org/displayname` with:

```json
{
"displayname": "Alice Wonderland"
}
```

**Note**: As the `DELETE` endpoint exists below, a `PUT` to key using a `null` value should leave
the key in place without deleting the key.

1. **DELETE `/_matrix/client/v3/profile/{userId}/{key_name}`**: This endpoint removes a key (and
associated value) from the profile, if permitted by the homeserver. This could be considered a
partial alternative to [MSC3754](https://github.com/matrix-org/matrix-spec-proposals/pull/3754),
which specifies `DELETE` endpoints specifically for `/avatar_url` and `/displayname`.

2. **GET `/_matrix/client/v3/profile/{userId}`**: This endpoint retrieves all profile fields:

```json
{
"avatar_url": "mxc://matrix.org/MyC00lAvatar",
"displayname": "John Doe",
"u.Custom Field": "value1"
}
```

5. **PATCH `/_matrix/client/v3/profile/{userId}`**: This endpoint accepts a complete JSON object to
*merge* into the current profile, updating any changed keys without altering any absent ones:

```json
{
"avatar_url": "mxc://matrix.org/MyNewAvatar",
"displayname": "John Doe",
"u.Custom Field": "new_value1"
}
```

6. **PUT `/_matrix/client/v3/profile/{userId}`**: This endpoint accepts a complete JSON object to
replace the entire profile, adding or updating any changed keys and removing any keys that are
absent in the provided object:

```json
{
"avatar_url": "mxc://matrix.org/MyNewAvatar",
"displayname": "John Doe",
"u.Custom Field": "new_value1"
}
```

**Note**: User-interactive clients are encouraged to manipulate fields individually to avoid race
conditions, however this `PUT` method allows single-client accounts (such as bots) to overwrite the
entire profile in a single request, which allows bridge bots managing many accounts to bulk update
profiles for their users with minimal requests.

### Server-Server API Changes

**GET `/_matrix/federation/v1/query/profile`** will mirror the client-server API changes to ensure
profile information is consistently available across the federated network.

As there is no method to verify the history of these fields over federation, this endpoint must
only accept requests for local users on the current homeserver, and homeservers must only request a
profile from the homeserver specified in that user's MXID.

As per the current stable endpoint, it accepts an optional `field` query string parameter to
request a single field. At time of writing, the Matrix specification says:

> If no `field` was specified, the response should include the fields of the user's profile that
> can be made public, such as the display name and avatar.

Given this wording, homeservers currently already have the flexibility to decide whether some
fields are published over federation, and this proposal continues to allow this behaviour.

### Capabilities

A new capability `m.profile_fields` is introduced to control the ability to set custom profile
fields.

- **Advertising the Capability**: Servers SHOULD advertise this capability in the `capabilities`
object returned by the `GET /_matrix/client/v3/capabilities` endpoint.

- **Checking the Capability**: Clients SHOULD check for the presence and value of the
`m.profile_fields` capability before attempting to create or update custom profile fields.

- **Capability Structure**:

```json
{
"capabilities": {
"m.profile_fields": {
"enabled": true
}
}
}
```

- **Backward Compatibility**: For backward compatibility, clients SHOULD assume that extended
profile fields are not supported if this capability is missing from the server's advertised
capabilities.
tcpipuk marked this conversation as resolved.
Show resolved Hide resolved

- **When `enabled` is `false`**: Clients SHOULD expect to read and display extended fields but
SHOULD NOT allow users to create or update custom fields. Any attempt to do so may result in a
`403 Forbidden` error.

- **When `enabled` is `true`**: Clients MAY allow users to create or update custom fields. However,
individual updates may still receive a `400 Bad Request` or `403 Forbidden` response from the
homeserver if specific server-side policies prevent the action.
Half-Shot marked this conversation as resolved.
Show resolved Hide resolved

### Error Handling

To ensure clear communication of issues, the following error codes and messages will be used:
anoadragon453 marked this conversation as resolved.
Show resolved Hide resolved

#### 400 Bad Request: When request is malformed, exceeds limits, or the profile larger than 64KiB

- **Error code for malformed request**: `M_BAD_JSON`

```json
{
"errcode": "M_BAD_JSON",
"error": "The provided JSON is malformed."
}
```

- **Error code for profile/field exceeding size limit**: `M_TOO_LARGE`

```json
{
"errcode": "M_TOO_LARGE",
"error": "The profile data exceeds the maximum allowed size of 64KiB."
}
```

or

```json
{
"errcode": "M_TOO_LARGE",
"error": "Profile field u.Bio exceeds maximum allowed size of 512 bytes."
}
```

or

```json
{
"errcode": "M_TOO_LARGE",
"error": "The key name exceeds the maximum allowed length of 128 bytes."
}
```

or

```json
{
"errcode": "M_TOO_LARGE",
"error": "The user has exceeded the maximum number of allowed keys in their profile."
}
```

#### 403 Forbidden: User lacks permission to take this action (e.g. restricted by server policy)

**Note:** See [MSC4170](https://github.com/matrix-org/matrix-spec-proposals/pull/4170) for more
discussion on how server policy may result in 403 errors for profile requests.

- **404 Not Found**: When attempting to `GET` or `DELETE` a profile key that does not exist:
- **Error Code**: `M_NOT_FOUND`

```json
{
"errcode": "M_NOT_FOUND",
"error": "The requested profile key does not exist."
}
```

### Propagation of Profile Fields to Membership Events

The existing fields, `avatar_url` and `displayname`, will continue to trigger state events in each
room. These fields are replicated per-room via member events. Custom fields, however, will **not**
tcpipuk marked this conversation as resolved.
Show resolved Hide resolved
trigger state events in rooms and will exist solely at the global level for storing metadata about
the user.

- **avatar_url** and **displayname**: Changes to these fields will generate state events in all
rooms the user is a member of.
- **Custom fields**: These are stored in the user's global profile and do not generate state events
in rooms.

### Key/Namespace Requirements for Custom Fields

Homeservers are not expected to enforce these namespaces, as future expansions may be unknown to
the server, but clients are expected to use the correct namespace for field creation/updates.

- The namespace `m.*` is reserved for fields defined in the Matrix specification. This field may
have special entry/display requirements that are defined in the Matrix specification. If a client
does not recognise a field in this namespace, it may attempt to display it, but should not
attempt to update the content in case it has special requirements.
- The namespace `u.*` is reserved for user-defined fields. The portion of the string after the `u.`
is defined as the display name of this field. These user-defined fields will always be string
format, and as measured in UTF-8 byte counts, the key and value must not be longer than 128 bytes
and 512 bytes respectively.
- Client-specific or unstable fields MUST use the Java package naming convention: `tld.name.*`.

tcpipuk marked this conversation as resolved.
Show resolved Hide resolved
Following support for this specification change, a user could enter a "My Timezone" field manually
in their client and the client would be expected to add a `u.My Timezone` key in their profile.
However, this would be expected to be a string value, even if the user types "null" or an integer
into the box.

In contrast, [MSC4175](https://github.com/matrix-org/matrix-spec-proposals/pull/4175) would use the
unstable key `us.cloke.msc4175.tz` and following approval would then support clients using the
`m.tz` key with the values/validation that MSC requires.

### Size Limits

Whenever "bytes" are referred to as a limit, this is calculated as UTF-8 bytes, so a two-byte code
point consumes two bytes of this limit. This size would be measured before any JSON encoding.

Until another MSC specifies otherwise:

- Each profile *must* be *at most* 64KiB (65536 bytes) in size, as measured in Canonical JSON.
- Each key *must* be a string of *at least* one byte and *must* not exceed 128 bytes.
tcpipuk marked this conversation as resolved.
Show resolved Hide resolved
- Each value in the `u.*` namespace *must* not exceed 512 bytes in length.
- The limit on overall profile size includes `avatar_url` and `displayname`.

### Implementation Details

- This feature will be implemented as optional but recommended, enabling a smooth transition and
minimal disruption to existing deployments.
tcpipuk marked this conversation as resolved.
Show resolved Hide resolved
- The profile data will be public by default, and compliance with GDPR and other privacy
regulations will be enforced, particularly in terms of data deletion and retention policies.
tcpipuk marked this conversation as resolved.
Show resolved Hide resolved
tcpipuk marked this conversation as resolved.
Show resolved Hide resolved
- Custom fields will not trigger state events in rooms, maintaining account-wide metadata without
tcpipuk marked this conversation as resolved.
Show resolved Hide resolved
creating state events or other moderation issues.

## Potential Issues

Initial challenges are primarily ensuring uniform support for custom fields across different
servers and clients during the rollout phase: users may come to expect that other users will check
their supported languages before communicating with them, but the sender's server does not support
custom profiles.

As such, this MSC is designed to be as simple as possible to get initial functionality and data
structures implemented widely in both clients and servers, so further extensions can be debated,
implemented, and tested over time.

As this data is stored only at the global level, it won't allow users to modify fields per-room,
or track historical changes in profile fields. However, this is for performance and moderation
reasons, as many users will struggle to maintain many fields of personal data between different
rooms, and publishing state events for every field change could become an additional burden on
servers and moderators.
tcpipuk marked this conversation as resolved.
Show resolved Hide resolved

In a similar vein, this proposal offers no method to "broadcast" to other users or homeservers that
changes have occurred. This is intentional to keep the scope of this change narrow and maximise
compatibility with existing servers. A future proposal may wish to use an EDU (such as Presence) to
notify users and homeservers that these custom fields have been updated.

## Alternatives
tcpipuk marked this conversation as resolved.
Show resolved Hide resolved

An alternative could be to allow for more specific endpoint modifications or to introduce a
completely new API specifically for extended information. However, these approaches could lead
to more significant changes to the existing API and higher complexity for client developers.

### Security Considerations

Since the profile data is public, there are minimal security risks associated with the transmission
of sensitive information; however, users should be made aware that any information they add will be
visible to others on the federated network.

Clients *should* inform users that any custom profile fields they add will be publicly accessible,
and *should* discourage users from adding sensitive personal information to their profiles.

Homeservers and clients *must* comply with GDPR and other relevant privacy regulations, particularly
regarding data deletion and retention. Profile data *should* be cleared when a user is deactivated.
While homeservers *should* cache remote profiles, they *should* implement strategies that do not
exceed 24 hours to minimize the risk of unintended data persistence.

## Unstable Prefixes

### Unstable Profile Fields

The current Matrix specification technically already allows extra custom fields to be published in
a user's profile. However, as this proposal introduces additional requirements and allows custom
user-defined fields, an unstable prefix should be used on these fields until this proposal has
entered the API as stable:

```json
{
"avatar_url": "mxc://matrix.org/MyC00lAvatar",
"displayname": "John Doe",
"uk.tcpip.msc4133.u.Custom Field": "field_value"
}
```

### Unstable Endpoints

`/_matrix/client/unstable/uk.tcpip.msc4133/profile/{userId}` would be necessary for the `PATCH` and
`PUT` methods allowed when the unstable capability (detailed below) is advertised by the server.

The existing `GET` method would act as normal and remain on `/_matrix/client/v3/profile/{userId}`
without need for an unstable endpoint.
tcpipuk marked this conversation as resolved.
Show resolved Hide resolved

Likewise, when the unstable capability is advertised by the server, the server should accept the
new key endpoints `/_matrix/client/unstable/uk.tcpip.msc4133/profile/{userId}/{key_name}` which
would then promote to `/_matrix/client/v3/profile/{userId}/{key_name}` when the stable capability
is advertised following this specification change.

### Unstable Client Capability

The client capability `m.profile_fields` should use this prefix until stable:

```json
{
"capabilities": {
"uk.tcpip.msc4133.profile_fields": {
"enabled": false
}
}
}
```

### Unstable Client Features

The client feature `uk.tcpip.msc4133` should be advertised on the `/_matrix/client/versions`
endpoint when the `PUT` and `PATCH` methods are accepted on the
`/_matrix/client/unstable/uk.tcpip.msc4133/profile/{userId}` endpoint.

Once this MSC is merged, the client feature `uk.tcpip.msc4133.stable` should be advertised when the
`PUT` and `PATCH` methods are accepted on the `/_matrix/client/v3/profile/{userId}` endpoint until
the next spec version where this endpoint is officially written into the spec, e.g.

```json
{
"unstable_features": {
"uk.tcpip.msc4133": true,
"uk.tcpip.msc4133.stable": true
},
"versions": [
"v1.11"
]
}
```