A proposal for delegation in OAuth identity verification

26 views
Skip to first unread message

Raffi Krikorian

unread,
Feb 9, 2010, 7:13:15 PM2/9/10
to twitter-deve...@googlegroups.com
hi all.

i apologise that i'm running behind on getting these out, but i've put out the first in a series of blog posts regarding what twitter is doing with oauth moving forward -- this one, specifically, is a RFC around "delegation in OAuth identity verification".  a total mouthful, i know, so it may help to think about it in a concrete example:

You're an OAuth enabled Twitter client, and you've already authorized your user.  You user wants to use a media providing service like TwitPic.  TwitPic, currently, asks for the username and password of your user so it can store the photo on behalf of the Twitter user.  You don't have that username and password, so how do you give the ability to TwitPic to verify the identity of your user?


thanks!

--
Raffi Krikorian
Twitter Platform Team
http://twitter.com/raffi

Michael Steuer

unread,
Feb 9, 2010, 7:50:08 PM2/9/10
to twitter-deve...@googlegroups.com
Hi Raffi,

Very pleased that this went out... I've been pushing for this on this list for quite a while now...

Let us know if you need any help in any way...

As a side note - TweetPhoto has claimed on this list that they have some sort of oAuth delegation live?? I haven't played with it yet, but perhaps someone who has can comment on what it actually is that they've done?

Thanks,

Michael.

Raffi Krikorian

unread,
Feb 9, 2010, 8:00:30 PM2/9/10
to twitter-deve...@googlegroups.com
Very pleased that this went out... I've been pushing for this on this list for quite a while now...

Let us know if you need any help in any way...

i think the biggest thing is just to comment on it, or let me know that it makes sense.  this is relatively easy for us to implement, but we want to make sure its right before go forth.
 
As a side note - TweetPhoto has claimed on this list that they have some sort of oAuth delegation live?? I haven't played with it yet, but perhaps someone who has can comment on what it actually is that they've done?

tweetphoto has a notion of delegation - 


the main difference, however, is that they require that the client's consumer key be shared with them -- that breaks the security model of oauth a bit.
 

Brian Smith

unread,
Feb 9, 2010, 11:24:49 PM2/9/10
to twitter-deve...@googlegroups.com

In the example, would the user have to grant TwitPic access to his account? I would like to be able to assure TwitPic about the user’s identity without the user having to grant TwitPic any read or read/write access to his account.

 

Why does the delegator need to send the service provider x_request_method, x_request_url, x_request_parameters, and x_request_authorization? For example, why does Twitter need to know what the user is doing with TwitPic? It seems like an unnecessary disclosure of information that should stay between the consumer and the delegator. The end-user might want to authenticate using his Twitter credentials without telling Twitter what he’s doing.

 

Instead, the consumer should just sign <some constant>||timestamp||nonce||expiration_date with their Twitter access token/secret, since that’s all Twitter needs to verify the end-user’s possession of the Twitter access token. The delegator should be responsible for securing its own service (e.g. against replay).

 

In particular, the delegator should be able to use this service, even if the delegator doesn’t otherwise use OAuth for protecting its own resources, and even if the consumer isn’t communicating with the delegator over HTTP (think WebSockets, SPDY, etc.).

 

Regards,

Brian

 

Harshad RJ

unread,
Feb 9, 2010, 11:43:09 PM2/9/10
to twitter-deve...@googlegroups.com
I posted a response on the blog which I am copy-pasting here:


If the intention is to just delegate identity, this can be achieved more easily with what is available today:

The Consumer, prepares a verify-credentials HTTP request, signed with its OAuth token, and passes this URL to the delegator, which in turn will simply issue this request on the consumer's behalf.

Since a signed request doesn't contain the token-secrets, this is pretty safe to the consumer as well as end user.

Some more thoughts:
  • Perhaps the plan is to scale this workflow to action delegation. In which case it makes sense to introduce the new flow.
  • The term delegator is confusing. Shouldn't it be delegatee or something :)
--
Harshad RJ
http://hrj.wikidot.com

Raffi Krikorian

unread,
Feb 10, 2010, 12:22:38 AM2/10/10
to twitter-deve...@googlegroups.com
hi all.

