Re: [OAUTH-WG] Handling stored tokens in mobile app after software update with client credential change

George Fletcher <gffletch@aol.com> Thu, 03 April 2014 19:06 UTC

Return-Path: <gffletch@aol.com>
X-Original-To: oauth@ietfa.amsl.com
Delivered-To: oauth@ietfa.amsl.com
Received: from localhost (ietfa.amsl.com [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 9621A1A02A0 for <oauth@ietfa.amsl.com>; Thu, 3 Apr 2014 12:06:48 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: 0
X-Spam-Level:
X-Spam-Status: No, score=0 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, FREEMAIL_FROM=0.001, HTML_EMBEDS=1.799, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_PASS=-0.001, T_DKIM_INVALID=0.01, T_RP_MATCHES_RCVD=-0.01] autolearn=no
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id hz2hsOByYd1J for <oauth@ietfa.amsl.com>; Thu, 3 Apr 2014 12:06:39 -0700 (PDT)
Received: from omr-m10.mx.aol.com (omr-m10.mx.aol.com [64.12.143.86]) by ietfa.amsl.com (Postfix) with ESMTP id BD85F1A027B for <oauth@ietf.org>; Thu, 3 Apr 2014 12:06:38 -0700 (PDT)
Received: from mtaout-mcb01.mx.aol.com (mtaout-mcb01.mx.aol.com [172.26.50.173]) by omr-m10.mx.aol.com (Outbound Mail Relay) with ESMTP id 4E9BA70246EA1; Thu, 3 Apr 2014 15:06:34 -0400 (EDT)
Received: from [10.172.4.228] (unknown [10.172.4.228]) (using TLSv1 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by mtaout-mcb01.mx.aol.com (MUA/Third Party Client Interface) with ESMTPSA id 8565A380000AA; Thu, 3 Apr 2014 15:06:33 -0400 (EDT)
Message-ID: <533DB139.3040906@aol.com>
Date: Thu, 03 Apr 2014 15:06:33 -0400
From: George Fletcher <gffletch@aol.com>
Organization: AOL LLC
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:24.0) Gecko/20100101 Thunderbird/24.4.0
MIME-Version: 1.0
To: Phil Hunt <phil.hunt@oracle.com>
References: <kbqjrqa9347he47eah7ghyxx.1396536196069@email.android.com> <533D754F.6010909@mitre.org> <533D7D1D.3020103@aol.com> <299C4586-EF50-4715-8EC4-49A6D785BE48@oracle.com>
In-Reply-To: <299C4586-EF50-4715-8EC4-49A6D785BE48@oracle.com>
Content-Type: multipart/alternative; boundary="------------080601040103010403000905"
x-aol-global-disposition: G
X-AOL-VSS-INFO: 5600.1067/97359
X-AOL-VSS-CODE: clean
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mx.aol.com; s=20121107; t=1396551994; bh=VWq/MMlKoX2xIUr5pLEd85SUOyFsEOfhYxmKR7IDXmc=; h=From:To:Subject:Message-ID:Date:MIME-Version:Content-Type; b=B/jqG/GQFVjm4lz3W1Ff/6upGn5gAYtf7EipaNjrGgSIRCziI3P4oxd5Lc5drSZxv YEZA+ieInmMswzH4OtrYbPGJ6VywJLf/lQzSvaYVpvK+ki85rhc+3Vi94qnRAqjGXo sFNUCEX3PMgWZnxuKH7fUC8FVl0hHgrbuVtpmsFQ=
x-aol-sid: 3039ac1a32ad533db1390273
X-AOL-IP: 10.172.4.228
Archived-At: http://mailarchive.ietf.org/arch/msg/oauth/o-u-vdsgrNLgBPa8W2ZFSQatQnI
Cc: OAuth WG <oauth@ietf.org>
Subject: Re: [OAUTH-WG] Handling stored tokens in mobile app after software update with client credential change
X-BeenThere: oauth@ietf.org
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: OAUTH WG <oauth.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/oauth>, <mailto:oauth-request@ietf.org?subject=unsubscribe>
List-Archive: <http://www.ietf.org/mail-archive/web/oauth/>
List-Post: <mailto:oauth@ietf.org>
List-Help: <mailto:oauth-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/oauth>, <mailto:oauth-request@ietf.org?subject=subscribe>
X-List-Received-Date: Thu, 03 Apr 2014 19:06:48 -0000

Great points Phil!

On 4/3/14, 12:29 PM, Phil Hunt wrote:
> I think there are two broad cases to consider:
>
> 1. Assuming each client "instance" gets its own client_id (e.g. via 
> Dyn Reg), my concern about changing client_id is you loose track of 
> the client software's relation to the user. In many cases it is more 
> important to track the software and its relation to the user rather 
> than the fact that it updated. In these cases you might want to keep 
> client_id the same and track versioning somewhere else (e.g. inside 
> the client assertion or database).
>
> 2. If however all copies of a particular class of client software 
> received the same client_id (e.g. because client_ids are issued to the 
> developer), then you may wish to force a client_id change with each 
> version. This allows differentiation of versions in use, etc and would 
> seem to represent a good way to do things when dynamic registration is 
> not possible or available.
>
> Depending on the model (of client_id management) you go for, the 
> reasons for voiding tokens and/or refresh tokens are likely different.
>
> Phil
>
> @independentid
> www.independentid.com <http://www.independentid.com>
> phil.hunt@oracle.com <mailto:phil.hunt@oracle.com>
>
> On Apr 3, 2014, at 8:24 AM, George Fletcher <gffletch@aol.com 
> <mailto:gffletch@aol.com>> wrote:
>
>> Comments inline...
>> On 4/3/14, 10:50 AM, Justin Richer wrote:
>>> This is the question I had. The spec says not to share refresh 
>>> tokens across clients, so it all depends on whether or not you 
>>> consider a new version a new client. I've usually seen client_id 
>>> stay the same across versions, since it's considered "the same 
>>> client", but you could easily consider the new client_id an alias of 
>>> the old client_id and consider the two of them flavors of "the same 
>>> client".
>> There are times where you want to track the change of semantics 
>> within a client. But yes, as Torsten says, we could treat the new 
>> client_id as an "alias" of the old client_id and issue a new set of 
>> tokens (refresh and access). I lose the ability to do the "sub" check 
>> (though that could be an additional parameter on the refresh_token 
>> call). Note that it also requires the client to be able to handle 
>> getting both a refresh_token and access_token on the response. That 
>> would be good client behavior anyway.
>>
>> And I agree that at token exchange time, the old refresh_token (and 
>> it's access tokens) would be revoked.
>>>
>>> Another option is to put all existing refresh tokens into a 
>>> one-time-use bucket when the upgrade happens, so that the client 
>>> gets issued a new refresh token the first time (and last time) it 
>>> uses the old token with the new client_id.
>>>
>>>  -- Justin
>>>
>>> On 04/03/2014 10:43 AM, Torsten Lodderstedt wrote:
>>>> Hi George,
>>>>
>>>> if you want to effectively preseve the refresh token, why doesn't the AS just treat the new client id as an alias of the the old client id?
>>>>
>>>> regards,
>>>> Torsten.
>>>>
>>>> -------- Ursprüngliche Nachricht --------
>>>> Von: George Fletcher<gffletch@aol.com>  
>>>> Datum:03.04.2014  15:43  (GMT+01:00)
>>>> An: Torsten Lodderstedt<torsten@lodderstedt.net>,Phil Hunt<phil.hunt@oracle.com>  
>>>> Cc: OAuth WG<oauth@ietf.org>  
>>>> Betreff: Re: [OAUTH-WG] Handling stored tokens in mobile app after software update with client credential change
>>>>
>>>> Hi Torsten,
>>>>
>>>> We actually have the same issue. Deployed clients in the field where we want to update the client_id and doing so invalidates the existing refresh_token stored with the client. From a user experience perspective, this is a pain and from a risk perspective I think it's fine to effectively do a "token exchange" from the old refresh_token to the new one (with the appropriate security considerations in mind).
>>>>
>>>> Andre got me thinking about this and here is what I'm leaning towards implementing in our system.
>>>>
>>>> Use the JWT Client Assertion flow requesting an authorization grant for the existing user. The JWT would contain an "iss" of the new client_id, a "sub" of the userid the client should already know about, an "aud" of the Authorization Server, a short lived "exp" value as this is effectively a one-time token exchange, and an additional claim of the old refresh_token. Maybe an additional claim with the old client_id as well (still thinking about that as the client_id is already associated with the refresh_token).
>>>>
>>>> This allows the AS to do the following checks...
>>>> 1. Make sure the assertion is being presented by the new client (the level of surety is based on the risk associated with the client. If the client is provisioned with additional keys some how that's much stronger than just using a client_secret which, as you point out, doesn't really prove anything).
>>>> 2. Verify that the "sub" value in the JWT is the same as that identified by the refresh_token
>>>> 3. Verify that the client_id defined as the "issuer" is allowed to make this token exchange call and that the client_id in the refresh_token is one of those being replaced
>>>> 4. Verify the audience of the JWT
>>>>
>>>> If all the checks pass, then a new refresh_token can be issued, with exactly the same scopes as the "old" refresh_token (no ability in this flow to change scopes). The semantics of the refresh_token (e.g. authN time, expiry time, etc) need to be copied to the new refresh_token. In other words there should be no way to "extend" the lifetime of the refresh_token via this mechanism. It's purely a token exchange to provide a new refresh_token mapped to the new client_id.
>>>>
>>>> Interested in feedback as to the viability of this.
>>>>
>>>> Phil, I agree this doesn't need to be standardized, and I would like to see the community start collecting some "best practices" to help others that come across the same use case. It will ensure       a more secure internet for all of us.
>>>>
>>>> Thanks,
>>>> George
>>>>
>>>> On 4/3/14, 6:13 AM, Torsten Lodderstedt wrote:
>>>> Hi Andre,
>>>>
>>>> I would expect the AS to treat a client with a different client id as another client. So the new client should not be able to use the "old" refresh tokens.
>>>>
>>>> Some further questions/remarks:
>>>> - if you utilize refresh tokens, access tokens should be transient. Right? So you don't need to bother
>>>> - public client means w/o secret - there is no security benefit of having a secret for the type of client you described (see Spec section 10)
>>>>
>>>> Regards,
>>>> Torsten.
>>>>
>>>> Am 03.04.2014 um 00:51 schrieb Phil Hunt<phil.hunt@oracle.com>om>:
>>>>
>>>> I don't see a strong reason to standardize behaviour here.  But it seems like a change in scope after a client upgrade is a good reason to expire existing tokens and re-authorize as well as simply expire tokens.
>>>>
>>>> Some may choose to be very conservative and always expire tokens on any client update. But I think that unless there is a critical security due to the nature of the client and/or server, there is no reason to assume it is necessary beyond "good practice".
>>>>
>>>> One good reason for expiring tokens is that you are forcing the client to re-confirm it has the new client credential and it is still valid.
>>>>
>>>> If you revoke tokens and refresh tokens, your authorization and authentication system might inspect browser cookies that hold the previous SSO state and/or previous authorization state.  Thus you could avoid re-authenticating the user and simply ask about the new scopes.
>>>>
>>>> Phil
>>>>
>>>> @independentid
>>>> www.independentid.com
>>>> phil.hunt@oracle.com
>>>>
>>>> On Apr 2, 2014, at 1:37 PM, André DeMarre<andredemarre@gmail.com>  wrote:
>>>>
>>>> We have a mobile app which operates as an OAuth 2.0 public client
>>>> (w/client credentials). It uses the resource owner password
>>>> credentials grant type for authorized communication with our resource
>>>> servers.
>>>>
>>>> We are working on a software update and want to change the registered
>>>> client_id and client_secret for the new app version (register a new
>>>> client at the auth server). The problem is that after the app updates
>>>> on users' devices, it will inherit the app data of the previous
>>>> version, including the access and refresh tokens.
>>>>
>>>> Since the token scope issued to the new client might be different, we
>>>> know that we want the new app version to discard the previous
>>>> version's access tokens. But what about the refresh token?
>>>> Technically, the new version of the app will be a different client,
>>>> but the core OAuth spec section 6 says "the refresh token is bound to
>>>> the client to which it was issued." So what should we do?
>>>>
>>>> We can program the app to discard the previous version's refresh
>>>> token, but that would inconvenience our users to re-enter their
>>>> password after the software update.
>>>>
>>>> I'm tempted to allow the new client to use the refresh token issued to
>>>> the previous client, but that violates the spec.
>>>>
>>>> Does the OAuth community have any insight here? Thank you.
>>>>
>>>> Kind Regards,
>>>> Andre DeMarre
>>>>
>>>> _______________________________________________
>>>> OAuth mailing list
>>>> OAuth@ietf.org
>>>> https://www.ietf.org/mailman/listinfo/oauth
>>>> _______________________________________________
>>>> OAuth mailing list
>>>> OAuth@ietf.org
>>>> https://www.ietf.org/mailman/listinfo/oauth
>>>> _______________________________________________
>>>> OAuth mailing list
>>>> OAuth@ietf.org
>>>> https://www.ietf.org/mailman/listinfo/oauth
>>>>
>>>>
>>>>
>>>> Hi George,
>>>>
>>>> if you want to effectively preseve the refresh token, why doesn't 
>>>> the AS just treat the new client id as an alias of the the old 
>>>> client id?
>>>>
>>>> regards,
>>>> Torsten.
>>>>
>>>>
>>>> -------- Ursprüngliche Nachricht --------
>>>> Von: George Fletcher
>>>> Datum:03.04.2014 15:43 (GMT+01:00)
>>>> An: Torsten Lodderstedt ,Phil Hunt
>>>> Cc: OAuth WG
>>>> Betreff: Re: [OAUTH-WG] Handling stored tokens in mobile app after 
>>>> software update with client credential change
>>>>
>>>> Hi Torsten,
>>>>
>>>> We actually have the same issue. Deployed clients in the field 
>>>> where we want to update the client_id and doing so invalidates the 
>>>> existing refresh_token stored with the client. From a user 
>>>> experience perspective, this is a pain and from a risk perspective 
>>>> I think it's fine to effectively do a "token exchange" from the old 
>>>> refresh_token to the new one (with the appropriate security 
>>>> considerations in mind).
>>>>
>>>> Andre got me thinking about this and here is what I'm leaning 
>>>> towards implementing in our system.
>>>>
>>>> Use the JWT Client Assertion flow requesting an authorization grant 
>>>> for the existing user. The JWT would contain an "iss" of the new 
>>>> client_id, a "sub" of the userid the client should already know 
>>>> about, an "aud" of the Authorization Server, a short lived "exp" 
>>>> value as this is effectively a one-time token exchange, and an 
>>>> additional claim of the old refresh_token. Maybe an additional 
>>>> claim with the old client_id as well (still thinking about that as 
>>>> the client_id is already associated with the refresh_token).
>>>>
>>>> This allows the AS to do the following checks...
>>>> 1. Make sure the assertion is being presented by the new client 
>>>> (the level of surety is based on the risk associated with the 
>>>> client. If the client is provisioned with additional keys some how 
>>>> that's much stronger than just using a client_secret which, as you 
>>>> point out, doesn't really prove anything).
>>>> 2. Verify that the "sub" value in the JWT is the same as that 
>>>> identified by the refresh_token
>>>> 3. Verify that the client_id defined as the "issuer" is allowed to 
>>>> make this token exchange call and that the client_id in the 
>>>> refresh_token is one of those being replaced
>>>> 4. Verify the audience of the JWT
>>>>
>>>> If all the checks pass, then a new refresh_token can be issued, 
>>>> with exactly the same scopes as the "old" refresh_token (no ability 
>>>> in this flow to change scopes). The semantics of the refresh_token 
>>>> (e.g. authN time, expiry time, etc) need to be copied to the new 
>>>> refresh_token. In other words there should be no way to "extend" 
>>>> the lifetime of the refresh_token via this mechanism. It's purely a 
>>>> token exchange to provide a new refresh_token mapped to the new 
>>>> client_id.
>>>>
>>>> Interested in feedback as to the viability of this.
>>>>
>>>> Phil, I agree this doesn't need to be standardized, and I would 
>>>> like to see the community start collecting some "best practices" to 
>>>> help others that come across the same use case. It will ensure a 
>>>> more secure internet for all of us.
>>>>
>>>> Thanks,
>>>> George
>>>>
>>>> On 4/3/14, 6:13 AM, Torsten Lodderstedt wrote:
>>>>> Hi Andre,
>>>>>
>>>>> I would expect the AS to treat a client with a different client id as another client. So the new client should not be able to use the "old" refresh tokens.
>>>>>
>>>>> Some further questions/remarks:
>>>>> - if you utilize refresh tokens, access tokens should be transient. Right? So you don't need to bother
>>>>> - public client means w/o secret - there is no security benefit of having a secret for the type of client you described (see Spec section 10)
>>>>>
>>>>> Regards,
>>>>> Torsten.
>>>>>
>>>>>> Am 03.04.2014 um 00:51 schrieb Phil Hunt<phil.hunt@oracle.com>om>:
>>>>>>
>>>>>> I don't see a strong reason to standardize behaviour here.  But it seems like a change in scope after a client upgrade is a good reason to expire existing tokens and re-authorize as well as simply expire tokens.
>>>>>>
>>>>>> Some may choose to be very conservative and always expire tokens on any client update. But I think that unless there is a critical security due to the nature of the client and/or server, there is no reason to assume it is necessary beyond "good practice".
>>>>>>
>>>>>> One good reason for expiring tokens is that you are forcing the client to re-confirm it has the new client credential and it is still valid.
>>>>>>
>>>>>> If you revoke tokens and refresh tokens, your authorization and authentication system might inspect browser cookies that hold the previous SSO state and/or previous authorization state.  Thus you could avoid re-authenticating the user and simply ask about the new scopes.
>>>>>>
>>>>>> Phil
>>>>>>
>>>>>> @independentid
>>>>>> www.independentid.com
>>>>>> phil.hunt@oracle.com
>>>>>>
>>>>>>> On Apr 2, 2014, at 1:37 PM, André DeMarre<andredemarre@gmail.com>  wrote:
>>>>>>>
>>>>>>> We have a mobile app which operates as an OAuth 2.0 public client
>>>>>>> (w/client credentials). It uses the resource owner password
>>>>>>> credentials grant type for authorized communication with our resource
>>>>>>> servers.
>>>>>>>
>>>>>>> We are working on a software update and want to change the registered
>>>>>>> client_id and client_secret for the new app version (register a new
>>>>>>> client at the auth server). The problem is that after the app updates
>>>>>>> on users' devices, it will inherit the app data of the previous
>>>>>>> version, including the access and refresh tokens.
>>>>>>>
>>>>>>> Since the token scope issued to the new client might be different, we
>>>>>>> know that we want the new app version to discard the previous
>>>>>>> version's access tokens. But what about the refresh token?
>>>>>>> Technically, the new version of the app will be a different client,
>>>>>>> but the core OAuth spec section 6 says "the refresh token is bound to
>>>>>>> the client to which it was issued." So what should we do?
>>>>>>>
>>>>>>> We can program the app to discard the previous version's refresh
>>>>>>> token, but that would inconvenience our users to re-enter their
>>>>>>> password after the software update.
>>>>>>>
>>>>>>> I'm tempted to allow the new client to use the refresh token issued to
>>>>>>> the previous client, but that violates the spec.
>>>>>>>
>>>>>>> Does the OAuth community have any insight here? Thank you.
>>>>>>>
>>>>>>> Kind Regards,
>>>>>>> Andre DeMarre
>>>>>>>
>>>>>>> _______________________________________________
>>>>>>> OAuth mailing list
>>>>>>> OAuth@ietf.org
>>>>>>> https://www.ietf.org/mailman/listinfo/oauth
>>>>>> _______________________________________________
>>>>>> OAuth mailing list
>>>>>> OAuth@ietf.org
>>>>>> https://www.ietf.org/mailman/listinfo/oauth
>>>>> _______________________________________________
>>>>> OAuth mailing list
>>>>> OAuth@ietf.org
>>>>> https://www.ietf.org/mailman/listinfo/oauth
>>>>
>>>> -- 
>>>> <http://connect.me/gffletch>
>>>>
>>>>
>>>> _______________________________________________
>>>> OAuth mailing list
>>>> OAuth@ietf.org
>>>> https://www.ietf.org/mailman/listinfo/oauth
>>>
>>
>> -- 
>> <XeC.png> <http://connect.me/gffletch>
>

-- 
George Fletcher <http://connect.me/gffletch>