Building a Dynamic OAuth Application for GitHub Enterprise Integrations - 7pace
Sign in GET STARTED
Published:Jan 24, 2022

Building a Dynamic OAuth Application for GitHub Enterprise Integrations

This post was authored by 7pace Engineer, Eugene Kolomytsev, in collaboration with wordsperson Tyler Hakes.

OAuth makes the world go ‘round.

Being able to seamlessly connect and authorize applications — and the user experience that comes with one-click login or signup — has become part of the backbone of the modern internet.

But there’s just one problem.

When OAuth doesn’t work — or doesn’t work as per normal — things can get complicated pretty quickly. Authorizing access, managing permissions, and maintaining security become infinitely more complex without an out-of-the-box system.

This is exactly what we ran up against when building 7pace for GitHub Enterprise.

github cloud extension workflow

We quickly discovered that the normal process for easily authenticating 7pace inside the GitHub instance wouldn’t work for an Enterprise installation. And, because of this, we had to develop an entirely new system to allow users to install and use 7pace inside their local installation or hosted instance of GitHub Enterprise.

In this article, I’ll explain how our team built a 4-step process for overcoming the challenges with OAuth and installing third-party integrations inside a hosted GitHub Enterprise instance.

GitHub for Enterprise: A Quick Primer on Integrations

Whereas all GitHub data exists in the cloud and can be easily accessed with a simple authentication procedure thanks to its static nature with preconfigured OAuth applications and processes, GitHub Enterprise is — first of all — installed on a local or hosted server.

Right off the bat, this presents a challenge when building integrations because the Host server and Organization are customized for each instance. But this, on its own, would be fairly easy to solve. By simply asking the user to provide the information, we would be able to connect and authenticate to the 7pace OAuth application and be on our way.

This is where things get tricky.

When using GitHub Enterprise, you cannot simply install the 7pace OAuth application out of the box like you might from the GitHub marketplace. There is no 7pace OAuth application for GitHub Enterprise.

That’s why none of the other time tracking companies in the marketplace offer an option for GitHub Enterprise. It requires manual setup and installation.

But 7pace was built to be simple — both to use and to install.

Rather than manually configuring and installing our application for GitHub Enterprise customers, we wanted to create a simple and seamless experience for installing 7pace.

github installing 7pace

To solve these challenges, we built an installation process comprising 4 steps:

  1. Collect GitHub Enterprise server information
  2. Dynamically generate a new OAuth application
  3. Install and authorize the new OAuth application – this is similar to cloud GitHub
  4. Generate OAuth scheme settings

Like all engineering challenges, the solution seems obvious in retrospect.

As we worked through the problem, we figured out how to tackle each challenge in order and build something that would feel as seamless as installing 7pace for cloud GitHub.

Dynamically Generating the OAuth Application

Let’s solve the “easy” problem first.

We know that GitHub Enterprise is installed locally or hosted on a server. Before we can connect the 7pace app for this instance, we need to know where it lives.

We’ve boiled this down to two fields that are required to begin the installation process:

  1. Host name
  2. Organization name

Knowing the Host Name and Organization Name, we can then move forward. With this information, we can dynamically generate a new application that will allow us OAuth access to connect to 7pace.

This is the first step in the installation process.

Dynamically Generating the OAuth Application

By collecting this information from the user, we’re able to dynamically generate a new application that can be installed locally on the server.

Installing and Authorizing With the OAuth Application

From the user’s perspective, they’ll now enter into the workflow to create a new application.

All of the required fields and other information is automatically generated. All the user needs to do is name the application (or use the default).

All of the heavy lifting is handled by the installer.

We analyzed the UI for creating a GitHub OAuth app and found out that it is making a POST request to an URL with following pattern:

https://github.com/organizations/owner/settings/apps/new

This means that after collecting the GitHub Enterprise Host and Organization name, we can generate the URL for the correct POST request:

https://${host}/organizations/${owner}/settings/apps/new

And provide a JSON body for the request with all predefined settings as we want:

{
           "name": "7pace-app",
           "url": origin,
           "hook_attributes": {
               "url": origin,
           },
           "redirect_url": `${origin}/GitHubEnterprise/SaveCreatedApp`,
           "callback_url": `${callbackUrl}`,
           "public": true,
…
}

With a redirect_url set to return to the 7pace App and with all of the data required to connect to the 7pace app within the response body of that callback, we have all of the information we need to generate and install a new OAuth application from scratch.

All we need to do is to wrap all that logic within a <form> on a page and present it to the user.

Then we store the information in the database — host, org name, app name, and all of the required secret information to authenticate with OAuth.

Add OAuth Scheme Redirects

This would all be too easy if there wasn’t one more hurdle.

On the 7pace side, we would normally store the OAuth scheme for each system (one for GitHub and one for Azure DevOps based on the predefined parameters that we receive when the application is created (before actual deployment of a system).

services.AddOAuth<TOptions, THandler>( schemeName, options =>{...})

But, in this instance, the 7pace application does not know the information needed to generate a static OAuth scheme. Again, GitHub Enterprise installations are not static. So, again, we need to handle this dynamically.

In this case, it’s a process of elimination.

Rather than cycling through all registered schemes, we maintain an on-demand of only the relevant schemes with each user authentication action.

If it is a new authorization process, we simply ask the user to provide the Host name.

If it’s a known Host name, we generate an OAuth Scheme, making an authorization and authentication and creating auth token for that user.

After a scheme is used, it is removed from the list of schemes, to not be cycled if any other users log in using a different scheme.

If it is a login challenge or a token update, we also know the origin of that token and before challenging OAuth, generate a scheme. Then we remove that scheme from the pool as soon as the challenge is completed.

With this system, the same scheme could be generated and removed multiple times, but it is a lightweight process and does not affect performance and the authorization process happens without any unnecessary schemes being stored.

Installing 7pace for GitHub Enterprise

Net-net, our goal is to create a user experience that’s as simple and as intuitive as possible.

We’ve literally built our entire business on giving developers and development teams more control over their time and their work—while protecting the hell out of every second.

So having a three-click process for setting up and installing 7pace in the GitHub Enterprise instance wasn’t just a fun engineering project. It’s actually critical to our entire mission as a business.

Now, teams using GitHub Enterprise can use 7pace to track and manage their time and there’s no drawn-out, complicated installation process that requires weeks of engineering and support time.

It just takes a few clicks to install.

See for yourself: Install 7pace for GitHub Enterprise.

Free eBook

Rethinking Timekeeping for Developers:

Turning a Timesuck Into Time Well Spent

Leave a Comment

By submitting this form I confirm that I have read the privacy policy and agree to the processing of my personal data for the above mentioned purposes.

Send

Sign up for GitHub News

    I would like to sign up to receive email updates from 7pace. Protected by 7pace's privacy policy .