thanks so much for the conversation so far!  its been great.  i've taken a bunch of the comments and incorporated them into a newer version


let's continue to tear this apart.

Brian Smith

unread,
Feb 10, 2010, 3:09:40 AM2/10/10
to twitter-deve...@googlegroups.com

The term most frequently used for “delegator” is “relying party.” What you call the service provider is most frequently called the “identity provider.” What you call the consumer is usually called the “subject.” See OpenID, InfoCard, and other similar specifications for example usage of these terms.

 

The subject does not want just *anybody* to verify his identity; he only wants the *relying party* to be able to verify his identity. So, the subject needs to be able to identify the relying party in the string he signs. Then the identity provider needs to be able to verify that the relying party is the one making the request, so the relying party needs to sign the request with its OAuth credentials.

 

The subject doesn’t want the relying party to have access to the entire response from the account/verify_credentials request as if he had given the relying party read access to his account. I am not sure if account/verify_credentials returns sensitive information (information only available to apps that have been authorized by the user) yet, but I think it is likely in the future that it will do so. It would be prudent to have delegation use a different resource designed specifically for delegation.

Also, it would be great if the consumer could require the delegator to also use TLS when verifying the identity. Maybe OAuth Wrap/2.0 will mandate HTTPS for this?

 

Careful attention needs to be paid to whether or not it is safe to expose something the subject has signed to the relying party in OAuth WRAP/2.0, if WRAP/2.0 is designed to have this information always protected from third parties with TLS.

 

Regards,

Brian

Raffi Krikorian

unread,
Feb 10, 2010, 12:31:12 PM2/10/10
to twitter-deve...@googlegroups.com

The term most frequently used for “delegator” is “relying party.” What you call the service provider is most frequently called the “identity provider.” What you call the consumer is usually called the “subject.” See OpenID, InfoCard, and other similar specifications for example usage of these terms.

i hear all this - it just gets a bit complicated with because we are conflating this with our oauth situation.  perhaps its time to move to an oauth + openID hybrid system.

 The subject does not want just *anybody* to verify his identity; he only wants the *relying party* to be able to verify his identity. So, the subject needs to be able to identify the relying party in the string he signs. Then the identity provider needs to be able to verify that the relying party is the one making the request, so the relying party needs to sign the request with its OAuth credentials.

in the general case, i completely understand this, in the twitter case, however, i'm not so sure?  either way, as i said, i believe this in the general case, and i will modify to account for this.

The subject doesn’t want the relying party to have access to the entire response from the account/verify_credentials request as if he had given the relying party read access to his account. I am not sure if account/verify_credentials returns sensitive information (information only available to apps that have been authorized by the user) yet, but I think it is likely in the future that it will do so. It would be prudent to have delegation use a different resource designed specifically for delegation.


i think this is again a general case vs a twitter case.  i think in the general case, the delegator would call some endpoint that would simply verify the identity through a HTTP code (2xx for success, 4xx for failure).  twitter, as a special case, sends along the user object ass part of it? 

Also, it would be great if the consumer could require the delegator to also use TLS when verifying the identity. Maybe OAuth Wrap/2.0 will mandate HTTPS for this?

that's going towards the oauth 2.0/wrap world.  when i write this up to account for oauth 2.0/wrap, i'll note that ssl is required.

this has been great!

Dewald Pretorius

unread,
Feb 10, 2010, 12:35:55 PM2/10/10
to Twitter Development Talk
Raffi,

You said, "sends along the user object ass part of it".

Does that explain why the user object is in some cases a bit bloated?

On Feb 10, 1:31 pm, Raffi Krikorian <ra...@twitter.com> wrote:
> > The term most frequently used for “delegator” is “relying party.” What you
> > call the service provider is most frequently called the “identity provider.”
> > What you call the consumer is usually called the “subject.” See OpenID,
> > InfoCard, and other similar specifications for example usage of these terms.
>
> > i hear all this - it just gets a bit complicated with because we are
>
> conflating this with our oauth situation.  perhaps its time to move to an
> oauth + openID hybrid system.
>

> >  The subject does not want just **anybody** to verify his identity; he
> > only wants the **relying party** to be able to verify his identity. So,

Raffi Krikorian

