All infrastructure related to WebPlatform Docs is shut down since 2016. Mentions about SSO and OAuth is still (2020) accessible from the archived webplatform.github.io/docs/WPD/Projects/SSO wiki pages.

How to run your own OAuth Identity provider service

Tags

Generally, we connect our application against a provider so it can share details about a user. Most of the documentation you'll find online explains how to use their service, but very few outlines concisely how it is if you want to be your own provider and share state across applications you also manage.

Documentation would generally allow your third party app to let users use their information from another site such as Facebook, GitHub, Twitter, etc.

But what if you wanted to share information across your web applications in a similar way?

This post is a quick summary of how things works so you can get acquainted with the basics.

Whitelist

Big sites aren't generally one big code repository but a set of separate components. A way to make each component to share your account details is most possibly by making a difference between their own infrastructure and third parties.

If your app were to use an external resource such as Google, the process would end up making Google users to be asked if they really want to share their information with you. This is why they would get a dialog similar to this.

While its OK to ask confirmation from a user if he wants to share his details with an external site, in the case of two components from the same site can share this information transparently.

OAuth confirmation modal with Google logo. Asking: My project is requesting permission to: Manage your calendars, manage your documents.

Looking at this OAuth dialog, I can't help but feel a bit uneasy. Sure, it looks clean and official, but I'm noticing how many apps are asking for more access than they seem to need. What bugs me is we can't pick and choose - it's all or nothing. I've got this nagging feeling that companies might use this to grab as much data as they can about us, building detailed profiles along the way. With how quickly this is catching on, it's starting to feel like a ticking time bomb for our personal info. Maybe I'm overthinking it, but something about this just doesn't sit right with me.

If you are your own Identity Provider, you can configure your relying parties as "whitelisted" so that your accounts system don't display such dialog.

Becoming your own Identity provider

In the case of WebPlatform.org we wanted to become our own Identity provider and found that we could deploy our own fork of Firefox Accounts ("FxA") would allow us to do so.

The way its designed is that we have an OAuth protected "profile" endpoint that holds user details (email, full name, etc) as a "source of truth". Each relying party (your own wiki, discussion forum, etc) gathers information from and ensure it has the same information locally.

In order to do so, we have to make a module/plugin for each web application so we it can query and bootstrap users locally based on the accounts system. We call those "relying parties".

Once we have relying party adapter in place, a web app will have the ability to check by itself with the accounts server to see if there's a session for the current browsing session. If it has, it'll give either an already generated OAuth Bearer token, or generate one for the one for the service in question — the "SSO" behavior.

With the OAuth Bearer token in hand, a relying party (i.e. the WebPlatform.org annotation service) can go read details from the "profile" endpoint and then check locally if it already has a user available.

WebPlatform Notes A Specification annotation tool
The WebPlatform Notes specification annotation tool.

It was one of the last parts added to the WebPlatform project and was designed to support adding annotations to specifications and to leverage a Single-Sign-On between other parts of the site.

Unfortunately the project never released the feature to the public before closing.

But I’ve made a YouTube video of its integration while I was building it. The notes about it are available in the archived wiki

If the relying party doesn't have a user, it'll create one.

Terminal session issuing HTTP call using cURL
With appropriate HTTP headers for current OAuth bearer token, requesting data to a profile server and giving current user’s data.

Each relying party is responsible to sync its local user and session state based on what the accounts service gives.

Seeing in action

Here is a recording I made showing how it looked like;