Skip to content

Spec for MSC4133: Update profile endpoints to support extended fields #2071

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

Open
wants to merge 58 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
fdc012a
Describe MSC4133 profile endpoint changes
tcpipuk Feb 13, 2025
212377e
Merge branch 'matrix-org:main' into MSC4133
tcpipuk Feb 14, 2025
1fc0118
2071 change log
tcpipuk Feb 14, 2025
b2e122f
Update changelog from `clarification` to `feature`
tcpipuk Feb 14, 2025
59d2c62
Link to MSC4133 in endpoint descriptions
tcpipuk Feb 14, 2025
ee9b5dd
Correct types and errors
tcpipuk Feb 14, 2025
8e9874a
Simplify change log
tcpipuk Feb 14, 2025
41c64c8
Linkify MSC4133 in change log
tcpipuk Feb 14, 2025
82adcec
Clarify `avatar_url` should be MXC
tcpipuk Feb 14, 2025
4f8999b
Tweak wording on full profile `GET`
tcpipuk Feb 14, 2025
992cf9d
Clarify `null` behaviour for `PUT` and `DELETE`
tcpipuk Feb 14, 2025
3311b08
Alphabetise `avatar_url` and `displayname` and remove redundant descr…
tcpipuk Feb 14, 2025
f3c269d
Added capability
tcpipuk Feb 14, 2025
9327793
Inline information from MSC4133, remove links
tcpipuk Feb 14, 2025
5d5b561
Deprecate `m.set_displayname` and `m.set_avatar_url` capabilities
tcpipuk Feb 14, 2025
76b48e2
Specify CNIG pattern for custom fields
tcpipuk Feb 14, 2025
79a1cde
Remove reference to spec version in `m.profile_field` capability
tcpipuk Feb 14, 2025
17af55d
Fix broken link
tcpipuk Feb 14, 2025
79af780
Camel case for endpoint variables
tcpipuk Feb 14, 2025
1cc93ec
Attempt to make descriptions look better in HTML rendered spec
tcpipuk Feb 14, 2025
0b0942d
Clarify capability lists should support wildcards
tcpipuk Feb 14, 2025
7a3b0c0
Clarify in change log that `m.set_avatar_url` and `m.set_displayname`…
tcpipuk Feb 14, 2025
9859e20
Don't use reference for capability.
tcpipuk Feb 20, 2025
013502b
Mention replacement for `m.set_displayname` and `m.set_avatar_url` ca…
tcpipuk Feb 20, 2025
9889fe3
Use more accessible terminology than "glob"
tcpipuk Feb 20, 2025
3a5e555
Correct `PUT`/`GET` payload definitions
tcpipuk Feb 20, 2025
7ef1d9d
Add `x-changedInMatrixVersion`
tcpipuk Feb 20, 2025
b5e2edf
Add `x-addedInMatrixVersion`
tcpipuk Feb 20, 2025
d8cc250
Tag `x-addedInMatrixVersion` on `additionalProperties` in entire prof…
tcpipuk Feb 20, 2025
37b1362
Attempt to describe variable payload content
tcpipuk Feb 20, 2025
50eab35
Standardise line-wrapping and update `avatar_url` format to `mx-mxc-uri`
tcpipuk Feb 21, 2025
dd4ea94
Clarify why `avatar_url` and `displayname` can't be returned as `null`
tcpipuk Feb 21, 2025
6183f24
Clarify value validation requirements
tcpipuk Feb 21, 2025
6646146
Accept minor suggestions from code review
clokep Jun 13, 2025
569c8aa
Merge upstream main into MSC4133
tcpipuk Jul 31, 2025
5a08263
Update data/api/client-server/profile.yaml
tcpipuk Jul 31, 2025
b834933
Update data/api/client-server/profile.yaml
tcpipuk Jul 31, 2025
648c050
Update data/api/client-server/profile.yaml
tcpipuk Jul 31, 2025
48ee9cf
Update data/api/client-server/profile.yaml
tcpipuk Jul 31, 2025
9357cea
Update data/api/client-server/capabilities.yaml
tcpipuk Jul 31, 2025
3f5c14b
Update data/api/client-server/capabilities.yaml
tcpipuk Jul 31, 2025
22a3405
Update data/api/client-server/capabilities.yaml
tcpipuk Jul 31, 2025
6a8b542
Update data/api/client-server/profile.yaml
tcpipuk Jul 31, 2025
3da3b18
Update data/api/client-server/profile.yaml
tcpipuk Jul 31, 2025
0a87d1b
Update data/api/client-server/profile.yaml
tcpipuk Jul 31, 2025
4408198
Update data/api/client-server/profile.yaml
tcpipuk Jul 31, 2025
e78b073
Update data/api/client-server/profile.yaml
tcpipuk Jul 31, 2025
c67980a
Update data/api/client-server/profile.yaml
tcpipuk Jul 31, 2025
7c18c4d
Update data/api/client-server/capabilities.yaml
tcpipuk Jul 31, 2025
0c6132e
Deprecate `m.set_avatar_url` and `m.set_displayname` capabilities
tcpipuk Jul 31, 2025
c197a23
Update changelogs/client_server/newsfragments/2071.feature
tcpipuk Jul 31, 2025
f5b9209
Update data/api/client-server/capabilities.yaml
tcpipuk Jul 31, 2025
df9d3e6
Update data/api/client-server/profile.yaml
tcpipuk Jul 31, 2025
c9057ed
Update data/api/client-server/profile.yaml
tcpipuk Jul 31, 2025
ea02776
Update data/api/client-server/capabilities.yaml
tcpipuk Jul 31, 2025
0051295
Update data/api/client-server/capabilities.yaml
tcpipuk Jul 31, 2025
4293659
Update data/api/client-server/capabilities.yaml
tcpipuk Jul 31, 2025
578e1fb
Update content/client-server-api/modules/guest_access.md
tcpipuk Aug 1, 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
1 change: 1 addition & 0 deletions changelogs/client_server/newsfragments/2071.deprecation
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Deprecate `m.set_avatar_url` and `m.set_displayname` capabilities, as per [MSC4133](https://github.com/matrix-org/matrix-spec-proposals/pull/4133).
1 change: 1 addition & 0 deletions changelogs/client_server/newsfragments/2071.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Update user profile endpoints to handle custom fields, and add a new `m.profile_fields` capability,as per [MSC4133](https://github.com/matrix-org/matrix-spec-proposals/pull/4133).
3 changes: 2 additions & 1 deletion content/client-server-api/modules/guest_access.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ for sending events:
The following API endpoints are allowed to be accessed by guest accounts
for their own account maintenance:

* [PUT /profile/{userId}/displayname](#put_matrixclientv3profileuseriddisplayname)
* [PUT /profile/{userId}/displayname](#put_matrixclientv3profileuseridkeyname) guests users may only modify their displayname in their profile
* [DELETE /profile/{userId}/displayname](#delete_matrixclientv3profileuseridkeyname) guests users may only modify their displayname in their profile
* [GET /devices](#get_matrixclientv3devices)
* [GET /devices/{deviceId}](#get_matrixclientv3devicesdeviceid)
* [PUT /devices/{deviceId}](#put_matrixclientv3devicesdeviceid)
Expand Down
55 changes: 53 additions & 2 deletions data/api/client-server/capabilities.yaml
Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggestion: tcpipuk#2

Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,25 @@ paths:
- default
- available
m.set_displayname:
deprecated: true
$ref: '#/components/schemas/booleanCapability'
description: Capability to indicate if the user can change their display name.
description: |
**Deprecated:** Capability to indicate if the user can change their display name.
Refer to `m.profile_fields` for extended profile management.

For backwards compatibility, servers that directly or indirectly include the
`displayname` profile field in the `m.profile_fields` capability MUST also
set this capability accordingly.
m.set_avatar_url:
deprecated: true
$ref: '#/components/schemas/booleanCapability'
description: Capability to indicate if the user can change their avatar.
description: |
**Deprecated:** Capability to indicate if the user can change their avatar.
Refer to `m.profile_fields` for extended profile management.

For backwards compatibility, servers that directly or indirectly include the
`avatar_url` profile field in the `m.profile_fields` capability MUST also
set this capability accordingly.
m.3pid_changes:
$ref: '#/components/schemas/booleanCapability'
description: Capability to indicate if the user can change 3PID associations
Expand All @@ -86,6 +100,43 @@ paths:
$ref: '#/components/schemas/booleanCapability'
description: Capability to indicate if the user can generate tokens to log further
clients into their account.
m.profile_fields:
x-addedInMatrixVersion: "1.16"
type: object
title: ProfileFieldsCapability
description: Capability to indicate if the user can set or modify extended profile fields via
[`PUT /_matrix/client/v3/profile/{userId}/{keyName}`](/client-server-api/#put_matrixclientv3profileuseridkeyname).
If absent, clients SHOULD assume custom profile fields are supported, provided the
homeserver advertises a specification version that includes `m.profile_fields` in the
[`/versions`](/client-server-api/#get_matrixclientversions) response.
properties:
allowed:
type: array
description: List of allowed additional custom profile field keys. A `*` can be used as a
Copy link
Member

Choose a reason for hiding this comment

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

additional to what?

Copy link
Member

Choose a reason for hiding this comment

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

oh, avatar_url and displayname? We should say that explicitly.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm actually not sure if avatar_url and displayname should really be excluded here. The MSC says m.set_avatar_url and m.set_displayname are not required when m.profile_fields is set.

This capability deprecates the use of m.set_displayname and m.set_avatar_url, which are not required when this capability is present.

That only makes sense if m.profile_fields includes avatar_url and displayname, however.

Copy link
Contributor

@Johennes Johennes Jul 30, 2025

Choose a reason for hiding this comment

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

wildcard to match any sequence of characters. This list takes precedence over the
Comment on lines +115 to +116
Copy link
Member

Choose a reason for hiding this comment

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

A * can be used as a wildcard to match any sequence of characters.

Wait, where did this come from? This wasn't in the MSC, was it? Wildcarding opens up a whole new set of questions that I don't think we want to deal with.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not seeing this in the MSC either. I can imagine this might be useful if home servers want to block- or allow-list a certain namespace within profiles. This feels more like a new feature and less like a clarification that could be tacked onto the MSC post merging though. So it's probably better deferred to a separate proposal.

Copy link
Contributor

@Johennes Johennes Jul 30, 2025

Choose a reason for hiding this comment

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

Copy link
Author

Choose a reason for hiding this comment

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

I know it was discussed in the MSC, but looks like it didn't make it through... there was a lot of back-and-forth on a few features, so I've had to fix a few changes that I forgot weren't still in the MSC when it merged 🥲

disallowed list if both are provided.
Comment on lines +115 to +117
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
description: List of allowed additional custom profile field keys. A `*` can be used as a
wildcard to match any sequence of characters. This list takes precedence over the
disallowed list if both are provided.
description: If `enabled` is `true`, a list of profile fields that clients are allowed to create,
modify or delete. Clients SHOULD assume all fields not in this list to be managed by the
server.
Only one of `allowed` and `disallowed` is permitted at the same time.

The MSC says:

If both allowed and disallowed keys are provided, the disallowed one should be ignored.

However, it's not clear to me why a server would specify both to begin with. I think we can rather say that only one is allowed at a time. I'm mindful that this might be a debatable interpretation of the proposal though.

Choose a reason for hiding this comment

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

This pattern is usually for something like disallowed: my.*, allowed: my.field

Copy link
Contributor

@Johennes Johennes Jul 30, 2025

Choose a reason for hiding this comment

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

Yes, but the MSC says:

If both allowed and disallowed keys are provided, the disallowed one should be ignored.

I'm saying rather than ignore the second list on the client, we could instead prevent the server from setting both at the same time.

Copy link
Contributor

@Johennes Johennes Jul 30, 2025

Choose a reason for hiding this comment

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

(I think your email reply got misrouted)

@JadedBlueEyes says:

From what I understand, it's not the whole list taking precedence (so only one takes effect) but if something is both disallowed (eg by wildcard) and allowed, then it is allowed. Only allowing one would mean that it's not possible to represent some configurations that would be representable otherwise.

Oh! So this is about the same key showing up in allowed and disallowed? I may have totally misinterpreted it then.

Though I guess in this case could we not make this kind of duplication illegal in the spec? The server must simply not include a key in both lists at the same time (wildcards are not currently supported by the MSC).

Choose a reason for hiding this comment

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

Yeah, that probably makes sense to do anyway.

Copy link
Author

Choose a reason for hiding this comment

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

The intention was to have either an "allowlist" model where a server can prescribe specific keys they allow users to set, or a "denylist" model where a server only forbids specific keys to be set.

It seems the MSC doesn't technically allow wildcards, so we wouldn't need both of these to exist, though I'm slightly afraid of forbidding in the spec both keys from existing at the same time just in case the behaviour needs to change in the future to accommodate an extension like wildcards.

The current MSC recommendation is that we simply prefer allowed over disallowed which I think would then make it easier to gracefully absorb extensions in the future without needing to version the endpoint?

items:
type: string
example:
- "m.example_field"
- "org.example.job_title"
disallowed:
type: array
description: If `enabled` is `true`, a list of profile fields that clients are _not_ allowed to
create, modify or delete. Clients SHOULD assume all fields not in this list to be unmanaged
and available for their use.

Only one of `allowed` and `disallowed` is permitted at the same time.
items:
type: string
example:
- "org.example.managed_field"
enabled:
type: boolean
description: "`true` if the user can create, update or delete any profile fields, `false` otherwise."
example: true
required:
- enabled
examples:
response:
value: {
Expand Down
Loading