|
| 1 | +# MSC0000: OpenID information exchange for widgets |
| 2 | + |
| 3 | +With the various integrations API proposals, widgets are left with no options to verify the |
| 4 | +requesting user's ID if they need it. Widgets like the sticker picker must know who is making |
| 5 | +the request and as such need a way to get accurate information about who is contacting them. |
| 6 | + |
| 7 | +This proposal introduces a way for widgets (room and account) to do so over the `fromWidget` |
| 8 | +API proposed by [MSC1236](https://github.com/matrix-org/matrix-doc/issues/1236). |
| 9 | + |
| 10 | + |
| 11 | +## Proposal |
| 12 | + |
| 13 | +Room and account widgets may request a new OpenID object from the user so they can log in/register with |
| 14 | +the backing integration manager or other application. This is largely based on the prior art available |
| 15 | +[here (riot-web#7153)](https://github.com/vector-im/riot-web/issues/7153). The rationale for such an |
| 16 | +API is so that widgets can load things like a user's sticker packs or other information without having |
| 17 | +to rely on secret strings. For example, a room could be used to let a user create custom sticker packs |
| 18 | +via a common widget - it would be nice if that widget could auth the user without asking them to enter |
| 19 | +their username and password into an iframe. |
| 20 | + |
| 21 | +Widgets can request OpenID credentials from the user by sending a `fromWidget` action of `get_openid` |
| 22 | +to intiate the token exchange process. The client should respond with an acknowledgement of |
| 23 | +`{"state":"request"}` (or `{"state":"blocked"}` if the client/user doesn't think the widget is safe). |
| 24 | +The client should then prompt the user if the widget should be allowed to get details about the user, |
| 25 | +optionally providing a way for the user to always accept/deny the widget. If the user agrees, the |
| 26 | +client sends a `toWidget` action of `openid_credentials` with `data` holding the raw OpenID credentials |
| 27 | +object returned from the homeserver, and a `success: true` parameter. If the user denies the widget, |
| 28 | +just `success: false` is returned in the `data` property. To lessen the number of requests, a client may |
| 29 | +also respond to the original `get_openid` request with a `state` of `"allowed"`, `success: true`, and |
| 30 | +the OpenID object (just like in the data for `openid_credentials`). The widget should not request OpenID |
| 31 | +credentials until after it has exchanged capabilities with the client, however this is not required. The |
| 32 | +widget should acknowledge the `openid_credentials` request with an empty response object. |
| 33 | + |
| 34 | +A full sequence diagram for this flow is as follows: |
| 35 | + |
| 36 | +``` |
| 37 | ++-------+ +---------+ +---------+ |
| 38 | +| User | | Client | | Widget | |
| 39 | ++-------+ +---------+ +---------+ |
| 40 | + | | | |
| 41 | + | | Capabilities negotiation | |
| 42 | + | |<-----------------------------------------| |
| 43 | + | | | |
| 44 | + | | Capabilities negotiation | |
| 45 | + | |----------------------------------------->| |
| 46 | + | | | |
| 47 | + | | fromWidget get_openid request | |
| 48 | + | |<-----------------------------------------| |
| 49 | + | | | |
| 50 | + | | ack with state "request" | |
| 51 | + | |----------------------------------------->| |
| 52 | + | | | |
| 53 | + | Ask if the widget can have information | | |
| 54 | + |<--------------------------------------------| | |
| 55 | + | | | |
| 56 | + | Approve | | |
| 57 | + |-------------------------------------------->| | |
| 58 | + | | | |
| 59 | + | | toWidget openid_credentials request | |
| 60 | + | |----------------------------------------->| |
| 61 | + | | | |
| 62 | + | | acknowledge request (empty response) | |
| 63 | + | |<-----------------------------------------| |
| 64 | +``` |
| 65 | + |
| 66 | +Prior to this proposal, widgets could use an undocumented `scalar_token` parameter if the client chose to |
| 67 | +send it to the widget. Clients typically chose to send it if the widget's URL matched a whitelist for URLs |
| 68 | +the client trusts. Widgets are now not able to rely on this behaviour with this proposal, although clients |
| 69 | +may wish to still support it until adoption is complete. Widgets may wish to look into cookies and other |
| 70 | +storage techniques to avoid continously requesting credentials. |
| 71 | + |
| 72 | +A proof of concept for this system is demonstrated [here](https://github.com/matrix-org/matrix-react-sdk/pull/2781). |
| 73 | + |
| 74 | +The widget is left responsible for dealing with the OpenID object it receives, likely handing it off to |
| 75 | +the integration manager it is backed by to exchange it for a long-lived Bearer token. |
| 76 | + |
| 77 | +## Security considerations |
| 78 | + |
| 79 | +The user is explicitly kept in the loop to avoid automatic and silent harvesting of private information. |
| 80 | +Clients must ask the user for permission to send OpenID information to a widget, but may optionally allow |
| 81 | +the user to always allow/deny the widget access. Clients are encouraged to notify the user when future |
| 82 | +requests are automatically handled due to the user's prior selection (eg: an unobtrusive popup saying |
| 83 | +"hey, your sticker picker asked for your information. [Block future requests]"). |
0 commit comments