Skip to content

Discussion: Streamlined GitHub authentication #93

Closed
@shana

Description

@shana

Goal

To streamline authentication for users connecting to GitHub or GitHub Enterprise for the purposes of using a GitHub application. Ideally, the user doesn't have to anything beyond logging into their account and authorizing access to an application (without copy pasting tokens).

Authentication tokens and scopes:

GitHub APIs almost always require a token to access them. Some don't (because the data is public for eg.), but anonymous calls are severely rate limited, so any app using the API for public data will need a token at some point

The API has a granular permission system, and a token will have scopes attached to it, so that only those endpoints or actions that the scopes allow will be usable.

  1. Git operations only need a repo scope
  2. GitHub API operations can need other scopes - user, discussion, gist, etc, depending on what they're doing.

There are three ways to obtain a token:

  1. The user creates a personal access token in their settings page and select the scopes.

    • Pros: The application doesn't need to be registered anywhere or handle authentication.
    • Cons: This is error prone and requires a lot of manual steps for the user.
  2. The application obtains a token on behalf of the user by doing the oauth2 web authentication flow - opening a browser to the server that will show the requested permissions for the user to authorize, and returning the token to the app

    • Pros: The user can see what permissions the application is requesting. If the user has already given this application these permissions before, the step is automatic and the user doesn't have to do anything at all
    • Cons: Requires the application to listen to a webrequest in some way, which can be problematic behind firewalls
  3. The application obtains a token on behalf of the user by asking the user for their username and password, their 2FA code, and calling the GitHub OAuth rest API endpoint with this information, along with the desired scopes, and obtaining a token in return.

    • Pros: No need for external browsers or listening to web requests, everything is handled by the application
    • Cons: Doesn't work for SSO-enabled organizations

The oauth webflow for applications

While the OAUTH Rest API is usable by any desktop app, the webflow is more complicated. The web flow requires that GitHub redirect the user to a known URI at the end of the authentication - this request includes the token in the body. For desktop applications, this is a bit tricky to pull off.

There are strategies around this:

  1. Desktop applications that have their own installers can install a protocol handler on the system, and configure the redirect URI to be a particular protocol (like desktop:// or something://).

    • apps using this approach: Desktop
    • Pros: doesn't require listening to any web requests
    1. Cons: Requires an installer with permissions to install the protocol handler. The handler can be overridden by any app at any time
  2. The application can listen on a known port on localhost, and the callback URI is configured to http(s)://localhost:PORT.

    • apps using this approach: GHfVS
    • Pros: localhost listeners bypass the network stack entirely (implemented on the loopback interface), so no data goes out to the network at all when the browser loads a localhost address (i.e. no one can sniff the data). That means we can use http, and listening on ports above a certain range does not require admin permissions
    • Cons: Since the callback URI is fixed in the oauth app on GitHub, there is no way to do dynamic ports on the listener. That means that if something else on the system is using that particular port, we can't do the webflow at all.
  3. The callback URI is configured to go to a separate webservice/webapp (running on heroku for eg.). The local application opens a websocket to the webservice to prepare it for handling the authentication, and the webservice handles all the redirects for the webflow. Once the webservice receives the token, it sends it back to the local application via the websocket

    • apps using this approach: Git Kraken
    • Pros: no local port conflicts, no local webservers listening on things. The application doesn't need to store the clientId and clientSecret data, that's on the webservice (which is a big plus)
    • Cons: Would this work behind a heavily proxies firewall? Unsure

What the extension does today

Right now, the extension requires the user to create a token manually and store it in the settings file. If there isn't a token in the settings, it will try to use whatever is available to Git via the credential helper - which is brittle, given that that token might not have enough permissions.

/cc @RMacfarlane @sguthals @daviwil

Metadata

Metadata

Assignees

Labels

feature-requestRequest for new features or functionalitygithubRelated to GitHub API

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions