-
Notifications
You must be signed in to change notification settings - Fork 375
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
Document the event auth rules #1027
Changes from 2 commits
47e2ddc
d6118c7
c11aa35
47005d5
561f116
6d038e1
2d89f1b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
.. Copyright 2016 OpenMarket Ltd | ||
.. Copyright 2017 New Vector Ltd | ||
.. | ||
.. Licensed under the Apache License, Version 2.0 (the "License"); | ||
.. you may not use this file except in compliance with the License. | ||
|
@@ -442,24 +443,155 @@ keys exist to support this: | |
``state_key`` String Combined with the ``pdu_type`` this | ||
identifies the which part of the room | ||
state is updated | ||
``required_power_level`` Integer The required power level needed to | ||
replace this update. | ||
``prev_state_id`` String The PDU id of the update this replaces. | ||
``prev_state_origin`` String The homeserver of the update this | ||
replaces. | ||
``user_id`` String The user updating the state. | ||
======================== ============ ========================================= | ||
|
||
.. code:: json | ||
Authorization of PDUs | ||
~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
{..., | ||
"is_state":true, | ||
"state_key":TODO-doc | ||
"required_power_level":TODO-doc | ||
"prev_state_id":TODO-doc | ||
"prev_state_origin":TODO-doc | ||
} | ||
Whenever a server receives an event from a remote server, the receiving server | ||
must check that the event is allowed by the authorization rules. These rules | ||
depend on the state of the room at that event. | ||
|
||
Definitions | ||
+++++++++++ | ||
|
||
Required Power Level | ||
A given event type has an associated *required power level*. This is given by | ||
the current ``m.room.power_levels`` event. The event type is either listed | ||
explicitly in the ``events`` section or given by either ``state_default`` or | ||
``events_default`` depending on if the event is a state event or not. | ||
|
||
Rules | ||
+++++ | ||
|
||
The rules governing whether an event is authorized depend solely on the | ||
state of the room at the point in the room graph at which the new event is to | ||
be inserted. The types of state events that affect authorization are: | ||
|
||
- ``m.room.create`` | ||
- ``m.room.member`` | ||
- ``m.room.join_rules`` | ||
- ``m.room.power_levels`` | ||
|
||
Servers should not create new events that reference unauthorized events. | ||
However, any event that does reference an unauthorized event is not itself | ||
automatically considered unauthorized. | ||
|
||
Unauthorized events that appear in the event graph do *not* have any effect on | ||
the state of the room. | ||
|
||
.. Note:: This is in contrast to redacted events which can still affect the | ||
state of the room. For example, a redacted ``join`` event will still | ||
result in the user being considered joined. | ||
|
||
1. If type is ``m.room.create``, allow if and only if has depth 0 and it has no | ||
previous events - *i.e.* it is the first event in the room. | ||
|
||
#. If type is ``m.room.member``: | ||
|
||
a. If ``membership`` is ``join``: | ||
|
||
i. If the previous event in the room graph is an ``m.room.create``, the | ||
depth is 1 and the ``state_key`` is the creator, allow. | ||
|
||
#. If the ``state_key`` does not match ``sender`` key, reject. | ||
|
||
#. If the state event being replaced has ``membership`` set to ``join``, | ||
allow. | ||
|
||
#. If the ``join_rule`` is: | ||
|
||
- ``public``: allow. | ||
|
||
- absent, or ``invite``: allow if and only if the state event being replaced has | ||
``membership`` set to ``join``. | ||
|
||
#. Otherwise, reject | ||
|
||
#. If ``membership`` is ``invite``: | ||
|
||
i. If the ``sender``'s current membership state is not ``joined``, reject. | ||
|
||
#. If the state event being replaced has ``membership`` set to ``join`` | ||
or ``ban``, reject. | ||
|
||
#. If ``sender``'s power level is greater than or equal to the ``invite`` | ||
level given in the current ``m.room.power_levels`` state (defaults to | ||
50), and the ``state_key``'s power level is less than or equal to the | ||
``sender``'s power level, then allow. | ||
|
||
#. Otherwise, reject. | ||
|
||
#. If ``membership`` is ``leave``: | ||
|
||
i. If ``sender`` matches ``state_key``, allow. | ||
|
||
#. If the ``sender``'s current membership state is not ``joined``, reject. | ||
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. There's a clause that allows an admin "unbanning" someone if they were banned an the admin has a power level above the "ban_level" 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. thanks, fixed in 47005d5. My understanding of the code is that you can unban someone even if you have PL < ban, provided you have PL >= kick, and the target's PL is <= yours. Seems a bit odd but if it's true we might as well spec it. Can you double-check me? 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. https://github.com/matrix-org/synapse/blob/master/synapse/event_auth.py#L320 seems to suggest you need a PL >= ban to unban? 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. Right, apparently I misread the code. Let me try again. It looks like you have to have PL >= ban and PL >= kick and PL >= the target to unban someone, otherwise you'll get caught at https://github.com/matrix-org/synapse/blob/master/synapse/event_auth.py#L327. Right? 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. Yup, looks like it. 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. Right, one more go in 6d038e1. PTAL? |
||
|
||
#. If ``sender``'s power level is greater than or equal to the ``kick`` level | ||
given in the current ``m.room.power_levels`` state (defaults to 50), | ||
and the ``state_key``'s power level is less than or equal to the | ||
``sender``'s power level, then allow. | ||
|
||
#. Otherwise, reject. | ||
|
||
#. If ``membership`` is ``ban``: | ||
|
||
i. If the ``sender``'s current membership state is not ``joined``, reject. | ||
|
||
#. If ``sender``'s power level is greater than or equal to the ``ban`` level | ||
given in the current ``m.room.power_levels`` state (defaults to 50), | ||
and the ``state_key``'s power level is less than or equal to the | ||
``sender``'s power level, then allow. | ||
|
||
#. Otherwise, reject. | ||
|
||
#. Otherwise, the membership is unknown. Reject. | ||
|
||
#. If the ``sender``'s current membership state is not ``joined``, reject. | ||
|
||
#. If the event type's *required power level* is greater than the ``sender``'s power | ||
level, reject. | ||
|
||
#. If type is ``m.room.power_levels``: | ||
|
||
a. For each of the keys ``users_default``, ``events_default``, | ||
``state_default``, ``ban``, ``redact``, ``kick``, ``invite``, as well as | ||
each entry being changed under the ``events`` or ``users`` keys: | ||
|
||
i. If the current value is higher than the ``sender``'s current power level, | ||
reject. | ||
|
||
#. If the new value is higher than the ``sender``'s current power level, | ||
reject. | ||
|
||
#. For each entry being changed under the ``users`` key, other than the | ||
``sender``'s own entry: | ||
|
||
i. If the current value is equal to the ``sender``'s current power level, | ||
reject. | ||
|
||
#. Otherwise, allow. | ||
|
||
#. If type is ``m.room.redact``: | ||
|
||
#. If ``sender``'s power level is greater than or equal to the ``redact`` level | ||
given in the current ``m.room.power_levels`` state (defaults to 50), allow. | ||
|
||
#. If the ``sender`` of the event being redacted is the same as the | ||
``sender`` of the ``m.room.redact``, allow. | ||
|
||
#. Otherwise, reject. | ||
|
||
#. Otherwise, allow. | ||
|
||
.. TODO-spec | ||
|
||
I think there is some magic about 3pid invites too. | ||
|
||
EDUs | ||
---- | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's an assertion for that room_id domain matches sender domain
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah. I think there's a whole class of checks like this and the signatures which I want to keep separately from the auth rules, because they don't really play a part in state resolution. The line's a bit fuzzy, but I want to punt this one and the signatures to a separate section and a separate PR.