unread,
Feb 10, 2010, 12:39:25 PM2/10/10
to twitter-deve...@googlegroups.com
nice

Harshad RJ

unread,
Feb 10, 2010, 1:12:59 PM2/10/10
to twitter-deve...@googlegroups.com
On Wed, Feb 10, 2010 at 11:05 PM, Dewald Pretorius <dpr...@gmail.com> wrote:
Raffi,

You said, "sends along the user object ass part of it".

Does that explain why the user object is in some cases a bit bloated?


And what does it mean when the HTTP response code is 503.


Harshad RJ

unread,
Feb 10, 2010, 1:15:35 PM2/10/10
to twitter-deve...@googlegroups.com
On Wed, Feb 10, 2010 at 11:42 PM, Harshad RJ <harsh...@gmail.com> wrote:


On Wed, Feb 10, 2010 at 11:05 PM, Dewald Pretorius <dpr...@gmail.com> wrote:
Raffi,

You said, "sends along the user object ass part of it".

Does that explain why the user object is in some cases a bit bloated?


And what does it mean when the HTTP response code is 503.


The whole list of 5xx response codes is ROFL read:
http://en.wikipedia.org/wiki/List_of_HTTP_status_codes#5xx_Server_Error


Kevin Marshall

unread,
Feb 10, 2010, 1:16:46 PM2/10/10
to twitter-deve...@googlegroups.com
It means you're in Portland Oregon...oh wait, that's area code 503...sorry.

Brian Smith

unread,
Feb 11, 2010, 1:05:03 PM2/11/10
to twitter-deve...@googlegroups.com


Raffi Krikorian wrote:

The term most frequently used for “delegator” is “relying party.” What you call the service provider is most frequently called the “identity provider.” What you call the consumer is usually called the “subject.” See OpenID, InfoCard, and other similar specifications for example usage of these terms.

First, what I wrote about "subject" was misleading: the user--not the consumer--is the subject.

i hear all this - it just gets a bit complicated with because we are conflating this with our oauth situation.
This doesn't really have much to do with OAuth, because you are not trying to allow delegation of credentials--that is, you are not trying to allow the "consumer" app to let the relying party use the consumer app's OAuth access token to read/write the user's account.

perhaps its time to move to an oauth + openID hybrid system.
I don't know if OpenID really solves this problem well, especially for apps that aren't webapps.

The subject doesn’t want the relying party to have access to the entire response from the account/verify_credentials request as if he had given the relying party read access to his account. I am not sure if account/verify_credentials returns sensitive information (information only available to apps that have been authorized by the user) yet, but I think it is likely in the future that it will do so. It would be prudent to have delegation use a different resource designed specifically for delegation.

i think this is again a general case vs a twitter case.  i think in the general case, the delegator would call some endpoint that would simply verify the identity through a HTTP code (2xx for success, 4xx for failure).  twitter, as a special case, sends along the user object [as] part of it?
account/verify_credentials discloses information that is private. For example, the HTTP header of account_verify_credentials discloses information about how frequently the user accesses twitter (the rate limit headers). If the user hasn't previously authorized (via OAuth) the delegator (relying party) to have read access to his account, then the delegator (relying party) shouldn't be able to get this information. Also, I think you should plan ahead for the case where account/verify_credentials returns even more sensitive information. If you were going to reuse an existing resource, I'd reuse users/show.format?user_id=<username> instead. But, AFAICT, it's much better to create a new resource for this purpose, and pretty easy to do so.

I think the following would be a better protocol:

Consumer to Relying Party: Give me <RP-SIGNED-TOKEN>, a nonce signed with your OAuth credentials for the relying party'sidentity verification service. Relying Party to Consumer: Here is the token <RP-SIGNED-TOKEN>. (This is done using whatever protocol the consumer and the relying party agree to use.)

Consumer to Identity Provider: Here's <RP-SIGNED-TOKEN>. Give me <IP-SIGNED-TOKEN>, which is (<RP-SIGNED-TOKEN>, screen_name) signed with a signature that the relying party can verify is from the identity provider. Identity Provider to Consumer: I verified that the token was signed by the relying party identified by <RP_ID>. Here is <IP-RP-SIGNED-TOKEN>. (This is an OAuth-protected transaction using the consumer's credentials).

