Skip to content
Open
Changes from all commits
Commits
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
147 changes: 147 additions & 0 deletions proposals/4337-as-profile-suppliments.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
# MSC4337: Appservice API to supplement user profiles
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Implementations:

  • Synapse (partial, no unstable prefixes)
  • [Bot-SDK][] TBD
  • [Implemenation)[] TBD


User profiles in Matrix are currently largely stored on the homeserver statically. Clients can
update the static information as often as they like, but it's expected that the homeserver
maintains a copy in it's datastore. This means that having dynamic profile values that may change
depending on a user's status (e.g. "In a meeting") or profiles that may change depending on the
requester are hard to achieve.

This proposal extends the appservice API to offer a new route to supplement a user's profile with
additional fields, or to replace existing ones.

## Proposal

A new route is introduced on the Application Service API:

`GET /_matrix/app/v1/profile/{userId}/{key}`

This API is authenticated as with the rest of the application service APIs, and takes two additional
*optional* query parameters:

- `origin_server` The server name of the server requesting the profile, *if* the profile is requested
over federation. Otherwise, omit.
- `from_user_id` The user MxID of the user requesting the profile, *if* the requesting user is known.
Otherwise, omit.
Comment on lines +21 to +24
Copy link
Member

Choose a reason for hiding this comment

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

What error is used if both are provided? Is it valid to provide neither?


The path parameters match the C-S API `/profile` GET parameters, where `userId` is the user profile to be
fetched and `key` is an optional field on the profile. If the `key` is omitted, the full profile should be returned.

The response to the API should be an object representing the profile. Homeservers should call this API
whenever a user's profile is requested by a client or a federated service, and the appservice should return
a profile object. If a `key` is specified then an object should be returned only containing the value for `key`.

### Examples

`GET /_matrix/app/v1/profile/@alice:example.org` would return

```json
{
"displayName": "Alice S.",
"org.example.holiday": true
}
```

and

`GET /_matrix/app/v1/profile/@alice:example.org/org.example.holiday` would return

```json
{
"org.example.holiday": true
}
```

### Merging behaviour

The homeserver should *always* request the profile from the application service even if the `key` is already
present in the user's stored profile. For instance, given a profile of:
Comment on lines +56 to +57
Copy link
Member

Choose a reason for hiding this comment

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

Always sounds strong, it is only when an AS has some control over a user ID.


```json
{
"displayName": "Bob",
"avatar_url": "mxc://foo/bar"
}
```

and an appservice response of:

```json
{
"displayName": "Alice S.",
"org.example.holiday": true
}
```

then the resulting profile for the user will be:

```json
{
"avatar_url": "mxc://foo/bar",
"displayName": "Alice S.",
"org.example.holiday": true
}
```

### Error codes

Application services may respond with a `404` `M_NOT_FOUND` if they do not provide any information
for the given `userId`. They may also choose to do this if they do not want to divulge information
about a given user to another user or service.
Comment on lines +87 to +89
Copy link
Member

Choose a reason for hiding this comment

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

How does this affect merging behavior?



### Caching

Homeservers should not cache responses to this endpoint as the values may change dynamically.

TODO: Should we introduce a ETag-like system here so homeservers can cache?

### Application service selection

Any homeserver with a matching `namespaces.users` field for the requested `userId` should be used
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
Any homeserver with a matching `namespaces.users` field for the requested `userId` should be used
Any application service with a matching `namespaces.users` field for the requested `userId` should be used

Maybe? I'm not sure what this sentence is saying.

when querying the profile. The resulting profile should be merged together. The order of application services
here is **NOT** stable, and so if multiple application services set the same field on the same user
then there is potential for instability. Server admins should take care not to register multiple application
Comment on lines +101 to +103
Copy link
Member

Choose a reason for hiding this comment

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

Is this already an issue today with overlapping ASes for other features, or new to this feature?

services with overlapping namespaces, if they may both alter the profile.

Implementations MAY choose to specify a guaranteed ordering for application service queries but this is out
of scope for the spec.

The registration file **MUST** contain `supports_profile_lookup: true` to be considered for profile queries
to reduce the number of requests made to appservices not supporting this feature.

## Potential issues

### Performance

This can place additional delay on the profile endpoint, as now an additional HTTP hit will need to be made. A sensible
maximum response time should probably be specified to reduce the risk of a profile endpoint timing out. Additionally,
the timeout should not prevent a client from reading the resulting profile, without the missing application service response.

### Instability

As per the previous section, application service querying is not inheriently stable across homeserver implementations
so overlaps in profiles may lead to unpredictable results.

## Alternatives

Application services already can modify profiles, albeit with no controls over who can view them and with the added
cost of these profiles being stored in the homeserver. There is also no way to update on-demand to reduce the amount
of changes needed to be made to the homeservers stores.

## Security considerations

The most obvious security risk is that this MSC opens up the ability to do authed profile requests and alter the response
depending on the requester. The application service and the homeserver must ensure not to cache these responses globally,
and be careful when validating the requester.

TODO: There must be more things that can go wrong here.

## Unstable prefix

While this MSC is not considered stable:
- the endpoint will be `/_matrix/app/uk.half-shot.msc4337/profile/@alice:example.org`
- the registration file flag will be `msc4337_supports_profile_lookup`

## Dependencies

None.