Subject: [OAUTH-WG] issuing new refresh tokens

From: Brian Eaton <[email-masked]>
Date: Mon, 12 Jul 2010 22:36:37 -0700

Draft 10 has the following sentence in section 4.1.4:
http://tools.ietf.org/html/draft-ietf-oauth-v2-10#section-4.1.4

"The authorization server MAY issue a new refresh token."

That carries a surprising amount of baggage.  I suggest removing the
sentence, or changing it to MUST NOT, pending a discussion of the use
cases for issuing new refresh tokens.

Does anyone remember why that sentence got added to the spec?

There are two reasons I can see for issuing new refresh tokens:
1) secrets are like underwear, change them frequently
2) someone has a cryptographically implemented refresh token that
needs to be re-signed or re-issued

I'm pretty sure anyone issuing cryptographic refresh tokens is crazy,
these pretty much have to be backed by server-side state or there is
no way to run your system.  So I'm going to ignore that possibility,
and guess that someone was interested in changing secrets...

So if we want to issue new refresh tokens because we like to change
secrets, we should cover:
- whether existing refresh tokens are revoked.  (I'd vote for MUST be revoked)
- the minimum latency between issuing a new refresh token and revoking
the old one.  (I'd vote for minimum latency measured in hours or
longer.  Clients that have cached refresh tokens need to refresh their
cache within this time period, or they're borked.)
- the maxium latency for revoking the old token.  (I'd vote for
maximum latency measured in hours or days, just for security reasons.
But I can't think of what would break if servers ignored this advice.)

Cheers,
Brian

---

From: Eran Hammer-Lahav <[email-masked]>
Date: Tue, 13 Jul 2010 07:04:11 -0700

> "The authorization server MAY issue a new refresh token."

The capability was there since -02.

-04 added the following text in an attempt to clarify how the refresh_token
output can be used (returning a refresh token was briefly discussed as part
of the general idea of always allowing a refresh token in token responses):

   The authorization server
   MAY issue a new refresh token in which case the client MUST NOT use
   the previous refresh token and replace it with the newly issued
   refresh token.

In -10 I dropped the restriction because people expressed a general issue
with having to revoke tokens.

> and guess that someone was interested in changing secrets...

There was no requirement to support changing refresh tokens. If there is no
interest in this, I suggest we forbid it (otherwise all clients will need to
accommodate the chance of a new refresh token, and then will need guidelines
on how to handle it).

> - whether existing refresh tokens are revoked.  (I'd vote for MUST be revoked)

I agree.

> But I can't think of what would break if servers ignored this advice.)

Why is this required? Can it be specified as a general recommendation?

EHL

> Cheers,
> Brian
> _______________________________________________
> OAuth mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/oauth
>

---

From: Andrew Arnott <[email-masked]>
Date: Tue, 13 Jul 2010 13:10:56 -0700

On Mon, Jul 12, 2010 at 10:36 PM, Brian Eaton <[email-masked]> wrote:

> no way to run your system.

Brian, can you tell me what you mean by cryptographically implemented
refresh token, and why using one would be crazy?  You say using them would
require server-side state.  I'd say just the opposite.  If you *are* signing
your refresh tokens (a cryptographic operation) you don't need to store them
on the auth server, but if you aren't using cryptography, then you must
store the tokens on the auth server in order to validate them when they come
back to you.

So in short, I'm thinking the opposite of what you state.  So please
enlighten me.  What am I missing?

---

From: Brian Eaton <[email-masked]>
Date: Tue, 13 Jul 2010 13:37:51 -0700

On Tue, Jul 13, 2010 at 1:10 PM, Andrew Arnott <[email-masked]> wrote:
> require server-side state.  I'd say just the opposite.  If you are signing

You and I are on the same page.  Let me try again.

Anyone implementing OAuth 2 needs to store information about issued
refresh tokens server-side, otherwise basic functionality such as
revocation is not possible.

Cryptographically implemented refresh tokens, without that
corresponding server-side state, are crazy.

---

From: Andrew Arnott <[email-masked]>
Date: Tue, 13 Jul 2010 13:46:45 -0700

> corresponding server-side state, are crazy.

Ah, got it.  Yes, we're on the same page.

I happen to store the authorization tuple (mentioned in another thread)
rather than the refresh token itself.  That way I can issue an arbitrary
number of refresh tokens for the same client/user/scope/issued_date set
without storing any extra data in the database, but I can still support
revocations by deleting the standing authorization from the db.  Obviously,
each time a refresh token is received, its corresponding tuple in the table
is checked to be present to detect revocations.

---

From: Brian Eaton <[email-masked]>
Date: Tue, 13 Jul 2010 13:56:13 -0700

> is checked to be present to detect revocations.

That's a reasonable design trade-off...

One possible issue there is compromise of the token database.  If a
token database leaks for any reason, all of the refresh tokens would
have to be revoked.

If you stored a one-way hash of the tokens instead, compromise of the
token database would be less dangerous.  (Note that this depends how
the database was compromised, of course...)

---

From: Andrew Arnott <[email-masked]>
Date: Tue, 13 Jul 2010 14:05:20 -0700

> the database was compromised, of course...)

I'm not storing tokens at all.  And a compromise of the database wouldn't
expose any tokens or their hashes.  I'm only storing that
user/client/scope/issued_date tuple -- not the token itself.

---

From: Brian Eaton <[email-masked]>
Date: Tue, 13 Jul 2010 14:59:25 -0700

> user/client/scope/issued_date tuple -- not the token itself.

And a signing key.  So the question is what happens if both the
signing key and the token database get compromised.

Now that I think of it, you may have issues if the signing key alone
is compromised.  It depends how much other entropy you've added to the
tokens...

---

From: Kris Selden <[email-masked]>
Date: Tue, 13 Jul 2010 17:55:54 -0700

Torsten Lodderstedt
[OAUTH-WG] Refresh tokens security enhancement
http://www.ietf.org/mail-archive/web/oauth/current/msg02292.html

Eran Hammer-Lahav
Re: [OAUTH-WG] Refresh tokens security enhancement
http://www.ietf.org/mail-archive/web/oauth/current/msg02390.html

---

From: Brian Eaton <[email-masked]>
Date: Tue, 13 Jul 2010 18:07:09 -0700

Kris -

Thanks for pointing back to where this started!

I more or less agree with what Allen said in response to Torsten's
proposal: http://www.ietf.org/mail-archive/web/oauth/current/msg02295.html.
 The devil is in the details.

I'd be interested in tackling client secret rotation at the same time
as handling refresh token rotation... they are similar problems.

BUT, if we do this, we should do it reasonably well.  In particular, I
think we'd need:
- a way for clients to opt-in to this, probably when they first get a
refresh token
- a system that worked for distributed clients
- a system that allowed rotation of the client secret

I don't think any of that would be impractical, long-term.  Windows
and AD have had automatic rotation of kerberos service keys for a
while, for example.

And here's a more far-fetched idea...  installed applications could
self-generate public/private key pairs, which could then be used to
authenticate to the authorization server using something like Yaron's
recent proposal for client assertion authentication.

Cheers,
Brian

---

From: Torsten Lodderstedt <[email-masked]>
Date: Wed, 14 Jul 2010 06:58:26 +0200

We plan to issue new refresh tokens for certain clients only (mobile, desktop), it's part of the client-related policy. So the behavior for a particular client is predictable.

Regards,
Torsten.

---

From: Andrew Arnott <[email-masked]>
Date: Wed, 14 Jul 2010 08:25:04 -0700

On Tue, Jul 13, 2010 at 2:59 PM, Brian Eaton <[email-masked]> wrote:

>  the question is what happens if both the

Um, if the signing key is lost, you're sunk.  Forget about the database,
with the signing key you can forge your own tokens till doomsday (which will
come much more quickly).  The keys are definitely the most confidential part
of the system, naturally.

---

From: Brian Eaton <[email-masked]>
Date: Wed, 14 Jul 2010 09:49:47 -0700

> of the system, naturally.

It doesn't have to be that way.

Refresh tokens can be backed by server-side state and stored as
one-way hashes in a database.  So no signing key involved there.

And access token signing keys can be rotated quickly, so that even if
they leak, you can recover quickly.

Cheers,
Brian

---

From: Brian Eaton <[email-masked]>
Date: Wed, 14 Jul 2010 09:54:37 -0700

On Tue, Jul 13, 2010 at 9:58 PM, Torsten Lodderstedt
<[email-masked]> wrote:
> We plan to issue new refresh tokens for certain clients only (mobile, desktop),
> it's part of the client-related policy. So the behavior for a particular client is predictable.

Nice.

Would you be willing to expand on the current spec language a bit, to
explain the use cases, and offer more normative language about how
clients should handle refresh token exchange?

This is a cool feature, but the current language is kind of vague.

Cheers,
Brian

---

From: Torsten Lodderstedt <[email-masked]>
Date: Wed, 14 Jul 2010 23:32:34 +0200

> This is a cool feature, but the current language is kind of vague.

I'm not sure what you would like me to write. But let's get started:

We expected the clients to discard the old refresh token and to use the 
newly issued refresh token instead. The old refresh tokens is revoked 
instantly. Any attempt to use it afterwards is interpreted as a 
potential misuse because the assumption would be that an adversary has 
copied the token or cloned the device. The client should notify the user 
of the problem and recommend him/her to check its application 
authorizations (refresh tokens) in our user self care portal. There, the 
user will have acces to information on when the token has been used the 
last time and therewith detect any odd behavior. The user could then 
revoke the token and/or alarm its providers helpdesk.

regards,
Torsten.

---

From: Brian Eaton <[email-masked]>
Date: Wed, 14 Jul 2010 22:14:38 -0700

On Wed, Jul 14, 2010 at 2:32 PM, Torsten Lodderstedt
<[email-masked]> wrote:
> instantly. Any attempt to use it afterwards is interpreted as a potential
> misuse because the assumption would be that an adversary has copied the
> token or cloned the device. The client should notify the user of the problem
> and recommend him/her to check its application authorizations (refresh
> tokens) in our user self care portal. There, the user will have acces to
> information on when the token has been used the last time and therewith
> detect any odd behavior. The user could then revoke the token and/or alarm
> its providers helpdesk.

My use cases for this are a little different.

1) I'm interested in the two-legged flows as well as three-legged flows.
    For example, imagine an autonomous client that is registered once,
and then after that maintains its own key material.  Regular rotation
of the key material is good cryptographic hygiene.

2) I'm interested in distributed scenarios.
    For example, imagine a geographically distributed client
application, or a client application that is extremely busy.  In both
these cases, you run into race conditions where refresh tokens are
changed even as they are being used.

3) I'm interested in authentication besides bearer tokens, in
particular public keys used to verify assertions.

