-
Notifications
You must be signed in to change notification settings - Fork 411
MSC4341: Support for RFC 8628 Device Authorization Grant #4341
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
hughns
wants to merge
8
commits into
main
Choose a base branch
from
hughns/device-authorization-grant
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+178
−0
Open
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
b802c76
OAuth 2.0 Device Authorization Grant
hughns 452f5dc
MSC4341
hughns 8a09a7e
Add note about Device Code and Device Flow
hughns 790a533
Suggestions from review
hughns 13db356
Update proposals/4341-device-authorization-grant.md
hughns 13d6289
Update proposals/4341-device-authorization-grant.md
hughns 2706d02
Update proposals/4341-device-authorization-grant.md
hughns 68184aa
Add notes about alternatives
hughns File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
# MSC4341: Support for RFC 8628 Device Authorization Grant | ||
|
||
The current [OAuth 2.0 API](https://spec.matrix.org/v1.15/client-server-api/#oauth-20-api) requires the user to complete | ||
authentication using a web browser on the device where the Matrix client is running. | ||
|
||
This can be problematic if the device does not have a built in web browser or the user wishes to use a different device. | ||
It also causes issues in scenarios where catching the redirect back to the client is hard, like in CLI apps, or | ||
desktop apps with no redirect custom schemes. | ||
|
||
[RFC 8628](https://datatracker.ietf.org/doc/html/rfc8628) defines the OAuth 2.0 Device Authorization Grant which can be | ||
hughns marked this conversation as resolved.
Show resolved
Hide resolved
|
||
used for this purpose. | ||
|
||
## Proposal | ||
|
||
Add the [RFC 8628 OAuth 2.0 Device Authorization Grant](https://datatracker.ietf.org/doc/html/rfc8628) to the [list of supported | ||
grant types](https://spec.matrix.org/v1.15/client-server-api/#grant-types) in the Client-Server API. | ||
|
||
This grant requires the client to know the following authorization server metadata: | ||
|
||
- `grant_types_supported` - this would include `urn:ietf:params:oauth:grant-type:device_code` | ||
- `device_authorization_endpoint` - this would be added to the [table of fields for the 200 response](https://spec.matrix.org/v1.15/client-server-api/#server-metadata-discovery) | ||
- `token_endpoint` - this is already included in the spec | ||
|
||
To use this grant, homeservers and clients MUST: | ||
hughns marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
- Support the device authorization grant as per RFC 8628. | ||
- Support the refresh token grant. | ||
|
||
The [login flow section](https://spec.matrix.org/v1.15/client-server-api/#login-flow) would need to be updated to | ||
reflect that more than one login grant type exists. | ||
|
||
As with the existing authorization code grant, when authorization is granted to a client, the homeserver MUST issue a | ||
refresh token to the client in addition to the access token. | ||
|
||
The access token and refresh token should have the same lifetime constraints as described for the authorization | ||
code grant in the current [spec](https://spec.matrix.org/v1.15/client-server-api/#refresh-token-grant). | ||
|
||
### Sample flow | ||
|
||
The user wishes to login to a Matrix client on a device that doesn't have a web browser built in (e.g. a TV), but wishes | ||
to complete the login on another device (e.g. a smartphone). | ||
|
||
1. The Matrix client [discovers the OAuth 2.0 server metadata](https://spec.matrix.org/v1.15/client-server-api/#server-metadata-discovery). | ||
|
||
This step is as per the current Matrix spec, but as per [RFC 8628 section 4](https://datatracker.ietf.org/doc/html/rfc8628#section-4) | ||
it should include the value `urn:ietf:params:oauth:grant-type:device_code` in the `grant_types_supported` field and specify | ||
a `device_authorization_endpoint` field. | ||
|
||
2. The Matrix client [registers itself as a client with the homeserver](https://spec.matrix.org/v1.15/client-server-api/#client-registration). | ||
|
||
This step is as per the current Matrix spec. | ||
|
||
3. The Matrix client sends a Device Authorization Request to the `device_authorization_endpoint` as per [RFC 8628 section 3.1](https://datatracker.ietf.org/doc/html/rfc8628#section-3.1). | ||
|
||
The `client_id` should be as per the registration step above, and the `scope` as described in the current [spec](https://spec.matrix.org/v1.15/client-server-api/#scope). | ||
|
||
e.g. | ||
|
||
```http | ||
POST /oauth2/device HTTP/1.1 | ||
Host: account.matrix.org | ||
Content-Type: application/x-www-form-urlencoded | ||
|
||
client_id=my_client_id&scope=urn%3Amatrix%3Aclient%3Aapi%3A%2A%20urn%3Amatrix%3Aclient%3Adevice%3AABCDEGH | ||
``` | ||
|
||
4. The homeserver responds to the Matrix client with the Device Authorization Response as per [RFC 8628 section 3.2](https://datatracker.ietf.org/doc/html/rfc8628#section-3.2). | ||
|
||
For example: | ||
|
||
```http | ||
HTTP/1.1 200 OK | ||
Content-Type: application/json | ||
|
||
{ | ||
"device_code": "GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS", | ||
"user_code": "WDJB-MJHT", | ||
"verification_uri": "https://account.matrix.org/link", | ||
"verification_uri_complete": "https://account.matrix.org/link?user_code=WDJB-MJHT", | ||
"expires_in": 1800, | ||
"interval": 5 | ||
} | ||
``` | ||
|
||
It is recommended that the server provides a `verification_uri_complete` such that the user does not need to type in the | ||
`user_code`. | ||
|
||
5. The Matrix client device conveys the returned `verification_uri_complete` (and/or `verification_uri`+`user_code`) to | ||
the user. | ||
|
||
Exactly how the client does this depends on the specific device characteristics and use case. | ||
|
||
For example, for a CLI application the `verification_uri` and `user_code` could be displayed as text for the user to | ||
type into their other device. | ||
|
||
Or, another example would be the `verification_uri_complete` (with fallback to the `verification_uri`) could be encoded | ||
and displayed as a QR code for scanning on the other device (e.g. on a TV). | ||
|
||
6. The user opens the `verification_uri_complete` (or `verification_uri`) on their other device that has a web browser. | ||
|
||
The user then completes authentication and authorization for the login. | ||
|
||
7. Whilst the user is doing this, the Matrix client starts polling the `token_endpoint` for an outcome. | ||
|
||
Frequency of polling is determined by the `interval` value returned in the Device Authorization Response from step 4. | ||
|
||
The poll request made by the client is the Device Access Token Request from [RFC 8628 section 3.4](https://datatracker.ietf.org/doc/html/rfc8628#section-3.4). | ||
|
||
e.g. | ||
|
||
```http | ||
POST /oauth2/token HTTP/1.1 | ||
Host: account.matrix.org | ||
Content-Type: application/x-www-form-urlencoded | ||
|
||
grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code&device_code=GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS&client_id=my_client_id | ||
``` | ||
|
||
The server in turn responds with the Device Access Token Response as per [RFC 8628 section 3.5](https://datatracker.ietf.org/doc/html/rfc8628#section-3.5). | ||
|
||
Whilst the authorization is still outstanding a `authorization_pending` (or `slow_down` in the case of rate limiting) | ||
error code will be returned. | ||
|
||
If the authorization is rejected then the `access_denied` error code will be returned. | ||
|
||
If the authorization does not complete within the `expires_in` timeframe then the `expired_token` error code will be returned. | ||
|
||
For a successful authorization the response will be an access token and refresh token as described in the current Matrix | ||
[spec](https://spec.matrix.org/v1.15/client-server-api/#login-flow). | ||
|
||
8. The Matrix client refreshes the access token with the refresh token grant when it expires. | ||
|
||
This is as per the current spec. | ||
|
||
9. The Matrix client revokes the tokens when the users wants to log out of the client. | ||
|
||
This is as per the current spec. | ||
|
||
## Potential issues | ||
|
||
Some literature refers to the Device Authorization Grant as the | ||
[Device Code](https://oauth.net/2/grant-types/device-code/) grant type or [Device Flow](https://curity.io/resources/learn/oauth-device-flow/). | ||
This MSC uses the name from the actual RFC. | ||
|
||
Otherwise, none identified. | ||
|
||
## Alternatives | ||
|
||
I'm not aware of any other standardised OAuth grant types that would be suitable as an alternative. | ||
|
||
### Requiring support for the new grant type | ||
|
||
We could make it mandatory that new grant type is supported by Matrix homeservers. | ||
|
||
As currently proposed it is optional and discoverable via the `grant_types_supported` metadata. | ||
|
||
### Make `verification_uri_complete` be mandatory | ||
|
||
RFC 8628 makes makes `verification_uri_complete` optional, but we could make it mandatory. This could improve the UX for some | ||
use cases. | ||
|
||
## Security considerations | ||
|
||
[RFC 8628 section 5](https://datatracker.ietf.org/doc/html/rfc8628#section-5) contains various security considerations | ||
that homeserver and client implementors should consider. | ||
|
||
Additionally, [RFC 9700](https://datatracker.ietf.org/doc/html/rfc9700) Best Current Practice for OAuth 2.0 Security | ||
mentions clickjacking as a consideration for the server and advises on appropriate measures. | ||
|
||
## Unstable prefix | ||
|
||
Although the response from the server metadata discovery endpoint is modified, because | ||
[we already defined it](https://spec.matrix.org/v1.15/client-server-api/#get_matrixclientv1auth_metadata) as being | ||
[RFC 8414](https://datatracker.ietf.org/doc/html/rfc8414) it isn't appropriate to introduce unstable prefixes. | ||
|
||
## Dependencies | ||
|
||
None. |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.