GitHub Comments for your GitHub Pages

Custom GitHub App

In order for your readers to comment on your pages, they must be logged in to GitHub, except a third party, like a gh-pages site, does not have the authority to authenticate GitHub users. Only GitHub knows your readers’ GitHub credentials, and it should stay that way. Fortunately, GitHub provides a way for other sites to securely authenticate its users, even if they use two-factor authentication (2FA).

Motivation

ghpages-ghcomments uses GitHub issues as the commenting system for gh-pages sites. For a reader to create a comment on an issue, GitHub requires that the commenter be logged in with the public_repo scope. GitHub allows third parties, like Jekyll gh-pages sites, to let their end users to securely login to GitHub via OAuth.

GitHub Applications

ghpages-ghcomments is a GitHub web application, which means it has a client_id and client_secret pair for using the GitHub API on users’ behalf. GitHub web applications authenticate GitHub users in three steps:

  1. The gh-pages site redirects users to GitHub for access.
  2. Once the user logs in, GitHub redirects back to the gh-pages site with a login code.
  3. The gh-pages site exchanges the code for the user’s OAuth token.

The first step requires the gh-pages site to send GitHub its client_id and requested access scopes. The last step requires the gh-pages site to also send the client_secret. This is a problem for static and fully public gh-pages sites – if the gh-pages site kept the client_secret in the site’s yml data, then any user could impersonate that site.

The only way to keep the client_secret fully secret is to keep it on a separate server where only the gh-pages site has access. Another project, Gatekeeper, has implemented a fast and simple way for GitHub web applications to keep their secrets.

ghpages-ghcomments uses its own Heroku instance of Gatekeeper to complete the GitHub web application authentication flow. This means there are two segments in the trust chain:

  1. The ghpages-ghcomments web application
  2. Heroku’s cloud server

To use ghpages-ghcomments on your site, you must:

    1. Create your own GitHub web application and then
  • A. Use your own Heroku Gatekeeper instance, or
  • B. Host your own server-side authenticator.

0. Custom web application

Creating a GitHub application is painless:

  1. Go to your settings page
  2. Select the Applications item on the left
  3. In the Developer applications panel, select Register new application
  4. Fill in the form:
    • Application name – anything is ok, consider using your site’s title
    • Homepage URL – use the URL to your site
    • Application description – anything is ok, consider using “Comments for [your site’s title]”
    • Authorization callback URL – use the URL to your site
    • Add an application image – consider using your site’s favicon.ico
  5. Once created, you’ll see your Client ID and Client Secret

A. Heroku

Gatekeeper

Gatekeeper has a Node.js implementation, which Heroku can directly serve in a web dyno. Creating a Heroku instance of Gatekeeper is a little more involved:

  1. Prepare Heroku
  2. Clone Gatekeeper:
    • git clone https://github.com/prose/gatekeeper.git
    • cd gatekeeper
  3. Login to Heroku on the command line:
    • heroku login
  4. Create your Heroku app, with your own APP_NAME
    • heroku apps:create APP_NAME
  5. Give your Heroku environment your own XXXX and YYYY GitHub application credentials:
    • heroku config:set OAUTH_CLIENT_ID=XXXX
    • heroku config:set OAUTH_CLIENT_SECRET=YYYY
  6. Deploy your Gatekeeper clone to Heroku:
    • git push heroku master
  7. Check that it’s working:
    • curl https://APP_NAME.herokuapp.com/authenticate/1234
{
  "error": "bad_code"
}

For more details about Heroku, see their Getting Started and How Heroku Works pages.

ghpages-ghcomments

Now that you have your own Gatekeeper instance, update _data/gpgc.yml:

github_application:
  client_id: __YOUR_CLIENT_ID__
  code_authenticator: https://__YOUR_HEROKU_APP__.herokuapp.com/authenticate/
  callback_url: http://__YOUR_CLIENT_CALLBACK_URL__

Summary

  1. Create your own GitHub application
  2. Clone and deploy Gatekeeper to your own Heroku dyno
  3. Update _data\gpgc.yml to match

B. Interface

If you don’t trust a Heroku web application, then you can remove it from the authentication sequence by creating your own GitHub authenticator. At this point, you are using your own GitHub application and your own server-side process to allow your readers to log in to GitHub.

You will still be using the ghpages-ghcomments JavaScript, which expects a specific web interface. Your server-side authenticator must:

  1. Accept a GitHub OAuth temporary code in the URL.
  2. Use the GitHub https://github.com/login/oauth/access_token API to exchange the code for a token.
  3. Respond with JSON: { "token": token }

For a reference implementation, see the Gatekeeper server.js method ` app.get(‘/authenticate/:code’, function(req, res))`.

ghpages-ghcomments

Now that you have your own server-side authenticator, update _data/gpgc.yml:

github_application:
  client_id: __YOUR_CLIENT_ID__
  code_authenticator: https://__YOUR_DOMAIN__/__YOUR_SERVICE__/
  callback_url: http://__YOUR_CLIENT_CALLBACK_URL__

Summary

  1. Create your own GitHub application
  2. Create and deploy your own GitHub web authenticator
  3. Update _data\gpgc.yml to match

Other advanced topics: