Merge branch 'main' into refresh_token_spec

pull/1056/head
Hubert Chathi 2 years ago
commit 84747f90e8

@ -0,0 +1 @@
Add timestamp massaging as per [MSC3316](https://github.com/matrix-org/matrix-spec-proposals/pull/3316).

@ -1 +1 @@
Adjust the OpenAPI specification so that the type `Flow information` is explicitly defined when the CS spec is rendered.
Adjust the OpenAPI specification so that the type `Flow information` is explicitly defined when the client-server API is rendered.

@ -0,0 +1 @@
Fix various typos throughout the specification.

@ -0,0 +1 @@
Fix various typos throughout the specification.

@ -0,0 +1 @@
Fix various typos throughout the specification.

@ -0,0 +1 @@
Clarify that state keys starting with `@` are in fact reserved. Regressed from [#3658](https://github.com/matrix-org/matrix-spec-proposals/pull/3658).

@ -1 +1 @@
Fix broken syntax in Server Access Control Lists definition.
Fix various typos throughout the specification.

@ -1,2 +1 @@
Improve readability of definitions in the state resolution v2 algorithm.
Improve readability and understanding of the state resolution algorithms.

@ -0,0 +1 @@
Improve readability and understanding of the state resolution algorithms.

@ -0,0 +1 @@
Improve readability and understanding of the state resolution algorithms.

@ -0,0 +1 @@
Improve readability of the authorization rules.

@ -0,0 +1 @@
For room versions 8, 9, and 10: clarify which homeserver is required to sign the join event.

@ -1 +1 @@
Fix join membership auth rules when `join_rule` is `knock`.
For room versions 7, 8, 9, and 10: fix join membership authorization rules when `join_rule` is `knock`.

@ -1 +1 @@
Update the default room version to 9.
Update the default room version to 9 as per [MSC3589](https://github.com/matrix-org/matrix-spec-proposals/pull/3589).

@ -1 +1 @@
Fix origin server name in S2S Request Authentication example.
Clarify the format for the Authorization header.

@ -0,0 +1 @@
Clarify what a "valid event" means when performing checks on a received PDU.

@ -0,0 +1 @@
Clarify that `valid_until_ts` is in milliseconds, like other timestamps used in Matrix.

@ -0,0 +1 @@
Clarify the format for the Authorization header.

@ -0,0 +1 @@
Add a `destination` property to the Authorization header, as per [MSC3383](https://github.com/matrix-org/matrix-spec-proposals/pull/3383).

@ -0,0 +1 @@
Clarify that checks on PDUs should refer to the state *before* an event.

@ -1 +1 @@
Remove `origin` field from PDUs which exists on many but not all PDUs in practice and doesn't serve an actual purpose.
Remove largely unused `origin` field from PDUs.

@ -300,13 +300,38 @@ An example request would be:
#### Timestamp massaging
Previous drafts of the Application Service API permitted application
services to alter the timestamp of their sent events by providing a `ts`
query parameter when sending an event. This API has been excluded from
the first release due to design concerns, however some servers may still
support the feature. Please visit [issue
\#1585](https://github.com/matrix-org/matrix-doc/issues/1585) for more
information.
{{% added-in v="1.3" %}}
Application services can alter the timestamp associated with an event, allowing
the application service to better represent the "real" time an event was sent
at. While this doesn't affect the server-side ordering of the event, it can allow
an application service to better represent when an event would have been sent/received
at, such as in the case of bridges where the remote network might have a slight
delay and the application service wishes to bridge the proper time onto the message.
When authenticating requests as an application service, the caller can append a `ts`
query string argument to change the `origin_server_ts` of the resulting event. Attempting
to set the timestamp to anything other than what is accepted by `origin_server_ts` should
be rejected by the server as a bad request.
When not present, the server's behaviour is unchanged: the local system time of the server
will be used to provide a timestamp, representing "now".
The `ts` query string argument is only valid on the following endpoints:
* [`PUT /rooms/{roomId}/send/{eventType}/{txnId}`](/client-server-api/#put_matrixclientv3roomsroomidsendeventtypetxnid)
* [`PUT /rooms/{roomId}/state/{eventType}/{stateKey}`](/client-server-api/#put_matrixclientv3roomsroomidstateeventtypestatekey)
Other endpoints, such as `/kick`, do not support `ts`: instead, callers can use the
`PUT /state` endpoint to mimic the behaviour of the other APIs.
{{% boxes/warning %}}
Changing the time of an event does not change the server-side (DAG) ordering for the
event. The event will still be appended at the tip of the DAG as though the timestamp
was set to "now". Future MSCs, like [MSC2716](https://github.com/matrix-org/matrix-spec-proposals/pull/2716),
are expected to provide functionality which can allow DAG order manipulation (for history
imports and similar behaviour).
{{% /boxes/warning %}}
#### Server admin style permissions

@ -1107,8 +1107,8 @@ as follows:
}
```
As with [token-based]() interactive login, the `token` must encode the
user ID. In the case that the token is not valid, the homeserver must
The `token` must encode the user ID, since there is no other identifying
data in the request. In the case that the token is not valid, the homeserver must
respond with `403 Forbidden` and an error code of `M_FORBIDDEN`.
If the homeserver advertises `m.login.sso` as a viable flow, and the

@ -4,11 +4,11 @@ toc_hide: true
The types of state events that affect authorization are:
- `m.room.create`
- `m.room.member`
- `m.room.join_rules`
- `m.room.power_levels`
- `m.room.third_party_invite`
- [`m.room.create`](/client-server-api#mroomcreate)
- [`m.room.member`](/client-server-api#mroommember)
- [`m.room.join_rules`](/client-server-api#mroom)
- [`m.room.power_levels`](/client-server-api#mroompower_levels)
- [`m.room.third_party_invite`](/client-server-api#mroomthird_party_invite)
{{% boxes/note %}}
Power levels are inferred from defaults when not explicitly supplied.

@ -2,20 +2,19 @@
toc_hide: true
---
The room state *S*(*E*) after an event *E* is defined in terms of the
room state *S*(*E*) before *E*, and depends on whether *E* is a state
The room state *S(E)* after an event *E* is defined in terms of the
room state *S(E)* before *E*, and depends on whether *E* is a state
event or a message event:
- If *E* is a message event, then *S*(*E*)=*S*(*E*).
- If *E* is a state event, then *S*(*E*) is *S*(*E*), except that its
entry corresponding to *E*'s `event_type` and `state_key` is
replaced by *E*'s `event_id`.
- If *E* is a message event, then *S(E)*=*S(E)*.
- If *E* is a state event, then *S(E)* is *S(E)*, except that its
entry corresponding to the `event_type` and `state_key` of *E* is
replaced by the `event_id` of *E*.
The room state *S*(*E*) before *E* is the *resolution* of the set of
states {*S*(*E*<sub>1</sub>),*S*(*E*<sub>2</sub>), …} consisting of
the states after each of *E*'s `prev_event`s
{*E*<sub>1</sub>,*E*<sub>2</sub>, …}, where the resolution of a set of
states is given in the algorithm below.
The room state *S(E)* before *E* is the *resolution* of the set of
states {*S(E*<sub>1</sub>*)*,*S(E*<sub>2</sub>*)*, …}
after the `prev_event`s {*E*<sub>1</sub>,*E*<sub>2</sub>, …} of *E*.
The resolution of a set of states is given in the algorithm below.
#### Definitions
@ -31,11 +30,22 @@ the `membership` is `leave` or `ban` and the `sender` does not match the
might remove someone's ability to do something in the room.
**Unconflicted state map and conflicted state set.**
The *unconflicted state map* is the state where the value of each key
exists and is the same in each state *S*<sub>*i*</sub>. The *conflicted
state set* is the set of all other state events. Note that the
unconflicted state map only has one event per `(event_type, state_key)`,
whereas the conflicted state set may have multiple events.
The keys of the state maps *S<sub>i</sub>* are 2-tuples of strings of the form
*K* = `(event_type, state_key)`. The values *V* are state events.
The key-value pairs (*K*, *V*) across all state maps *S<sub>i</sub>* can be
divided into two collections.
If a given key *K* is present in every *S<sub>i</sub>* with the same value *V*
in each state map, then the pair (*K*, *V*) belongs to the *unconflicted state map*.
Otherwise (*K*, *V*) belongs to the *conflicted state set*.
Note that the unconflicted state map only has one event for each key *K*,
whereas the conflicted state set may associate multiple events to the same key.
**Auth chain.**
The *auth chain* of an event *E* is the set containing all of *E*'s auth events,
all of *their* auth events, and so on recursively, stretching back to the
start of the room. Put differently, these are the events reachable by walking
the graph induced by an event's `auth_events` links.
**Auth difference.**
The *auth difference* is calculated by first calculating the full auth
@ -112,9 +122,9 @@ the auth event is not rejected.
The *resolution* of a set of states is obtained as follows:
1. Take all *power events* and any events in their auth chains,
recursively, that appear in the *full conflicted set* and order them
by the *reverse topological power ordering*.
1. Select all *power events* that appear in the *full conflicted set*. Compute
the union of their auth chains, including the power events themselves.
Sort the union using the *reverse topological power ordering*.
2. Apply the *iterative auth checks algorithm*, starting from the
*unconflicted state map*, to the list of events from the previous
step to get a partially resolved state.

@ -11,11 +11,11 @@ however.
The types of state events that affect authorization are:
- `m.room.create`
- `m.room.member`
- `m.room.join_rules`
- `m.room.power_levels`
- `m.room.third_party_invite`
- [`m.room.create`](/client-server-api#mroomcreate)
- [`m.room.member`](/client-server-api#mroommember)
- [`m.room.join_rules`](/client-server-api#mroom)
- [`m.room.power_levels`](/client-server-api#mroompower_levels)
- [`m.room.third_party_invite`](/client-server-api#mroomthird_party_invite)
{{% boxes/note %}}
Power levels are inferred from defaults when not explicitly supplied.

@ -12,11 +12,11 @@ of receipt, they are authorized at a later stage: see the
The types of state events that affect authorization are:
- `m.room.create`
- `m.room.member`
- `m.room.join_rules`
- `m.room.power_levels`
- `m.room.third_party_invite`
- [`m.room.create`](/client-server-api#mroomcreate)
- [`m.room.member`](/client-server-api#mroommember)
- [`m.room.join_rules`](/client-server-api#mroom)
- [`m.room.power_levels`](/client-server-api#mroompower_levels)
- [`m.room.third_party_invite`](/client-server-api#mroomthird_party_invite)
{{% boxes/note %}}
Power levels are inferred from defaults when not explicitly supplied.
@ -46,7 +46,7 @@ The rules are as follows:
1. If no `state_key` key or `membership` key in `content`, reject.
2. If `content` has a `join_authorised_via_users_server`
key:
1. If the event is not validly signed by the user ID denoted
1. If the event is not validly signed by the homeserver of the user ID denoted
by the key, reject.
3. If `membership` is `join`:
1. If the only previous event is an `m.room.create` and the

@ -66,18 +66,18 @@ This is fixed in the state resolution algorithm introduced in room
version 2.
{{% /boxes/warning %}}
The room state *S*(*E*) after an event *E* is defined in terms of the
The room state *S*(*E*) after an event *E* is defined in terms of the
room state *S*(*E*) before *E*, and depends on whether *E* is a state
event or a message event:
- If *E* is a message event, then *S*(*E*)=*S*(*E*).
- If *E* is a state event, then *S*(*E*) is *S*(*E*), except that its
entry corresponding to *E*'s `event_type` and `state_key` is
replaced by *E*'s `event_id`.
- If *E* is a message event, then *S(E)*=*S(E)*.
- If *E* is a state event, then *S(E)* is *S(E)*, except that its
entry corresponding to the `event_type` and `state_key` of *E* is
replaced by the `event_id` of *E*.
The room state *S*(*E*) before *E* is the *resolution* of the set of
states {*S*(*E*),*S*(*E*″), …} consisting of the states after each
of *E*'s `prev_event`s {*E*,*E*″, …}.
The room state *S(E)* before *E* is the *resolution* of the set of
states {*S(E)*,*S(E″)*, …} after the `prev_events` {*E*,*E″*, …}.
of *E*.
The *resolution* of a set of states is defined as follows. The resolved
state is built up in a number of passes; here we use *R* to refer to the

@ -59,11 +59,11 @@ Events must be signed by the server denoted by the `sender` key.
The types of state events that affect authorization are:
- `m.room.create`
- `m.room.member`
- `m.room.join_rules`
- `m.room.power_levels`
- `m.room.third_party_invite`
- [`m.room.create`](/client-server-api#mroomcreate)
- [`m.room.member`](/client-server-api#mroommember)
- [`m.room.join_rules`](/client-server-api#mroom)
- [`m.room.power_levels`](/client-server-api#mroompower_levels)
- [`m.room.third_party_invite`](/client-server-api#mroomthird_party_invite)
{{% boxes/note %}}
Power levels are inferred from defaults when not explicitly supplied.

@ -45,11 +45,11 @@ of receipt, they are authorized at a later stage: see the
The types of state events that affect authorization are:
- `m.room.create`
- `m.room.member`
- `m.room.join_rules`
- `m.room.power_levels`
- `m.room.third_party_invite`
- [`m.room.create`](/client-server-api#mroomcreate)
- [`m.room.member`](/client-server-api#mroommember)
- [`m.room.join_rules`](/client-server-api#mroom)
- [`m.room.power_levels`](/client-server-api#mroompower_levels)
- [`m.room.third_party_invite`](/client-server-api#mroomthird_party_invite)
{{% boxes/note %}}
Power levels are inferred from defaults when not explicitly supplied.

@ -255,7 +255,7 @@ condition applies throughout the request signing process.
Step 2 add Authorization header:
GET /target HTTP/1.1
Authorization: X-Matrix origin=origin.hs.example.com,key="ed25519:key1",sig="ABCDEF..."
Authorization: X-Matrix origin="origin.hs.example.com",destination="destination.hs.example.com",key="ed25519:key1",sig="ABCDEF..."
Content-Type: application/json
<JSON-encoded request body>
@ -283,14 +283,52 @@ def authorization_headers(origin_name, origin_signing_key,
for key, sig in signed_json["signatures"][origin_name].items():
authorization_headers.append(bytes(
"X-Matrix origin=%s,key=\"%s\",sig=\"%s\"" % (
origin_name, key, sig,
"X-Matrix origin=\"%s\",destination=\"%s\",key=\"%s\",sig=\"%s\"" % (
origin_name, destination_name, key, sig,
)
))
return ("Authorization", authorization_headers)
return ("Authorization", authorization_headers[0])
```
The format of the Authorization header is given in
[RFC 7235](https://datatracker.ietf.org/doc/html/rfc7235#section-2.1). In
summary, the header begins with authorization scheme `X-Matrix`, followed by
one or more spaces, followed by a comma-separated list of parameters written as
name=value pairs. The names are case insensitive and order does not matter. The
values must be enclosed in quotes if they contain characters that are not
allowed in `token`s, as defined in
[RFC 7230](https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.6); if a
value is a valid `token`, it may or may not be enclosed in quotes. Quoted
values may include backslash-escaped characters. When parsing the header, the
recipient must unescape the characters. That is, a backslash-character pair is
replaced by the character that follows the backslash.
For compatibility with older servers, the sender should
- only include one space after `X-Matrix`,
- only use lower-case names, and
- avoid using backslashes in parameter values.
For compatibility with older servers, the recipient should allow colons to be
included in values without requiring the value to be enclosed in quotes.
The authorization parameters to include are:
- `origin`: the server name of the sending server. This is the same as the
`origin` field from JSON described in step 1.
- `destination`: {{< added-in v="1.3" >}} the server name of the receiving
sender. This is the same as the `destination` field from the JSON described
in step 1. For compatibility with older servers, recipients should accept
requests without this parameter, but MUST always send it. If this property
is included, but the value does not match the receiving server's name, the
receiving server must deny the request with an HTTP status code 401
Unauthorized.
- `key`: the ID, including the algorithm name, of the sending server's key used
to sign the request.
- `signature`: the signature of the JSON as calculated in step 1.
Unknown parameters are ignored.
### Response Authentication
Responses are authenticated by the TLS server certificate. A homeserver
@ -356,13 +394,15 @@ specification](/rooms).
Whenever a server receives an event from a remote server, the receiving
server must ensure that the event:
1. Is a valid event, otherwise it is dropped.
1. Is a valid event, otherwise it is dropped. For an event to be valid, it
must contain a `room_id`, and it must comply with the event format of
that [room version](/rooms).
2. Passes signature checks, otherwise it is dropped.
3. Passes hash checks, otherwise it is redacted before being processed
further.
4. Passes authorization rules based on the event's auth events,
otherwise it is rejected.
5. Passes authorization rules based on the state at the event,
5. Passes authorization rules based on the state before the event,
otherwise it is rejected.
6. Passes authorization rules based on the current state of the room,
otherwise it is "soft failed".

@ -38,6 +38,10 @@ properties:
Present if, and only if, this event is a *state* event. The key making
this piece of state unique in the room. Note that it is often an empty
string.
State keys starting with an `@` are reserved for referencing user IDs, such
as room members. With the exception of a few events, state events set with a
given user's ID as the state key MUST only be set by that user.
type: string
example: '@user:example.org'
sender:

@ -114,7 +114,7 @@ paths:
Some example error codes include:
* `M_INVALID_PARAMETER`: One or more aliases within the `m.room.canonical_alias`
* `M_INVALID_PARAM`: One or more aliases within the `m.room.canonical_alias`
event have invalid syntax.
* `M_BAD_ALIAS`: One or more aliases within the `m.room.canonical_alias` event

@ -88,9 +88,10 @@ properties:
type: integer
format: int64
description: |-
POSIX timestamp when the list of valid keys should be refreshed. This field MUST
be ignored in room versions 1, 2, 3, and 4. Keys used beyond this timestamp MUST
be considered invalid, depending on the [room version specification](/rooms).
POSIX timestamp in milliseconds when the list of valid keys should be refreshed.
This field MUST be ignored in room versions 1, 2, 3, and 4. Keys used beyond this
timestamp MUST be considered invalid, depending on the
[room version specification](/rooms).
Servers MUST use the lesser of this field and 7 days into the future when
determining if a key is valid. This is to avoid a situation where an attacker

@ -4,7 +4,6 @@
"content": {
"version" : 0,
"call_id": "12345",
"lifetime": 60000,
"answer": {
"type" : "answer",
"sdp" : "v=0\r\no=- 6584580628695956864 2 IN IP4 127.0.0.1[...]"

@ -2,7 +2,7 @@
{{ $this := .Params.this }}
{{ if $this }}
<span>**[New in this version]**</span>
<span><strong>[New in this version]</strong></span>
{{ else }}
<span>**[Added in `v{{ $ver }}`]**</span>
{{ end }} {{/* Do not leave an empty line at the end of this file otherwise the inline behaviour breaks. */}}
<span><strong>[Added in <code>v{{ $ver }}</code>]</strong></span>
{{ end }} {{/* Do not leave an empty line at the end of this file otherwise the inline behaviour breaks. */}}

@ -2,7 +2,7 @@
{{ $this := .Params.this }}
{{ if $this }}
<span>**[Changed in this version]**</span>
<span><strong>[Changed in this version]</strong></span>
{{ else }}
<span>**[Changed in `v{{ $ver }}`]**</span>
{{ end }} {{/* Do not leave an empty line at the end of this file otherwise the inline behaviour breaks. */}}
<span><strong>[Changed in <code>v{{ $ver }}</code>]</strong></span>
{{ end }} {{/* Do not leave an empty line at the end of this file otherwise the inline behaviour breaks. */}}

Loading…
Cancel
Save