-
Notifications
You must be signed in to change notification settings - Fork 435
MSC3192: Batch state endpoint #3192
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
Draft
clokep
wants to merge
6
commits into
old_master
Choose a base branch
from
clokep/batch-state
base: old_master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
ed8c7fa
Wrap text.
clokep 42857ee
Updates.
clokep 033695c
Various updates.
clokep 2a7d4ad
Guess MSC number.
clokep 317c95c
Fix typo.
clokep 5addf0b
Rework to be more generic -- handle multiple event types in a single …
clokep File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,176 @@ | ||
| # MSC3192: Batch state endpoint | ||
|
clokep marked this conversation as resolved.
|
||
|
|
||
| It is desired to potentially dump a bunch of state into a room in one go. This | ||
| is useful to: | ||
|
|
||
| * Kick (or ban) many users at once. | ||
| * Invite many users at once. | ||
| * Add many rooms to a [MSC1772](https://github.com/matrix-org/matrix-doc/pull/1772) Space. | ||
| * Bulk-insert [MSC2313](https://github.com/matrix-org/matrix-doc/pull/2313)-style reputation data. | ||
|
clokep marked this conversation as resolved.
|
||
|
|
||
| ## Proposal | ||
|
|
||
| A new endpoint is added to send multiple state events to a room in a single request. | ||
|
|
||
| This endpoint is authenticated and rate-limited. | ||
|
|
||
| `PUT /_matrix/client/r0/rooms/{roomId}/batch_state/{txnId}` | ||
|
|
||
| Example request: | ||
|
|
||
| ```json | ||
| [ | ||
| { | ||
| "event_type": "m.room.membership", | ||
| "state_key": "@alice:example.com", | ||
| "content": { | ||
| "membership": "join", | ||
| "avatar_url": "mxc://localhost/SEsfnsuifSDFSSEF", | ||
| "displayname": "Alice Margatroid" | ||
| } | ||
| } | ||
| ] | ||
| ``` | ||
|
|
||
| Example response: | ||
|
|
||
| ```json | ||
| [ | ||
| "$YUwRidLecu:example.com" | ||
| ] | ||
| ``` | ||
|
|
||
| This API extends the [current ways to push state into a room](https://matrix.org/docs/spec/client_server/latest#sending-events-to-a-room) | ||
| by allowing for multiple events for differing state keys to be created with a single API call. | ||
|
|
||
| Path parameters: | ||
|
|
||
| * `room_id`: **Required.** The room to set the state in | ||
| * `txnId`: **Required.** The transaction ID for this state update. Clients should | ||
| generate an ID unique across requests with the same access token; it will be | ||
| used by the server to ensure idempotency of requests. | ||
|
|
||
| The body of the request should be an ordered array of objects with the following | ||
| keys: | ||
|
|
||
| * `event_type`: **Required.** A string. The type of event to send. | ||
| * `state_key`: A string. The state_key for the state to send. Defaults to the | ||
| empty string. | ||
| * `content`: **Required.** The content object of the event; the fields in this object will vary | ||
| depending on the type of event. See [Room Events](https://matrix.org/docs/spec/client_server/latest#room-events) | ||
| for the `m.` event specification. | ||
|
|
||
| At most 50 events can be included in the request body.<sup id="a1">[1](#f1)</sup> | ||
|
|
||
| The body of the response will contain an array of the created event IDs. If an | ||
| event cannot be created then `null` will be returned in its place. | ||
|
|
||
| Error responses: | ||
|
|
||
| * Status code 400: No events were successfully sent. | ||
| * Status code 403: The sender doesn't have permission to send the event(s) into | ||
| the room. | ||
|
|
||
| This also updates the previous definition to note that | ||
| `PUT /_matrix/client/r0/rooms/{roomId}/state/{eventType}/{stateKey}` should be | ||
| rate-limited. | ||
|
|
||
| ## Potential issues | ||
|
|
||
| Handling a partial batch of state updates could lead to unexpected behavior, but | ||
| should not be worse than the current situation (where each state event must be | ||
| sent individually). | ||
|
|
||
| ## Alternatives | ||
|
|
||
| ### Request body | ||
|
|
||
| A request body consisting of nested objects with event types and state keys as the | ||
| keys pointed to their content was considered, but it seemed not in the style of | ||
| other Matrix APIs. This alternative would look something like: | ||
|
|
||
| ```json | ||
| { | ||
| "m.room.member": { | ||
| "@alice:example.com": { | ||
| "membership": "join", | ||
| "avatar_url": "mxc://localhost/SEsfnsuifSDFSSEF", | ||
| "displayname": "Alice Margatroid" | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ### Atomic requests | ||
|
|
||
| Handling the request atomically and returning an error if any of the state events | ||
| cannot be created for some reason could be nicer. (See [a similar discussion](https://github.com/matrix-org/synapse/issues/7543) | ||
| involving the federation API: `/_matrix/federation/v1/send/{txnId}`.) | ||
|
clokep marked this conversation as resolved.
|
||
|
|
||
| ### Batch inserting state and messages | ||
|
|
||
| The [MSC2716](https://github.com/matrix-org/matrix-doc/pull/2716): Incrementally | ||
| importing history into existing rooms has need to insert both state and messages | ||
| at the same time. This is used to insert messages plus their auth state at the | ||
| same time. | ||
|
|
||
| It is possible this API could be expanded to cover that use-case, but given the | ||
| current specialization needed to handle MSC2716 there does not exist an | ||
| example use-case for handling both state and messages at the same time. | ||
|
|
||
| ## Security considerations | ||
|
|
||
| The main risk of this endpoint is a denial of service attack (against a server | ||
| directly or an amplification attack by using a server to spam over federation). | ||
|
|
||
| An example scenario would be: | ||
|
|
||
| * An unprivileged user creates a public chatroom; has PL 100 | ||
| * Persuades loads of people into it (e.g. via spam or invite-spam, which should | ||
| have other mitigations in place) | ||
| * Starts looping creating `m.space.*` (or any other state) events en bulk | ||
| * Causes loads of PDUs to be pushed over federation, as well as loads of state | ||
| resolution due to the rapidly churning state of the room. | ||
|
|
||
| This is no more amplification than any other federation traffic, but it makes it | ||
| easier for a single unsophisticated user to create a large amount of federation | ||
| traffic, getting their local homeserver into trouble, without them having to run | ||
| a malicious homeserver themselves. | ||
|
|
||
| However, other than consuming resources, there's no particular benefit in doing | ||
| so, and there are other similar attacks (e.g. uploading lots of large files into | ||
| a room and encouraging folks to click on them; or joining many large rooms in | ||
| quick succession). | ||
|
|
||
| Note that, by default, you already have to be a room admin to set arbitrary state | ||
| events in the first place, so the only risk here is of room admins going rogue. | ||
| You could argue this is just one of many ways an admin could go rogue, and would | ||
| need to be dealt with by the server admin on the server where they reside (by | ||
| deactivation or puppetting them to self-demote). | ||
|
|
||
| The benefits of this API outweigh the risks. Server admins can always put some | ||
| monitoring alerts in place to check if they have rogue admins who are | ||
| bulk-spamming rooms with state events - and freeze users who do so. It is also | ||
| recommended to have a low rate-limit on this endpoint. | ||
|
|
||
| There are some measures in the API design which attempt to mitigate some of the | ||
| risk. | ||
|
|
||
| Limiting each call to a single event type and ensuring that each event type / | ||
| state key pair only appears a single time should reduce state resolution churn | ||
| to a degree. | ||
|
|
||
| Limiting the number of state events in a single API call to match what can be | ||
| done by an abusive sever over federation should offer a level of security as | ||
| well. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is probably worth adding that servers should consider rate-limiting at a per-event level rather than treating this endpoint as a single "unit" of rate-limiting consumption. |
||
|
|
||
| ## Unstable prefix | ||
|
|
||
| During development of this feature it will be available at an unstable endpoint: | ||
|
|
||
| `/_matrix/client/unstable/org.matrix.mscxxxx/rooms/{roomId}/batch_state/{txnId}` | ||
|
|
||
| ## Footnotes | ||
|
|
||
| <a id="f1"/>[1]: This matches the [maximum of 50 PDUs](https://matrix.org/docs/spec/server_server/latest#put-matrix-federation-v1-send-txnid) | ||
| that can be in a federation transaction. [↩](#a1) | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.