Consumer to Relying Party: Here is <IP-RP-SIGNED-TOKEN>.Relying Party to Consumer: OK, let's continue on with whatever we need to do. (This is done using whatever protocol the consumer and the relying party want to use.)

Notice in particular: (a) each server only has to process one request, (b) the relying part and the identity provider never have to communicate directly with each other, (c) the consumer (user) can control the level of security used in all the communication (e.g. TLS for everything), (d) IP-RP-SIGNED-TOKEN> can be used as the assertion in the OAuth 2.0/WRAP assertion profile, if the relying party is using OAuth WRAP to authenticate the user, (e) the user and the identity provider can both restrict which consumers can sign into which relying parties for which users using this mechanism.

Regards,
Brian

Sean Callahan

unread,
Feb 11, 2010, 3:37:14 PM2/11/10
to Twitter Development Talk
That is similar to what we are doing at TweetPhoto and it is working
out fine.

Feel free to check out what we are doing:

http://groups.google.com/group/tweetphoto/web/oauth-signin

Third-party apps share with us their app's consumer key and secret.

We receive the same level of access to the third-party app using our
photo sharing service.

When two companies work together and are partners there needs to be a
level of trust.

Furthermore, developers can change their consumer secret at any time
so their is no real issue with this method.

There are a few integrations coming out soon with this method in
place.

Please let us know your thoughts and if you have any questions.

Sean

Raffi Krikorian

unread,
Feb 11, 2010, 6:41:24 PM2/11/10
to twitter-deve...@googlegroups.com
account/verify_credentials discloses information that is private. For example, the HTTP header of account_verify_credentials discloses information about how frequently the user accesses twitter (the rate limit headers). If the user hasn't previously authorized (via OAuth) the delegator (relying party) to have read access to his account, then the delegator (relying party) shouldn't be able to get this information. Also, I think you should plan ahead for the case where account/verify_credentials returns even more sensitive information. If you were going to reuse an existing resource, I'd reuse users/show.format?user_id=<username> instead. But, AFAICT, it's much better to create a new resource for this purpose, and pretty easy to do so.

oh - most certainly.  at some point, or maybe with the launch of something like oauth echo, we could have a different endpoint that just provided the screen name, or something like that. 

the endpoint that the delegator users on the service provider is up to different implementations.  in the twitter case, we very may well deal with account/verify_credentials -- we only show user objects there, which are discoverable by other public means.
 
I think the following would be a better protocol:

Consumer to Relying Party: Give me <RP-SIGNED-TOKEN>, a nonce signed with your OAuth credentials for the relying party'sidentity verification service. Relying Party to Consumer: Here is the token <RP-SIGNED-TOKEN>. (This is done using whatever protocol the consumer and the relying party agree to use.)

Consumer to Identity Provider: Here's <RP-SIGNED-TOKEN>. Give me <IP-SIGNED-TOKEN>, which is (<RP-SIGNED-TOKEN>, screen_name) signed with a signature that the relying party can verify is from the identity provider. Identity Provider to Consumer: I verified that the token was signed by the relying party identified by <RP_ID>. Here is <IP-RP-SIGNED-TOKEN>. (This is an OAuth-protected transaction using the consumer's credentials).

Consumer to Relying Party: Here is <IP-RP-SIGNED-TOKEN>.Relying Party to Consumer: OK, let's continue on with whatever we need to do. (This is done using whatever protocol the consumer and the relying party want to use.)

Notice in particular: (a) each server only has to process one request, (b) the relying part and the identity provider never have to communicate directly with each other, (c) the consumer (user) can control the level of security used in all the communication (e.g. TLS for everything), (d) IP-RP-SIGNED-TOKEN> can be used as the assertion in the OAuth 2.0/WRAP assertion profile, if the relying party is using OAuth WRAP to authenticate the user, (e) the user and the identity provider can both restrict which consumers can sign into which relying parties for which users using this mechanism.

in general, i really like this mechanism.  from just a usability standpoint, however, it means that the consumer has to make a few calls simply to perform one action -- they have to call Twitter and then the service provider.  on top of that, a real world example would have them:
  1. call the delegator to get a token;
  2. send that token to twitter to get another token;
  3. call the delegator with that received token to perform the action; and then
  4. (outside this protocol) call twitter to post the status update after that action has been performed.
