It is easier, faster, and cheaper to borrow GitHub for your next internal business app than to write your own login/reset-password/two-factor authentication/team management system.

example-login

In 2018 it is easier than ever to write small bespoke web apps for your business. Pick a high-level web framework (Ruby on Rails, Spring/Java) with a high-level ORM, collect data from SaaS products with APIs, send data to Slack, deploy in minutes to Cloud Foundry/Kubernetes/Heroku, and then rinse and repeat with your favourite CI system.

Any application deployed to the public internet needs authentication to control who is allowed to see/edit your data. The VPN is dead, says Google.

Today, none of Google’s employee-facing applications are on a virtual private network. They all have public IP addresses.
The company feels this approach, which it has dubbed BeyondCorp, is the “new cloud model”

When granting or denying access to our web apps we have two questions to ask of every user/interaction:

  1. Authentication - who is this person using your site?
  2. Authorization - what is this person allowed to see/do?

In Google's BeyondCorp infrastructure they even scope authorization by each device you use:

“The access is granted based on context: Who are you? Have you authenticated in a strong way? What are you using? What do I know about your device?”

Keeping it Simple

For our Stark & Wayne apps we wanted to keep it simple, and we wanted a solution that would work with our Cloud Foundry-based Pivotal Web Services provider.

So we did the simplest thing there is - nothing. We implemented no new authentication or authorization system. Instead, we used a system that already existed, and that almost everyone already an account: GitHub.

Our new applications were being written in Ruby on Rails, and the https://github.com/fphilipe/warden-github-rails library was very simple to use. We could restrict access to routes based on users being guests, authenticated via their GitHub account (we know their email address & name), or authorized by their membership of the https://github.com/starkandwayne organization or a smaller team.

Here is a sample of this library in action to guide different routes/catch-alls to different behavior based on the user's GitHub memberships:

Rails.application.routes.draw do
  get '/login'  => 'sessions#create', as: :login
  get '/logout' => 'sessions#destroy', as: :logout

  github_authenticate(team: ENV['GITHUB_STAFF_TEAM']) do
    root to: "site#show"
    resources :staff, only: [:index, :show, :update]
    ...
  end

  github_authenticate() do
    root to: "help#help_not_in_team"
    match '*all' => 'help#help_not_in_team', via: :all
  end

  github_unauthenticated() do
    root to: "help#help_unauthenticated"
    match '*all' => 'help#help_unauthenticated', via: :all
  end
end

A guest will see the help_unauthenticated page which displays "Please login via GitHub".

There are millions of people with GitHub accounts, and less than 100 staff at Stark & Wayne, so we need to be more discerning.

If someone logs in with their GitHub account, but they are not a member of a specific team in the https://github.com/starkandwayne organization, they will see the help_not_in_team page to explain that this application is not for them, or that they should ask their manager to add them to the GitHub team.

Additional Security for Free

At Stark & Wayne, we require all GitHub accounts to have two-factor authentication to be enabled.

This means that our GitHub-protected internal apps are also protected by two-factor authentication. Access to our internet-facing systems requires both their GitHub credentials and their mobile phone/yubi key.

By not implementing our own single-sign-on system, we also didn't have to implement a password reset/email/SMS system. GitHub engineers wrote this for us.

We also didn't have to implement an authorization system to add/remove users or change their permissions. We add staff to our GitHub organization when they join (after they have enabled 2FA), and can then add them to any teams to access different internal applications.

GitHub APIs

A secondary benefit to using GitHub for our applications' authentication/authorization is that we are authorized to interact with the GitHub API on behalf of each user.

An application could look up a users repositories, their commit history, issues, pull requests, and more.

Mostly our business apps don't need to do this. We're using the GitHub API for its authentication/authorization system rather than the API itself.

Google Apps vs GitHub

One API that our business apps would like to talk to is the Google Apps API - viewing/updating staff calendars, viewing/inserting/updating data in spreadsheets, and more.

It is this secondary benefit/feature - permission to access the Google Apps API - that has led us to investigate moving away from using GitHub to using Google Apps for our auth system.

For this we need staff to authorize the application to access subsets of the Google Apps APIs. That is, replace the same process using with GitHub, but change to Google Apps. Our staff should not see a substantial difference - they'll only need to re-login after the switch and grant new permissions to Google Apps subsystems. Stay tuned.