4) I'm less interested in installed applications.
    I understand your use case for rotating refresh tokens, but it's
somewhat less important for me.

That said, maybe we could arrive at a set of protocol flows that we
would both implement the same way, and would meet all of those use
cases?  For example, would a protocol where the client secret for
installed applications changed regularly work for you?

Maybe something like this:

- when a client contacts the authorization server, it would provide a
hint that it supports key rotation
- the authorization server may return an error code that says "key
rotation needed"
- the client would then generate a new secret key (this could be
either a machine-generated password, or an HMAC key, or a
public/private key pair.)
- the client would then contact the authorization server again,
signing the message with the old key, and providing the verification
material for the new key.
- the authorization server would then store the new key, and mark the
old key for expiration.
- subsequent requests from the client would be signed with the new key

Note that in the case of installed applications using the
user-approval flows, you would associate the new key material with the
client-id and refresh token together, rather than the client-id alone.
 Otherwise it's impossible to look up the verification material for
requests, since you would quickly run into problems with a single
client-id mapping to zillions of secrets.

Cheers,
Brian

---

From: Torsten Lodderstedt <[email-masked]>
Date: Thu, 22 Jul 2010 23:10:36 +0200

Am 15.07.2010 07:14, schrieb Brian Eaton:
> ...

How is the client registered? Out of band or via API?

