- 
                Notifications
    You must be signed in to change notification settings 
- Fork 414
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.
          
          
  
     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.