Security and Convenience

, Wellesley, MA

The other night I decided to use this website to learn more about OpenID and OAuth. I started from the relatively naive perspective that:

  1. OpenID and OAuth are two different tools I can use to get access to a website or app, and potentially avoid creating yet another account. [1]
  2. Typically, my experience signing in with OAuth has been much more convenient than using OpenID.
  3. I like the convenience of using a single service like Facebook sign on to other services without creating a new identity for every service. But I don’t like the idea that Facebook — or Twitter, Google, Yahoo, or any other single entity — can control my identity and my access to every other service I use.
  4. I like the convenience of using a single username and password on every service I use. But I don’t like the implication that every service would know my credentials on every other service I use.
  5. I like the security of using a different username and password on every service I use. But I don’t like the the inconvenience of remembering all those passwords.
  6. I like the idea of storing all my different passwords in a secure password database. But all the solutions I know of compromise too much convenience or too much security. [2]

I wanted to see if I could take more direct control of my online identity by using matthewlmcclure.com to sign into other websites. It turns out, if a website provides OpenID sign on, that’s as simple as adding two elements to the <head> of my /index.html:

<html>
<head>
    <title>Matt McClure</title>
    <link rel="openid2.provider" href="https://www.google.com/accounts/o8/ud">
    <link rel="openid2.local_id" href="https://www.google.com/accounts/o8/id">
</head>

I delegated to Google since it was much simpler than becoming an OpenID provider myself. But at that point, I hadn’t really gained anything over using Google directly. Finding the correct URLs to use, was also a monumental chore.

Somewhere in the course of exploring how to make that work, I discovered XRDS. XRDS complements OpenID, and lets me replace the above delegation with one that mitigates the dependency on any single OpenID provider.

In my /index.html, I have:

<html>
<head>
    <title>Matt McClure</title>
    <meta http-equiv="X-XRDS-Location" content="http://matthewlmcclure.com/xrds.xml">
</head>

And my /xrds.xml contains:

<?xml version="1.0" encoding="UTF-8"?>
<xrds:XRDS xmlns:xrds="xri://$xrds" xmlns="xri://$xrd*($v*2.0)"
           xmlns:openid="http://openid.net/xmlns/1.0">
    <XRD>
        <Service priority="0">
            <Type>http://specs.openid.net/auth/2.0/server</Type>
            <Type>http://openid.net/srv/ax/1.0</Type>
            <Type>http://specs.openid.net/extensions/ui/1.0/mode/popup</Type>
            <Type>http://specs.openid.net/extensions/ui/1.0/icon</Type>
            <Type>http://specs.openid.net/extensions/pape/1.0</Type>
            <URI>https://www.google.com/accounts/o8/ud</URI>
            <openid:Delegate>https://www.google.com/accounts/o8/id</openid:Delegate>
        </Service>
        <Service priority="1">
            <Type>http://specs.openid.net/auth/2.0/server</Type>
            <Type>http://specs.openid.net/extensions/pape/1.0</Type>
            <Type>http://openid.net/srv/ax/1.0</Type>
            <Type>http://specs.openid.net/extensions/oauth/1.0</Type>
            <Type>http://specs.openid.net/extensions/ui/1.0/lang-pref</Type>
            <Type>http://specs.openid.net/extensions/ui/1.0/mode/popup</Type>
            <Type>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/privatepersonalidentifier</Type>
            <Type>http://www.idmanagement.gov/schema/2009/05/icam/no-pii.pdf</Type>
            <Type>http://www.idmanagement.gov/schema/2009/05/icam/openid-trust-level1.pdf</Type>
            <Type>http://csrc.nist.gov/publications/nistpubs/800-63/SP800-63V1_0_2.pdf</Type>
            <URI>https://open.login.yahooapis.com/openid/op/auth</URI>
            <openid:Delegate>https://open.login.yahooapis.com/openid20/www.yahoo.com/xrds</openid:Delegate>
        </Service>
    </XRD>
</xrds:XRDS>

Now I have a single OpenID delegator http://matthewlmcclure.com that I can use to sign on to a variety of services by delegating to Google or Yahoo. And if I decide later that I prefer a different identity provider over Google or Yahoo, I can change without changing how I sign on to every other service I’m using. I’ll still identify myself as http://matthewlmcclure.com regardless of what OpenID provider I’m using under the hood.

By contrast, websites and applications providing OAuth sign on tend to become tightly coupled to the underlying authorization service. I’m not aware of any website or application that would let me enter my own “OAuth ID”. Instead, the developers have already decided which authorization services I can use by providing a button for each authorization service they’ve selected for me.

OAuth is a clear winner in the user experience department. The chasm between the convenience of clicking a “Sign in with Facebook” button — OAuth — and the inconvenience of typing https://www.google.com/accounts/o8/id — OpenID — is wide. But OpenID is just as clear a winner in the privacy department. OAuth comes with pernicious baggage.

The differences among identity, authentication, and authorization are subtle to most users, and easily confused. OAuth is primarily an authorization tool. OpenID is primarily an identity tool. When you sign on to a website with OAuth, you are not only identifying yourself to the website. You are also authorizing the website to act on your behalf and access anything the underlying authorization service would like to provide to the website. Put more directly, when you sign on to a website with Facebook, you’re potentially giving the website access to everything you’ve ever done on Facebook and vice versa.

To my fellow geeks, do I have this correct, or am I contributing to FUD?

To any non-geek who read this far, will you still use Facebook to sign on to other websites?

[1] Many services that provide OAuth or OpenID sign in still require that users choose a username and password. As a user, you have three choices: (a) use the same username and password you use on other services, (b) use a new unique username and password, (c) don’t use the service. None of those choices is ideal. Choosing (a) is tantamount to the password anti-pattern; you’re giving your credentials on one service to another service. Choosing (b) puts an additional burden on you to remember yet another username and password. Choosing (c) deprives you of the service itself.

[2] I want to store my usernames and passwords in an openly specified, encrypted database format, with open source applications that read and write the database on my computer and my phone. And I want any application that needs one of my usernames and passwords to request it from the application that knows how to read the database. I want the latter application to request my authorization to hand over the credential.

Enjoyed reading this post? Discuss it on Reddit, or follow me on Twitter.