Skip to content

MSC4155: Invite filtering #4155

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

Open
wants to merge 28 commits into
base: main
Choose a base branch
from
Open
Changes from 2 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
6adc165
MSC4155: Invite filtering
Johennes Jun 13, 2024
43aef70
Fix typo
Johennes Jun 13, 2024
b8b226a
Update proposal with feedback from pull request
Johennes May 27, 2025
dcde420
Update proposals/4155-invite-filtering.md
Johennes May 30, 2025
04169f8
Update proposals/4155-invite-filtering.md
Johennes May 30, 2025
8c81fd5
Update proposals/4155-invite-filtering.md
Johennes May 30, 2025
d132a13
Update proposals/4155-invite-filtering.md
Johennes May 30, 2025
2345a5b
Update proposals/4155-invite-filtering.md
Johennes May 30, 2025
a558adb
Update proposals/4155-invite-filtering.md
Johennes May 30, 2025
a47dbce
Update proposals/4155-invite-filtering.md
Johennes May 30, 2025
e9478f0
Update proposals/4155-invite-filtering.md
Johennes Jun 2, 2025
29324e9
Drop capability and enforce the config on the server only
Johennes Jun 4, 2025
2f17aa7
Add missing client-side review option as a potential issue
Johennes Jun 4, 2025
3b248c5
Update proposals/4155-invite-filtering.md
Johennes Jun 5, 2025
230ed37
Update proposals/4155-invite-filtering.md
Johennes Jun 5, 2025
f916f98
Update proposals/4155-invite-filtering.md
Johennes Jun 5, 2025
44ecf7e
Update proposals/4155-invite-filtering.md
Johennes Jun 5, 2025
88fe9cc
Fix list indentation
Johennes Jun 26, 2025
be64f07
Extend alternatives
Johennes Jun 26, 2025
e526862
Update proposals/4155-invite-filtering.md
Johennes Jun 26, 2025
52c8bd5
Clarify interaction with m.ignored_user_list
Johennes Jun 30, 2025
0eee397
Fix typo
Johennes Jun 30, 2025
21521f0
Spell out what the globs should operate on
Johennes Jun 30, 2025
643c5bc
Avoid 'eponymous'
Johennes Jul 8, 2025
5c3cab8
Avoid over-specifying null / missing behaviour
Johennes Jul 8, 2025
16dd841
Update proposals/4155-invite-filtering.md
Johennes Jul 8, 2025
e735ee8
Add expanding m.ignored_user_list as an alternative
Johennes Jul 8, 2025
f65b9b2
Ignore ports when applying server globs
Johennes Jul 9, 2025
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
134 changes: 134 additions & 0 deletions proposals/4155-invite-filtering.md
Copy link
Member

@turt2live turt2live Jun 13, 2024

Choose a reason for hiding this comment

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

Implementation requirements:

  • Client supporting the feature, and using it

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since I believe all the gematik implementations will be closed source, I'll reference #3860 (comment) as an example for how cases like this were handled in the past. Thanks @clokep for digging it up.

Copy link
Contributor

@Half-Shot Half-Shot Mar 27, 2025

Choose a reason for hiding this comment

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

element-hq/synapse#18288 is a serverside implementation, albeit with #4155 (comment) "corrected"

Copy link
Contributor

Choose a reason for hiding this comment

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

element-hq/element-web#29603 exposes the serverside settings in the client, but does no filtering of itself. @Johennes does this evoke any worries from you if the invite filtering is done server-side?

Copy link
Contributor Author

@Johennes Johennes Mar 27, 2025

Choose a reason for hiding this comment

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

No, I this is fine and consistent with the proposal which allows but doesn't enforce the filtering on either the client or the server. Now that I think of it, we might need a capability so that the client knows when the server does not filter in which case the client needs to filter itself.

Copy link
Contributor

Choose a reason for hiding this comment

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

element-hq/synapse#18288 supports the updated proposal.

Copy link
Member

Choose a reason for hiding this comment

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

With my SCT hat:

The following implementations demonstrate the desire for filtering, and experiment with different ordering, but all demonstrate that the code is more than possible:

The following implementations show that there's desire, but don't do much with the actual config:

