You asked for it, so we made GitHub Enterprise support a reality in GitKraken v1.9! That means with GitKraken Pro, all the cool GitHub.com integrations you’ve come to know and love in GitKraken, are now at your disposal for your GitHub Enterprise repositories as well.
Want to know more about what went into making our GitHub Enterprise support possible? Then read on! You can also check out all of the other cool features you get when you upgrade to GitKraken Pro.
Options
One of the things that made GitHub Enterprise a different beast than our GitHub.com integration, is the fact that we wouldn’t be able to rely on GitKraken’s API server to act as a mediator between the client and the service with which GitKraken is trying to interface.
GitKraken uses OAuth to communicate with GitHub.com, meaning the app asks the user, on GitKraken’s behalf, for permission to do a subset of actions for the user in the service. This all works because GitKraken can prove to the service that it is truly the one requesting those permissions for the user, through the use of a “secret” key, kept on the API server, and not shared with the app itself.
This logic falls apart, somewhat, in the case of GitHub Enterprise because the API server can’t really know all of the possible GitHub Enterprise servers it would potentially need to authenticate for. Even if it could, a “secret” key would have to be generated on each individual GitHub Enterprise instance.
The GitKraken dev team went through a litany of potential solutions for the new problems posed by the potential GitHub Enterprise integration and came up with a couple feasible solutions:
1. Release a standalone API server.
One thought was to deploy a standalone API server that could be set up for each GitHub Enterprise instance, presumably by the GitHub Enterprise owner’s IT department or whoever is in charge of maintaining that GitHub Enterprise instance. The drawback here is that there’s a significant amount of work required on the user’s end (or at least their IT department) to set something like that up.
Each user’s GitKraken instance would also need to know where that API server is, in addition to already needing to know where the GitHub Enterprise instance is. We’d also have to build the aforementioned standalone API server, test it, and make documentation for it. Basically, it’d be a lot of work for everyone. Highly illogical if you ask me.
2. Let GitKraken act as the API server, and allow a config file on the user’s system to handle required configuration.
This idea had some really interesting components to it. This would work by allowing a JSON configuration file to be placed on the user’s system (presumably by their IT department) that would contain the necessary information to allow the user’s GitKraken app to act as the API server. It actually probably sounds a lot simpler than it truly is.
One of the neat things about OAuth is that it allows the user to give an app permission to do things on their behalf, without sharing their password with the app. This only actually works if the user isn’t forced to enter their credentials somewhere that’s fully controlled by the app (defeating the purpose of OAuth almost entirely). That means GitKraken needs to hand off the authentication process to an external app that the user can trust (usually their web browser). The interesting part comes in at this point: How can the browser hand information back to the app when the user completes the authentication process?
Well, there’s a bunch of ways to do that, but the most elegant and interesting way (in my humble opinion) is to use a custom protocol handler. We’d essentially tell the user’s system that if a URL with a specified protocol was accessed (likegitkraken://), GitKraken should be used to handle that action.
This would allow the browser to hand the code generated by the authentication process back to GitKraken, so the OAuth process could be completed within the app.
The process for this flow would simply be: the user (or on a larger scale, the user’s IT department) would add a single configuration file within the GitKraken settings directory, and then click a connect button in-app, in a fashion very similar to the current GitHub.com integration. This idea works best on a large scale where there’s an IT department willing and able to automate the process for the user.
3. Use Personal Access Tokens.
GitHub (and lots of other services, actually) allow you to generate a token that can be given the same subsets of permissions as OAuth tokens and can be used in much the same way. Once we have one of those tokens, it can be used in place of an OAuth token that we’d get by performing the authentication process through GitKraken’s API server.
It requires some extra configuration on the user’s part, but given that we need to know where the GitHub Enterprise server is located, some extra configuration is necessary, and there are ways to make that configuration quite painless.
Decisions
The IT-facilitated configuration route (2) and personal access tokens (3) were the two options that were considered most heavily. We eventually settled on personal access tokens as a great starting point for the feature.
This is because of not only the relative ease of implementation but also because it isn’t predicated on the assumption that all GitHub Enterprise users will have an IT department capable of automating the process for them, by creating the configuration file and injecting it into the user’s GitKraken settings.
Personal access tokens also don’t preclude the use of the config file, so it’s something we can expand on in the future for much larger teams if there is significant demand for a slightly more streamlined process.
Another important part of making personal access tokens as simple as possible is making sure that it requires as little user interaction as possible. Unfortunately, we have to direct users to a page with a somewhat overwhelming number of options:
It would be great to try to simplify the process by filling this form out for the user, and not making them have to go back and forth to make sure they have all of the necessary scopes.
We couldn’t find any documentation to support the theory that there might be a way to automatically check those boxes, but if working with GitHub APIs has taught us anything, it’s that they’re really good about making a lot of things dead simple to figure out, even in the absence of documentation.
After a tiny bit of fiddling, we discovered that you can check those boxes and specify a description default, by simply passing a couple of query string parameters. Thanks, GitHub!
Execution
Once personal access tokens were in place, GitHub Enterprise was almost literally a drop-in replacement for GitHub.com at the API level. Seriously, the package that we use to handle fetching and updating user info, repositories, pull requests and SSH Keys, just worked when pointed at a GitHub Enterprise server, instead of GitHub.com, and when given a personal access token instead of an OAuth token. Which is awesome! It means most future integration points we add to GitHub.com will likely automatically work in GitHub Enterprise for free.