Using XRDS


Back when people were trying to bring OpenID, LID, and i-names together, something called Yadis was born. At the time, it was all pretty abstract to me, but over time I've come to understand more of the details. Yadis was a discovery protocol for identifiers that was based on XRDS, or eXtensible Resource DescriptorS.

The basic idea was that when you resolved an identifier, you'd get back an XRDS document that would tell you which authentication service the identifier was associated with. I'll talk about the details of how this happens in a minute. First, let's talk about why and what.

One of the things an XRDS document can contain is a pointer to an authentication service. IN fact, that's the most common usage pattern at present. So, when you enter an i-name or a URL into an application that understands Yadis, it will retrieve the XRDS document, look for an authentication service type and endpoint and then use that authentication service. So, the same URL could be an OpenID or a LID identifier depending on what the XRDS document contains that is at that URL.

Yadis has been folded into OpenID 2.0, so from now on, I'll not mention Yadis specifically--any OpenID 2.0 relying party or identity provider will understand XRDS.

XRDS documents are just XML. So, they're mostly human readabe and editable. But, like most complicated XML, you can get confused pretty fast. The XRI resolution specification is the document that describes how XRDS works. An XRDS document is a collection of services. For example, here's the OpenID service descriptor on my i-name:

<xrd:Service>

    <xrd:Type xrd:select='true'>
      http://openid.net/signon/1.0
    </xrd:Type>

    <xrd:URI xrd:priority='1' xrd:append='qxri'>
      https://2idi.com/openid/
    </xrd:URI>

    <xrd:URI xrd:priority='2' xrd:append='qxri'>
      http://2idi.com/openid/
    </xrd:URI>

</xrd:Service>

This says that if I enter my i-name (=windley) at a place that understands OpenID 2.0, that I want to use 2idi's OpenID identity provider as my authentication service. If I changed this XRDS document, I could use MyOpenID.com or any other authentication service transparently to the relying party.

XRDS is more than just a way of pointing to authentication services, however. Andy Dale left a comment about XRDS in response to my post on Sun's support of OpenID and their linking it to employment. He points out that XRDS could be used, in this case, to point to an attribute exchange service that would have attributes giving employment status or even a more general reputation service. He points out that:

The trick is having OpenID providers expose the XRDS to end users in a way that is useful to them. By that I mean a) They have the ability to 'change' their own XRDS. b) Providers support an automatic provisioning protocol so that end users can easily adopt new services without having to craft XML and manually edit their XRDS.

He expanded on his comment in blog post on using XRDS and then expanded on that in a follow up. He points out, that a user had their Flickr feed listed as a http://photo.feed/1.0 type service in their XRDS wouldn't have to tell applications that need that info anything about it--just entering their identifier would allow another application to find out which service providers that person used.

So, how do you return an XRDS document from an identifier? The simplest way is to sign up for an OpenID or an i-name and let the identity provider do it for you. The problem is that most IdPs don't currently allow you to change the contents of your XRDS doc easily. 2idi, the i-name broker I use does. So, as long as I'm happy just using my i-name, that works.

If I want to return an XRDS document that I control from a URL I'm using as an identifier, I probably need to serve it up myself. If you're running your own Web server, that's not to hard. This write up by Josh Hoyt shows how to configure a URL that returns an XRDS document using Apache and some modules (no code).

The basic idea is that I want a URL, say http://phil.windley.org to return it's normal content (from index.shtml in my case) for anything that's not asking for xml+xrds content. That can be accomplished using mod_negotiation to do content negotiation, mod_headers to add the right headers to the response, and mod_rewrite to redirect to the appropriate location (the XRDS doc or the index.shtml document.

This gives you a way of configuring XRDS-style services on whatever URL you want to use as an identifier. You still need to edit the XML by hand, but at least you can.

As an aside, it strikes me that you could use this same trick to put a WADL discovery document for a RESTful API at the API URL and return it when the request specifically set the content type to xml+wadl. A nice way of overloading the URL so that it's the service endpoint and the discovery endpoint all at the same time. Of course, some are bound to object that this isn't very RESTful.

So, that's basically everything I know about XRDS. I plan to XRDS enable on of my identifying URLs and play with it some more. I'll let you know how the experiment goes.