another possible problem i have with it is that it assumes that the identity provider can sign something in a way that the delegator can verify it?  oh - i suppose that may be the case -- we could use the consumer secret of the protected resource/delegator.
 

Brian Smith

unread,
Feb 11, 2010, 10:17:34 PM2/11/10
to twitter-deve...@googlegroups.com
Raffi Krikorian wrote:
in general, i really like this mechanism.  from just a usability standpoint, however, it means that the consumer has to make a few calls simply to perform one action -- they have to call Twitter and then the service provider.  on top of that, a real world example would have them:
  1. call the delegator to get a token;
  2. send that token to twitter to get another token;
  3. call the delegator with that received token to perform the action; and then
  4. (outside this protocol) call twitter to post the status update after that action has been performed.
Step #3 would usually be "trade the Twitter-signed token with another token used for subsequent authentication to the delegator." In particular, if the consumer and delegator were using OAuth, then they'd probably use the OAuth WRAP assertion profile. Maybe that resultant token would have an expiration date; in that case, the consumer can keep using that token without doing steps #1 and #2 up to the expiration date of the delegator-issued ticket. It would be up to the delegator to decide how frequently he needs to verify that the consumer still is authorized to act on that account. Or, maybe other information provided in step #1 or #3 would be sufficient to allow the delegator to permanently link the Twitter account to a "native" account on the delegator's service, so that the consumer would not have to use the delegated authentication ever again.

another possible problem i have with it is that it assumes that the identity provider can sign something in a way that the delegator can verify it?  oh - i suppose that may be the case -- we could use the consumer secret of the protected resource/delegator.
Right, the delegator and the identity provider could have a shared HMAC key like that. Alternatively, you could skip step #1 all the time if you use have the identity provider sign the token with a RSA private key that corresponds to a public key that is shared with the delegators on some other channel. The scheme I outlined lets Twitter verify the delegator's identity for the consumer, as well as verifying the consumer's identity for the delegator. If you used the public key approach, then the consumer would have to verify the delegator's identity using a public key protocol too (probably via X.509 certificates using TLS).

Cheers,
Brian

Ryan Sarver

unread,
Feb 11, 2010, 9:12:11 PM2/11/10
to twitter-deve...@googlegroups.com
Thanks for sending this out. 

I did want to send a note about having developers share consumer keys and secrets with other applications. While we don't have an explicit policy yet to block this we STRONGLY advise not to hand out your tokens to other providers for a number of reasons. Most important of all is that if your tokens get compromised and abuse is associated with those tokens, we have to revoke access for the consumer. Obviously tokens can get compromised in a number of ways, but the more services you share them with the more likely they are to get compromised which could lead to revocation of your application.

Raffi has proposed a way to do delegated identity using OAuth and we are open to finding other models, but we strongly advise not promoting applications to provide you with their tokens as there are always other ways of solving that same problem.

Thanks, Ryan

Harshad RJ

unread,
Feb 11, 2010, 11:17:48 PM2/11/10
to twitter-deve...@googlegroups.com
On Wed, Feb 10, 2010 at 1:39 PM, Brian Smith <br...@briansmith.org> wrote:

The subject does not want just *anybody* to verify his identity; he only wants the *relying party* to be able to verify his identity.


If I understand correctly, a URL signed using OAuth can be accessed successfully only once, because of the oauth-nonce parameter. Or atleast, it is possible to implement such a restriction at the identity provider's end.


Raffi Krikorian

unread,
Feb 11, 2010, 11:20:55 PM2/11/10
to twitter-deve...@googlegroups.com

The subject does not want just *anybody* to verify his identity; he only wants the *relying party* to be able to verify his identity.

If I understand correctly, a URL signed using OAuth can be accessed successfully only once, because of the oauth-nonce parameter. Or atleast, it is possible to implement such a restriction at the identity provider's end.

yup - that's the case.  the nonce prevents the call from being used twice, and you can't delay verification (to an extent) because the timestamp on the signature will fall out of bounds. 
Reply all
Reply to author
Forward
0 new messages