Merge e15517ee53 into e9f0f31d27
commit
165fc2cf94
@ -0,0 +1,204 @@
|
|||||||
|
# MSC4104: Auth Lock: Soft-failure-be-gone!
|
||||||
|
|
||||||
|
This proposal aims to make soft failure redundant, by introducing
|
||||||
|
`m.auth_lock` as a mechanism to stop authorising events that are
|
||||||
|
crafted to reference previous state. All without disrupting the
|
||||||
|
history of the room for new users.
|
||||||
|
|
||||||
|
This MSC introduces a new authorization event, the `m.auth_lock` event.
|
||||||
|
When a server issues an authorization event that supersedes an existing
|
||||||
|
event, for example by banning a user, the admin can choose to
|
||||||
|
canonicalise their version of the room history by issuing an auth-lock.
|
||||||
|
This can be thought of as a thread lock from forum software applied
|
||||||
|
to a specific portion of the DAG. The auth-lock event not only
|
||||||
|
specifies the authorization event to lock, but all forward
|
||||||
|
extremities that reference the locked authorization event. Thus
|
||||||
|
canonicalising the history of that part of the DAG.
|
||||||
|
|
||||||
|
Any further events that reference an authorization event that has been
|
||||||
|
*locked* will then be rejected outright during authorization.
|
||||||
|
|
||||||
|
## Proposal
|
||||||
|
|
||||||
|
### The auth lock event `m.auth_lock`
|
||||||
|
|
||||||
|
The `m.auth_lock` event can be issued in scenarios where room admins
|
||||||
|
or their tooling detect or anticipate events referring to previous
|
||||||
|
authorization events. This should only be done eagerly when there
|
||||||
|
is reasonable risk. For example, it would be inappropriate to
|
||||||
|
issue an `m.auth_lock` event after banning a spammer that
|
||||||
|
resided on `matrix.org` as it is unlikely for matrix.org
|
||||||
|
to attempt to maliciously reference old authorization events.
|
||||||
|
By delaying the application of `m.auth_lock`, room administrators
|
||||||
|
reduce the risk of divergence. This is something that currently
|
||||||
|
occurs frequently with [soft failure](https://github.com/element-hq/synapse/issues/9329).
|
||||||
|
|
||||||
|
#### Properties
|
||||||
|
- `content`:
|
||||||
|
+ `locked_event_id`: The event_id of the authorization event to lock.
|
||||||
|
This is protected from redaction.
|
||||||
|
+ `extremities`: A list of extremities that should be shared to other
|
||||||
|
servers representing the canonicalised version of the room history.
|
||||||
|
This is protected from redaction.
|
||||||
|
|
||||||
|
- `state_key`: A sha256 of the `locked_event_id` concatenated with the
|
||||||
|
mxid of the event sender. We do this so that different room admins
|
||||||
|
can optionally specify their own versions of the `extremities`
|
||||||
|
that will combine to form a complete set to be considered during
|
||||||
|
authorization. This also keeps `extremities` conflict free.
|
||||||
|
|
||||||
|
### Changes to auth_rules
|
||||||
|
|
||||||
|
#### Issuing `m.auth_lock`
|
||||||
|
|
||||||
|
If type is `m.auth_lock`:
|
||||||
|
1. if `state_key` does not match a sha256 of `locked_event_id` and
|
||||||
|
`sender`, reject.
|
||||||
|
|
||||||
|
#### Authorizing other events
|
||||||
|
|
||||||
|
Considering the event's `auth_events`:
|
||||||
|
1. For each `auth_event` all `m.auth_lock` events with a
|
||||||
|
`locked_event_id` matching the `event_id` of the `auth_event`
|
||||||
|
are found from the room's current state.
|
||||||
|
From each `m.auth_lock` event relevant to one `auth_event`, the
|
||||||
|
`extremities` fields are combined to form a set of all `extremities`
|
||||||
|
relevant to the `auth_event`.
|
||||||
|
If the considered auth_event's `event_id` matches any
|
||||||
|
`m.auth_lock`'s `locked_event_id` field AND the `event_id` of the
|
||||||
|
event being authorized is absent from both the `extremities` set
|
||||||
|
AND the `event_id` of any connected event referenced via each
|
||||||
|
extremity's `prev_events`, reject.
|
||||||
|
|
||||||
|
## Potential issues
|
||||||
|
|
||||||
|
### Multiple auth-lock events
|
||||||
|
|
||||||
|
Imagine that there are two admins in a room, Alice and Bob.
|
||||||
|
Imagine that there is a malicious user Chelsea.
|
||||||
|
Alice and Bob both ban Chelsea.
|
||||||
|
Alice sees Chelsea send events B -> A.
|
||||||
|
Bob sees Chelsea send events C -> B -> A.
|
||||||
|
Alice and Bob both issue auth_lock events for Chelsea's prior membership.
|
||||||
|
Alice's `extremities` field includes `B`, but excludes `C`.
|
||||||
|
Bob's `extremities` field includes `C`.
|
||||||
|
|
||||||
|
#### Solution
|
||||||
|
|
||||||
|
The receiving server must combine the `extremities` from both events
|
||||||
|
such that the canonical history becomes C -> B -> A.
|
||||||
|
This is already explicitly written within the authorization rules
|
||||||
|
in this MSC.
|
||||||
|
|
||||||
|
### Diverging `extremities`
|
||||||
|
|
||||||
|
Imagine Bob's server receives an `m.auth_lock` event and Bob's server
|
||||||
|
has authorized events referencing the `locked_event_id` that are not
|
||||||
|
present within any relevant `m.auth_lock`'s `extremities`.
|
||||||
|
Bob's server must decide what to do with the events it has already
|
||||||
|
authorized.
|
||||||
|
|
||||||
|
This is a problem that occurs in the following scenarios:
|
||||||
|
|
||||||
|
#### Scenario A: Alice deliberately encodes less `extremities` than Bob has
|
||||||
|
Alice issues an `m.auth_lock` to deliberately encode less or no
|
||||||
|
extremities, in an attempt permanently to diverge Bob's DAG.
|
||||||
|
Joining user David would then also not be able to see a large portion
|
||||||
|
of the history that Bob can, because it wouldn't be authorized in
|
||||||
|
David's DAG when David backfills.
|
||||||
|
|
||||||
|
#### Scenario B: Alice issues a lock quickly after changing an auth event
|
||||||
|
|
||||||
|
Imagine that Alice issues an `m.room.power_levels` event P.
|
||||||
|
Alice revises this event so that it becomes P'.
|
||||||
|
Alice issues an auth_lock for P, Lock-P.
|
||||||
|
Imagine that Alice receives an event B from Bob that references P.
|
||||||
|
Alice and every other server with Lock-P is forced to reject event B.
|
||||||
|
|
||||||
|
#### Scenario C: Bob's events are mixed with Chelsea's
|
||||||
|
|
||||||
|
Chelsea has sent `X -> A` to Alice, but `Y -> A` to Bob.
|
||||||
|
Bob has then appended `B -> Y -> A` and in turn Chelsea
|
||||||
|
has appended `Z -> B -> Y -> A` and sent `Z` to Bob.
|
||||||
|
|
||||||
|
Alice has banned Chelsea and locked Chelsea's prior membership.
|
||||||
|
Only now has Bob received this `m.auth_lock` event, and it only
|
||||||
|
contains the extremity `X`.
|
||||||
|
|
||||||
|
Alice can get `B` if Bob sends it to her,
|
||||||
|
but new joiner David will probably be unable to by backfilling `B`,
|
||||||
|
at least if David's server doesn't have special code to account
|
||||||
|
for the connected events being rejected.
|
||||||
|
|
||||||
|
#### Effects on participating servers
|
||||||
|
|
||||||
|
Servers are required to maintain all their existing `extremities`
|
||||||
|
and their `prev_events`, regardless of whether they are missing from
|
||||||
|
the `extremities` field of any `m.auth_lock` event.
|
||||||
|
|
||||||
|
These servers should still incorporate these diverged `extremities`
|
||||||
|
into `prev_events` so that they can be discovered and repaired later.
|
||||||
|
|
||||||
|
#### Effects on joining servers
|
||||||
|
|
||||||
|
Joining servers will no longer be able to authorize large parts of the
|
||||||
|
room's history.
|
||||||
|
|
||||||
|
#### Solution A: Dedicated API for showing diverged events to room admins
|
||||||
|
|
||||||
|
A room administrator could be made aware of all the extremities that
|
||||||
|
are diverged. This can be done because a server can detect when
|
||||||
|
authorized events contain references to unauthorized events
|
||||||
|
within `prev_events` of authorized events in the DAG.
|
||||||
|
|
||||||
|
A room administrator can then preview the effects of incorporating
|
||||||
|
diverged extremities and make a decision to do so via the
|
||||||
|
`extremities` field of `m.auth_lock`.
|
||||||
|
|
||||||
|
#### Solution B: Room administrators on other servers issue their own `m.auth_lock`
|
||||||
|
|
||||||
|
Room admins residing on different servers with diverged extremities
|
||||||
|
can issue their own `m.auth_lock` event to include diverged extremities.
|
||||||
|
When this event is received by other servers, the diverged extremities
|
||||||
|
can be authorized and the DAG will converge again.
|
||||||
|
|
||||||
|
#### Solution C: Unprivileged users propose changes to the `extremities` of `m.auth_lock`
|
||||||
|
|
||||||
|
Participants in the room can propose changes to the `extremities`
|
||||||
|
contained within `m.auth_lock` via a dedicated event. Room administrators
|
||||||
|
can then review the effects and merge them.
|
||||||
|
|
||||||
|
#### Solution D: Recrafting PDUs
|
||||||
|
|
||||||
|
Take scenario B. Bob receives Lock-P, and notices that B is absent
|
||||||
|
from the chain specified in Lock-P's `extremities`.
|
||||||
|
|
||||||
|
We would need a new MSC for bob to resend B as B' such that servers who
|
||||||
|
have accepted B would recognise B' to be a duplicate that references
|
||||||
|
more recent authorization events.
|
||||||
|
|
||||||
|
This would allow Alice to see `B` in Scenario C. But it wouldn't
|
||||||
|
allow Alice to redact `Z` or `Y`, which Bob my find harmful.
|
||||||
|
|
||||||
|
### Locking all current auth events
|
||||||
|
|
||||||
|
It would be possible to lock all auth_events and stop any further
|
||||||
|
developments in the room.
|
||||||
|
|
||||||
|
## Alternatives
|
||||||
|
|
||||||
|
None recognized.
|
||||||
|
|
||||||
|
|
||||||
|
## Security considerations
|
||||||
|
|
||||||
|
See potential issues.
|
||||||
|
|
||||||
|
|
||||||
|
## Unstable prefix
|
||||||
|
|
||||||
|
None issued.
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
None.
|
||||||
Loading…
Reference in New Issue