This document is a proposal for a handshake process that builds on
existing OpenID technologies to provide a means by which an activity
provider can advertise the availability of an activity stream for a
user at the earliest possible stage of the sign in process.
*Activity Provider*: the service the user is registering for, which
produces an activity stream the user may want to share. Same as the
*Identity Provider*: the OpenID (or similar) service, where the user
already has an account they want to use to login to the *Identity
Consumer*, and where the user has contacts with whom they may want to
share activity information.
* The user wants to register with the Activity Provider and decides to
login with their OpendID Identity Provider rather than registering
using the site’s own registration system. The user's Identity Provider
for the sake of argument is also a social activity aggregator
(Facebook, Plaxo, TypePad, etc)
* The user is redirected to the Identity Provider to be authenticated.
With the request, the Activity Provider includes a request for an
activity callback attribute for the user from the Identity Provider,
using SReg or Attribute Exchange.
* The Identity Provider authenticates the user as usual.
* If the Activity Provider has included the callback request, the
Identity Provider should inform the user that the activity provider
(the OpenID Relying Party) ask the user if they want to share their
activities from Activity Provider with other members of the Identity
* If the user agrees to share their activities, the Identity Provider
responds to the activityhook request with a the URI to a webhook (HTTP
callback) on the Identity Provider’s service.
* If the Identity Provider responds with an activityhook value, the
Activity Provider sends an HTTP POST request to the provided URI,
providing a **feed_uri** parameter and value.
* Upon receiving the post request, the Identity Provider would begin
aggregating the user’s activities to the Identity Provider community.
* Aggregation could take several forms:
* polling the providers feed
* subscribing to the feed on a push hub
* an as-yet undefined straight push from the provider to the aggregator.
Mark Paschal and I (mostly Mark) built two demo Django apps that
implement both the activity provider and identity provider parts of
this handshake. Mark deserves all kinds of praise for working on this
in his spare time to help me out, and for taking it much further than
I had anticipated:
* <http://activity.neologasm.org> is the activity ("Send Thanks!")
side of the equation. The app includes a new AX request with the login
request: http://activitystrea.ms/axschema/callback. This tells the
identity app that the activity app can provide one or more activity
streams for the logging in user.
* <http://identity.neologasm.org> is the identity app ("Cloudface") -
an OpenID provider. If the relying party sends along the callback AX
request, the identity app will prompt the user:
> The relying party indicated that it can provide activity updates to this community. Would you like to share your activities with your followers on this community?
* If the user confirms that they want to share their activity, the
identity provider will return a value that points to a user-specific,
expiring endpoint on the identity site.
* Once the activity app receives the endpoint URI, it POSTs to that
URI a single value: feed_uri. That URI represents the feed for that
* The identity app receives the POST, stores the URI for the user. At
this point the "handshake" suggested above is complete. What the
identity app (the social aggregator) does with the feed is up to the
application. In our case, the identity app checks for a pubsubhubbub
<link> element in the feed (which the Send Thanks app provides) and
subscribes to the feed on pubsubhubbub.
* The activity app pushes updates to pubsubhubbub, which pushes
updates to the identity app.
If you'd like to try it out, you can register on the identity app
linked above. Use that OpenID to sign in on the activity app. After
you've sent a few thanks in the app, you'll start to see the activity
appearing on your profile in the identity app (may take several
minutes to start appearing).
Both of these apps are hosted on github, so if you're a python/django
type feel free to check them out and take a look.
### Discussion / Enhancements
This is a rough sketch, but I think the flow makes sense and all the
pieces are in place to make this happen. The next step would probably
be to expand this system to use a hybrid OpenID / Oauth protocol so
that postbacks can be signed, but how that would best happen is open
My hope with this is that we can get a discussion going that will help
clarify the technological issues as well as the user-interaction
issues. It isn't a difficult implementation (Mark Paschal and I -
mostly Mark - implemented the handshake in a few hours), and I think
the benefits to users, activity providers and social aggregators would
Users are given an easy and understandable opportunity to take
advantage of the power of sharing one’s activity in the community;
activity providers are given more exposure in more communities for
their service, and community/social network providers are given a
valuable tool to increase members’ investment in the network.
On Mon, Oct 19, 2009 at 10:59 AM, Mark Paschal <mark...@markpasc.org> wrote:
> I had thought about federating activity a little since building Action
> Streams for Movable Type, so when you suggested building the demo this
> way, it was different from the technique I had expected:
> * The viewer signs in to the activity service using OpenID/OAuth
> * When an activity occurs, the activity service posts it directly to
> the identity server using AtomPub, authenticating with the OAuth token
> granted at sign-in.
I was just thinking about this, and really, you could do this the same
way we did in the demo, except instead of a feed callback, the
identity app replies with an atompub endpoint. If the login was
performed with the hybrid openid/oauth protocol, then it would work as
In either situation, the advantage of this handshake technique remains
the same: most any app can implement it on top of existing openid/ax
code. I've never been married to the update mechanism, but I maintain
that making it possible to affirm the activity sharing up front is a
> I can see how one might argue we should send something other than the
> Activity Streams feed URL:
> * If it were the URL for an XRD, more services than just the Activity
> Streams feed could be plugged in.
> * If it were the URL of the viewer's HTML profile on the activity
> service, the identity site could use other integration protocols that
> work on profile pages (like feed autodiscovery to get the Activity
> Streams feed and Yadis to get an XRD).
As we discussed earlier, I think providing the user's url is also a
Good Thing. In fact, the possible parameters to the callback just need
to be formalized:
- feed uri
- user profile uri
- what else?
Ultimately, it seems like some sort of capabilities mechanism is
called for - one that:
* doesn't actually depend on having a user's profile url yet
* can be expressed as part the original openid authentication request
XRD, I wonder?
> Thanks for suggesting we build this mock-up. It's been instructive.