> changed even as they are being used.

What is the difference between rotating a key and changing the refresh 
token with respect to such race conditions?

> particular public keys used to verify assertions.

Authentication between which parties? client and authz server, client 
and resource server?

> installed applications changed regularly work for you?

Why not? Let's talk about :-)

The following comments are given with focus on installed application.

> hint that it supports key rotation

where would the initial secret come from? Would it be the same secret 
for all installations? I assume there is no initial secret and key 
material is used to protect the refresh tokens only. It is not used to 
authenticate the client.

> public/private key pair.)

I would prefer if the authz server would issue the fresh secrets (at 
least for shared secrets).

> - the authorization server would then store the new key, and mark the

when will the old key expire? Instantly?

> client-id mapping to zillions of secrets.

what about clients with multiple refresh tokens from the same authz 
server? Would they need different secrets? Or would you suggest to 
associate all refresh tokens with the respective key material?

I would rather suggest the following approach:

We distinguish clients (application type) and client instances 
(installation).
Every installed application is registered with the authz server as a 
separate client instance (identified by an new client_id). As far as I 
remember, there has been a proposal on the list to introduce instance 
identifiers recently.
Key material is managed per client instance. Refresh tokens are assigned 
to a particular client instance.

That way an authz server can identify and lock out particular 
installations (e.g. the media center app on my iPhone). The same holds 
for end-users, a self care UI could vizualize different installations 
and their authorizations. If the authz server also manages the relation 
between clients and client instances, a particular application can be 
black listed, too.

Bottom line: it's an viable alternative to rotate keys instead of 
issuing new refresh tokens. In my opinion, this is the more complex way 
to protected installed applications because it requires a client 
registration and key rotation protocol. On the other hand, (in 
combination with instances) it has some additional advantages.

What is your assessment?

regards,
Torsten.

> Brian

Assumptions

in the case of installed applications, the secret is used to protect 
refresh tokens only
no client authentication