Jekyll Auth
A simple way to use GitHub OAuth to serve a protected Jekyll site to your GitHub organization
The problem
Jekyll and GitHub Pages are awesome, right? Static site, lightning fast, everything versioned in Git. What else could you ask for?
But what if you only want to share that site with a select number of people? Before, you were SOL. Now, simply host the site on a free, Heroku Dyno, and whenever someone tries to access it, it will Oauth them against GitHub, and make sure they're a member of your Organization. Pretty cool, huh?
Requirements
- A GitHub account (one per user)
- A GitHub Organization (of which members will have access to the Jekyll site)
- A GitHub Application (you can register one for free)
- A Heroku account (you can technically use this elsewhere, but the instructions are for Heroku)
Getting Started
Create a GitHub Application
- Navigate to the GitHub app registration page
- Give your app a name
- Tell GitHub the URL you want the app to eventually live at
- Hit Save, but leave the page open, you'll need some of the information in a moment
Add Jekyll Auth to your site
- Add
gem 'jekyll-auth'
to yourGemfile
or if you don't already have aGemfile
, create a file calledGemfile
in the root of your site's repository with the following content:
source "https://rubygems.org"
gem 'jekyll-auth'
cd
into your project's directory and runbundle install
.Run
bundle exec jekyll-auth new
which will copy the necessary files to set up the server
Setting up hosting with Heroku
Automatically
Run bundle exec jekyll-auth --client_id XXX --client_secret XXX --org_id XXX
(or --team_id XXX
)
Manually
- You may need to add and commit the files generated by
jekyll-auth new
to Git before continuing - Make sure you have the Heroku toolbelt installed
- Run
herkou create
from your site's directory heroku config:set GITHUB_CLIENT_ID=XXX GITHUB_CLIENT_SECRET=XXX GITHUB_ORG_ID=XXX
(orGITHUB_TEAM_ID
)git push heroku
heroku open
to open the site in your browser
Finding the team ID
If you need help finding a team's numeric ID, you can use the jekyll-auth team_id
command.
For example, to find the team ID for @jekyll/maintainers you'd run the command:
jekyll-auth team_id --org jekyll --team maintainers
You'll want to add a personal access token to your .env
file so that Jekyll-Auth can make the necessary API request, but the command will run you through the process if you dont.
Configuration
Whitelisting
Don't want to require authentication for every part of your site? Fine! Add a whitelist to your Jekyll's config.yml file:
jekyll_auth:
whitelist:
- drafts?
jekyll_auth.whitelist
takes an array of regular expressions as strings. The default auth behavior checks (and blocks) against root (/
). Any path defined in the whitelist won't require authentication on your site.
What if you want to go the other way, and unauthenticate the entire site except for certain portions? You can define some regex magic for that:
jekyll_auth:
whitelist:
- "^((?!draft).)*$"
There is also a more extensive article containing installation instructions for Jekyll-Auth and a second one on how to find your GitHub team ID.
Requiring SSL
If you've got SSL set up, simply add the following your your _config.yml
file to ensure SSL is enforced.
jekyll_auth:
ssl: true
Using a custom 404
Just like GitHub Pages, Jekyll Auth will honor a custom 404 page, if it's generated as /404.html
in the built site.
Running locally
Want to run it locally?
Without authentication
Just run jekyll serve
as you would normally
With authentication
export GITHUB_CLIENT_ID=[your github app client id]
export GITHUB_CLIENT_SECRET=[your github app client secret]
export GITHUB_ORG_ID=[org id]
orexport GITHUB_TEAM_ID=[team id]
orexport GITHUB_TEAM_IDS=1234,5678
jekyll-auth serve
Pro-tip #1: For sanity sake, and to avoid problems with your callback URL, you may want to have two apps, one with a local oauth callback, and one for production if you're going to be testing auth locally.
Pro-tip #2: Jekyll Auth supports dotenv out of the box. You can create a .env
file in the root of site and add your configuration variables there. It's ignored by .gitignore
if you use jekyll-auth new
, but be sure not to accidentally commit your .env
file. Here's what your .env
file might look like:
GITHUB_CLIENT_SECRET=abcdefghijklmnopqrstuvwxyz0123456789
GITHUB_CLIENT_ID=qwertyuiop0001
GITHUB_TEAM_ID=12345
Under the hood
Every time you push to Heroku, we take advantage of the fact that Heroku automatically runs the rake assets:precompile
command (normally used for Rails sites) to build our Jekyll site and store it statically, just like GitHub pages would.
Anytime a request comes in for a page, we run it through Sinatra (using the _site
folder as the static file folder, just as public
would be normally), and authenticate it using sinatra_auth_github.
If they're in the org, they get the page. Otherwise, all they ever get is the bouncer.
Upgrading from Jekyll Auth < 0.1.0
cd
to your project directoryrm config.ru
rm Procfile
- Remove any Jekyll Auth specific requirements from your
Gemfile
- Follow the instructions above to get started
- When prompted, select "n" if Heroku is already set up