Collectively, I feel this satisfies the implementation component, though we should monitor for user feedback if the rule processing order feels wrong. If so, we can correct it with a future MSC relatively easily (it'll suck for people on implementations which use the 'old' rules, but as those implementations update users will see the changes).

Copy link
Member

Choose a reason for hiding this comment

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

If so, we can correct it with a future MSC relatively easily (it'll suck for people on implementations which use the 'old' rules, but as those implementations update users will see the changes).

I wish I shared your confidence. Won't it (also) suck for people who have set up rules with the "old" system, which suddenly don't work because the ordering has changed? And then they'll change the rules and get something that works with their client but not their server.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I cannot think of a good way to prevent that other than blocking this MSC to let implementations try out the currently proposed ordering in practice. That'll involve exactly the same migration pain for users if the proposal changes, just that people will (hopefully consciously) have opted into an explicitly unstable implementation at their own risk.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah I don't disagree with you there. At some point we're going to have to just decide that we have enough confidence in the ordering that it's worth shipping. I just think it's worth having our eyes open to the fact that changing it later is going to be a bit of a buttpain, rather than "relatively easy" as Travis claimed.

Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
# MSC4155: Invite filtering

Matrix supports ignoring users via the eponymous [module] and the `m.ignored_user_list` account data
event. This is a nuclear option though and will suppress both invites and room events from the ignored
users. Additionally, the `m.ignored_user_list` event only allows for block-list configurations that ignore
specific users but doesn't have a mechanism to ignore entire servers. These shortcomings make the module
insufficient for use cases such as tightly locked down applications where ignoring needs to be the default
behaviour.

This proposal generalises the ignoring users [module] to allow filtering invites specifically. The scheme
outlined below is conceptually borrowed from the [gematik specification]. The main purpose of this proposal
is to ensure that this option is available for comparison with [other existing MSCs] that attempt to address
invite filtering.


## Proposal

To allow users to configure which other users are allowed to invite them into rooms, a new account data
event `m.invite_permission_config` is introduced.

```json5
{
"type": "m.invite_permission_config",
"content": {
"default": "allow | block",
"user_exceptions": {
"@someone:example.org": {},
...
},
"server_exceptions": {
"example.org": {},
...
}
}
}
```

The `default` field defines the standard setting that is applied to all invites that don't match an
exception. Exceptions invert the default setting and are provided via the `user_exceptions` and
`server_exceptions` fields which follow the format of the `ignored_users` field in `m.ignored_user_list`.

As an example, a block-list configuration that ignores invites from `@badguy:scam.org` but allows invites
from any other user would look like this:

```json5
{
"type": "m.invite_permission_config",
"content": {
"default": "allow",
"user_exceptions": {
"@badguy:scam.org": {},
}
}
}
```

In contrast, an allow-list configuration that permits invites from users on goodguys.org but blocks invites
from all other servers would look like this:

```json5
{
"type": "m.invite_permission_config",
"content": {
"default": "block",
"server_exceptions": {
"goodguys.org": {},
}
}
}
```

Note that since the default setting for entities that don't match an exception is part of the configuration,
an exception for a user does _not_ need to be accompanied by an exception for their server[^1].

Servers MAY suppress invites for which the configuration evaluates to `block` and not send them to the recipient.
They MAY additionally reject the invite.

Clients SHOULD hide invites from users for which the permission configuration evaluates to `block`. They MAY
allow reviewing ignored invites in a dedicated section of their UI.


## Potential issues

Larger permission configurations could run into the [event size limit] of 65536 bytes. This issue also exists
with the `m.ignored_user_list` event.


## Alternatives

As mentioned above, the main goal of this proposal is to offer an alternative so that the question of invite
filtering can be answered holistically. Therefore, this section will not attempt to make a case for why the
current proposal is better than others and instead simply list the alternatives known to the author at the
time of writing:

- [MSC2270] (which borrows from `m.ignored_user_list` to ignore rooms and invites)
- [MSC3659] (which introduces a push-rule-like grammar to filter invites)
- [MSC3840] (which is similar to this proposal but only supports block-list semantics)
- [MSC3847] (which ignores invites by building on [moderation policy lists] and could be combined with
[MSC4150] to support both block-list and allow-list use cases)


## Security considerations

None.


## Unstable prefix

Until this proposal is accepted into the spec, implementations should refer to `m.invite_permission_config`
as `org.matrix.msc4155.invite_permission_config`. Note that the [gematik specification], which predates
this MSC, uses an event type of `de.gematik.tim.account.permissionconfig.v1` and slightly different field
names. Given that the general JSON scheme of the event is the same though, implementations of the
[gematik specification] should largely be equivalent to implementations of this MSC.


## Dependencies

None.


[^1]: This is in contrast to e.g. [Mjolnir] which requires two `org.matrix.mjolnir.allow` rules, one for
the user ID and one for the server name, to build an allow list that only permits a single user.

[event size limit]: https://spec.matrix.org/v1.10/client-server-api/#size-limits
[gematik specification]: https://github.com/gematik/api-ti-messenger/blob/9b9f21b87949e778de85dbbc19e25f53495871e2/src/schema/permissionConfig.json
[Mjolnir]: https://github.com/matrix-org/mjolnir
[MSC2270]: https://github.com/matrix-org/matrix-spec-proposals/pull/2270
[MSC3659]: https://github.com/matrix-org/matrix-spec-proposals/pull/3659
[MSC3840]: https://github.com/matrix-org/matrix-spec-proposals/pull/3840
[MSC3847]: https://github.com/matrix-org/matrix-spec-proposals/pull/3847
[MSC4150]: https://github.com/matrix-org/matrix-spec-proposals/pull/4150
[moderation policy lists]: https://spec.matrix.org/v1.10/client-server-api/#moderation-policy-lists
[module]: https://spec.matrix.org/v1.10/client-server-api/#ignoring-users
[other existing MSCs]: #alternatives