From 03d4482d05deb7e7e479805c70ce29219f7f3003 Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Tue, 14 Sep 2021 13:30:16 +0100 Subject: [PATCH 1/5] proposal --- proposals/3395-synthetic-appservice-events.md | 153 ++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 proposals/3395-synthetic-appservice-events.md diff --git a/proposals/3395-synthetic-appservice-events.md b/proposals/3395-synthetic-appservice-events.md new file mode 100644 index 000000000..ac51cc9bb --- /dev/null +++ b/proposals/3395-synthetic-appservice-events.md @@ -0,0 +1,153 @@ +# MSC3395: Synthetic Appservice Events + +Most services today have the concept of a webhook, which is used to inform an external service about +the state of another service. For instance when a new user is registered on a platform, it is useful +to alert a bot to send a welcome message. + +In Matrix we already have the concept of services which complement the homeserver, known as Application +Services. However, they can only be informed of user actions that have taken place in rooms (with +the notable exception of presence / device updates via EDUs). This proposal aims to extend the existing +AS spec to include "synthetic" events where the homeserver can inform the appservice when a variety of +things have happened on the homeserver. + +For clarity, this MSC introduces a modest set events that could be extended by further MSCs: + +- User registration +- User login +- User logout +- User deactivation + + +## Proposal + +An appservice must subscribe to the changes that it wishes to listen for. This can be done by setting a new +key in the appservice registration file: `m.synthetic_events`: + +```yaml +m.synthetic_events: + events: + - "m.user.registration" + - "m.user.login" + - "m.user.logout" + - "m.user.deactivated" +``` + +Then, when the homeserver wishes to inform a appservice of an event it would send the event over the appservice `/transaction` +API. The homeserver is NOT expected to retry these events if the appservice is down, + +``` +PUT /_matrix/app/v1/transactions/{txnId} +``` + +```json5 +{ + "m.synthetic_events": [{ + "type": "m.user.deactivated", + "content": { + "user_id": "@alice:example.com" + }, + "ts": 1432735824653, + }], + "events": [/* ... */] +} +``` + +For each of the event types given above, there is a definition: + +### `m.user.registration` + +This should be sent when a new user registers on the homeserver. + +```json5 +{ + + "type": "m.user.registration", + "content": { + "user_id": "@alice:example.com" + } +} +``` + +### `m.user.login` + +This should be sent when an existing user logs in on the homeserver. + +```json5 +{ + + "type": "m.user.login", + "content": { + "user_id": "@alice:example.com", + "device_id": "ABCDEF" + } +} +``` + +### `m.user.logout` + +This should be sent when an existing user logs out of their session. + +```json5 +{ + + "type": "m.user.logout", + "content": { + "user_id": "@alice:example.com", + "soft_logout": true, + "device_id": "ABCDEF" + } +} +``` + +### `m.user.deactivated` + +This should be sent when an existing user deactivates their account. + +```json5 +{ + + "type": "m.user.logout", + "content": { + "user_id": "@alice:example.com", + } +} +``` + +## Potential issues + + +Appservices can now request permissions to reveal quite intimate details about each user, which means that homeserver +administrators will need to be more careful when adding new appservice registrations. However, it has always been the +case that appservices should be considered powerful tools that need review before being connected. + +This proposal would not work over a federated context, as federated homeservers are not aware of foregin appservices. +That being said, the events suggested in this proposal are sensitive and are expected to only be shared with immediate +appservices connected to the homeserver. It would be possible for an appservice to "proxy" these events to a seperate room +if federation of the information is desired, though. + + +## Alternatives + +One alternative would be to have homeserver implementations make an "events" room, which sends these events +as normal room events rather than synthetic events. Appservices would be joined and left to this room and would +recieve events organically. However there are some problems with this approach: + +- It increases the burden on the homeserver implementor to manage these rooms, including membership of + each appservice. +- It would require each of these events to be stored in the homeserver database, which would increase storage + costs over time and would require homeservers to store lots of activity in the database. +- While varying by implementation, it would be slower to store an event in a room and send it to an AS, than + just to send it. +- Each event type would need it's own room to allow fine grained control over which events the appservice would + recieve, at least until a form of per-message ACLs lands in the spec. + +For these reasons, the suggested proposal was chosen. + +## Security considerations + +These events will be sent down the same channel as other AS events, and so the security footprint +is not impacted. + +## Unstable prefix + +All keys mentioned in this document beginning with `m.` will use `uk.half-shot.mscXXXX.` as the prefix. \ No newline at end of file From 068d29f6d49bca8c737c4e7ba7c0017b869fea0f Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Tue, 14 Sep 2021 13:52:39 +0100 Subject: [PATCH 2/5] formatting tweaks --- proposals/3395-synthetic-appservice-events.md | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/proposals/3395-synthetic-appservice-events.md b/proposals/3395-synthetic-appservice-events.md index ac51cc9bb..b25ad18fe 100644 --- a/proposals/3395-synthetic-appservice-events.md +++ b/proposals/3395-synthetic-appservice-events.md @@ -17,7 +17,6 @@ For clarity, this MSC introduces a modest set events that could be extended by f - User logout - User deactivation - ## Proposal An appservice must subscribe to the changes that it wishes to listen for. This can be done by setting a new @@ -33,7 +32,7 @@ m.synthetic_events: ``` Then, when the homeserver wishes to inform a appservice of an event it would send the event over the appservice `/transaction` -API. The homeserver is NOT expected to retry these events if the appservice is down, +API. If the application service is down, these events SHOULD be retried when the appservice comes back up. ``` PUT /_matrix/app/v1/transactions/{txnId} @@ -52,7 +51,8 @@ PUT /_matrix/app/v1/transactions/{txnId} } ``` -For each of the event types given above, there is a definition: +For each of the event types given above, there is an expected schema. As with all Matrix +event contents, this can be extended to include implementation specific metadata. ### `m.user.registration` @@ -60,7 +60,6 @@ This should be sent when a new user registers on the homeserver. ```json5 { - "type": "m.user.registration", "content": { "user_id": "@alice:example.com" @@ -74,7 +73,6 @@ This should be sent when an existing user logs in on the homeserver. ```json5 { - "type": "m.user.login", "content": { "user_id": "@alice:example.com", @@ -89,7 +87,6 @@ This should be sent when an existing user logs out of their session. ```json5 { - "type": "m.user.logout", "content": { "user_id": "@alice:example.com", @@ -105,27 +102,24 @@ This should be sent when an existing user deactivates their account. ```json5 { - "type": "m.user.logout", "content": { - "user_id": "@alice:example.com", + "user_id": "@alice:example.com" } } ``` ## Potential issues - Appservices can now request permissions to reveal quite intimate details about each user, which means that homeserver administrators will need to be more careful when adding new appservice registrations. However, it has always been the case that appservices should be considered powerful tools that need review before being connected. This proposal would not work over a federated context, as federated homeservers are not aware of foregin appservices. -That being said, the events suggested in this proposal are sensitive and are expected to only be shared with immediate +That being said the events suggested in this proposal are sensitive and are expected to only be shared with immediate appservices connected to the homeserver. It would be possible for an appservice to "proxy" these events to a seperate room if federation of the information is desired, though. - ## Alternatives One alternative would be to have homeserver implementations make an "events" room, which sends these events @@ -150,4 +144,4 @@ is not impacted. ## Unstable prefix -All keys mentioned in this document beginning with `m.` will use `uk.half-shot.mscXXXX.` as the prefix. \ No newline at end of file +All keys mentioned in this document beginning with `m.` will use `uk.half-shot.mscXXXX.` as the prefix. From db2597befe55c93d62779e427358563b4dc28b83 Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Thu, 16 Sep 2021 10:54:22 +0100 Subject: [PATCH 3/5] Move the key into the namespaces field --- proposals/3395-synthetic-appservice-events.md | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/proposals/3395-synthetic-appservice-events.md b/proposals/3395-synthetic-appservice-events.md index b25ad18fe..7f1dffce9 100644 --- a/proposals/3395-synthetic-appservice-events.md +++ b/proposals/3395-synthetic-appservice-events.md @@ -20,7 +20,7 @@ For clarity, this MSC introduces a modest set events that could be extended by f ## Proposal An appservice must subscribe to the changes that it wishes to listen for. This can be done by setting a new -key in the appservice registration file: `m.synthetic_events`: +key in the appservice registration file: `m.synthetic_events`, under the `namespaces` key: ```yaml m.synthetic_events: @@ -31,8 +31,14 @@ m.synthetic_events: - "m.user.deactivated" ``` -Then, when the homeserver wishes to inform a appservice of an event it would send the event over the appservice `/transaction` -API. If the application service is down, these events SHOULD be retried when the appservice comes back up. +Currently only the `namespaces.users` field can contain this key, though the door is left open for +future MSCs to expand upon this feature and allow synthetic events for different contexts. + +Then, when the homeserver wishes to inform a appservice of an event it would send the event over the +appservice `/transaction` API. If the application service is down, these events SHOULD be retried when +the appservice comes back up. + +As the synthetic events are namespaced, the AS should only be sent events for users in that namespace. ``` PUT /_matrix/app/v1/transactions/{txnId} @@ -113,7 +119,8 @@ This should be sent when an existing user deactivates their account. Appservices can now request permissions to reveal quite intimate details about each user, which means that homeserver administrators will need to be more careful when adding new appservice registrations. However, it has always been the -case that appservices should be considered powerful tools that need review before being connected. +case that appservices should be considered powerful tools that need review before being connected. The ability to +namespace the events sent allows for fine-grained control. This proposal would not work over a federated context, as federated homeservers are not aware of foregin appservices. That being said the events suggested in this proposal are sensitive and are expected to only be shared with immediate From 6249e2e8b5c56f63fbca396c84fde03dbdb22b0c Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Thu, 16 Sep 2021 10:58:56 +0100 Subject: [PATCH 4/5] Also allow to opt-out of normal events --- proposals/3395-synthetic-appservice-events.md | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/proposals/3395-synthetic-appservice-events.md b/proposals/3395-synthetic-appservice-events.md index 7f1dffce9..6b2dcf107 100644 --- a/proposals/3395-synthetic-appservice-events.md +++ b/proposals/3395-synthetic-appservice-events.md @@ -23,12 +23,17 @@ An appservice must subscribe to the changes that it wishes to listen for. This c key in the appservice registration file: `m.synthetic_events`, under the `namespaces` key: ```yaml -m.synthetic_events: - events: - - "m.user.registration" - - "m.user.login" - - "m.user.logout" - - "m.user.deactivated" +namespaces: + users: + - exclusive: false # This needs to be false to allow for registrations + regex: "@.*:mydomain" + m.events: false # Allow or disallow normal events to be sent from this namespace. + m.synthetic_events: + events: + - "m.user.registration" + - "m.user.login" + - "m.user.logout" + - "m.user.deactivated" ``` Currently only the `namespaces.users` field can contain this key, though the door is left open for @@ -40,6 +45,9 @@ the appservice comes back up. As the synthetic events are namespaced, the AS should only be sent events for users in that namespace. +Because a namespace is listed for these users, the AS will also recieve room events for these users by default. To opt-out +of sending room events to the AS (and allow only synthetic events to be sent), the key `m.events` can be set to `false`. + ``` PUT /_matrix/app/v1/transactions/{txnId} ``` From 6c1c855088b1e83a74edb81e22e6e238b38e333f Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Fri, 24 Sep 2021 14:08:55 +0100 Subject: [PATCH 5/5] Correct MSC3395 name Co-authored-by: Brendan Abolivier --- proposals/3395-synthetic-appservice-events.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/3395-synthetic-appservice-events.md b/proposals/3395-synthetic-appservice-events.md index 6b2dcf107..595e0022b 100644 --- a/proposals/3395-synthetic-appservice-events.md +++ b/proposals/3395-synthetic-appservice-events.md @@ -159,4 +159,4 @@ is not impacted. ## Unstable prefix -All keys mentioned in this document beginning with `m.` will use `uk.half-shot.mscXXXX.` as the prefix. +All keys mentioned in this document beginning with `m.` will use `uk.half-shot.msc3395.` as the prefix.