Proposal - should we remove support for refresh token rotation from FAPI 2.0 (one of the drafts)

Issue #456 resolved
Ralph Bragg created an issue

Joseph and I have independently been approached by different elements of Brazil regarding the support for Refresh Token rotation in an ecosystem. Given that this credential is bound to a Client and that the authentication mechanisms allowed by FAPI are asymmetric and that it continues to cause significant challenges for Clients when a Refresh Token is lost during refresh token utilisation, are there any benefits of continuing to support RT rotation.

FAPI doesn’t ban the use of refresh token rotation nor call out the potential challenges if a Bank enforces RT rotation on clients. Do we want to do anything about this area in FAPI 2.0 or any of the family of FAPI 2 specifications.

The risk that was raised was that ‘should a client have its keys and its refresh tokens stolen and such an attack go undetected' then rotation would prevent ongoing access to customers data. Conversely it would also result in a lock out of the client if the tokens and keys were swiped and then immediately used.

Comments (27)

  1. Joseph Heenan

    It’s not just Brazil, I’m pretty certain we’ve had the conversation about rotating refresh tokens resulting in loss of consents (and hence people trying to invent very complex and still fragile ways to recover from lost access tokens) in FDX, Australia and UK. Everyone seems to overlook the simple solution of not rotating refresh tokens.

  2. Joseph Heenan

    I saw this ticket being shared on twitter, so I should probably add more background just to make sure the point isn’t misunderstood.

    The confusion often comes from this text in the OAuth Security BCP, https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics#section-2.2.2

    2.2.2  Refresh Tokens
    
       Refresh tokens MUST be sender-constrained or use refresh token
       rotation as described in Section 4.13.
    

    People often use this to justify using refresh token rotation with FAPI, however as we only allow confidential clients in FAPI refresh tokens are always sender constrained, and hence rotation is not required. Using refresh rotation with confidential clients at best provides little if any additional security, but experience from the UK, Australia and Brazil all show in practice it causes occasional but substantial reliability issues that result in loss of consents and users having to reauthenticate/reauthorize.

  3. Nicholas Irving

    A Refresh Token enables a 3rd party to request a new Access Token once the current (AT) one expires. So this means the endpoint is enforcing some limitations on the AT lifetime that would cause a re-authentication event to occur. By provding a RT this enables a 3rd Party to get a new AT from the endpoint without having to re-ask the End User to re-authenicate to the end point. The RT would have to contain/reference the original Intent (that is now a Consent) in order for the endpoint to re-issue an AT and validate it is still a valid Consent. So what is it that we are trying to solve by removing RT?

    The first thing would be that the AT would have to live longer, and the RT would no longer be stored, therefore if there is an issue with what ever store is being used you don’t have to have a long lived RT. However this is only a problem with Opaque Tokens, Stateless Tokens don’t need to be stored, only White/Black listed. So the problem has to be the Endpoint Token Storage for Opaque Tokens? If so having longer lived AT is also at the same level of risk of being lost in the event of ETS failure. Therefore the problem is not easily solved.

    If you remove the RT then how do you get a new AT (short lived) without asking the end user to re-authenticate? You would need to define some way to get the Intent in the Authentication flow, which could easily done through a private_key_jwt , and it would be up to the endpoint to validate / authorize signature / intent / consent to issue a new AT with end user interaction.

  4. Joseph Heenan

    Hi Nicholas - the proposal is to remove refresh token rotation. Refresh tokens would remain, they would just be issued at the time the authorization code is exchanged, and never changed when used to renew an access token.

  5. Takahiko Kawasaki

    FYI: Example of authorization server configuration that enables/disables refresh token rotation.

    RFC 6749 leaves it to authorization server implementations whether to rotate refresh tokens or not, but through experiences, the community has learned that refresh token rotation causes problems.

    It will be good for FAPI 2.0 not to recommend refresh token rotation.

  6. Nicholas Irving

    Hi Joseph, Salesforce, for example, does this by default when you create a Connected App.

    I was speaking more from how to decentralise AT acquisition, as the problem is about the AS being out of sync with the client and I should have made it clearer in what I was saying. As a recommendation to not recommend RTR go ahead. I am thinking bigger picture on how to solve AT, in a decentralised / multi entity relationship, so that RT is not a part of it.

  7. Torsten Lodderstedt

    +1 pointing out that refresh token rotation is not required for confidential clients (and basically adds just pain).

    Refresh token rotation is a stop gap measure for clients w/o any other way to detect/prevent replay, such as authentication, sender constrained RTs, …

  8. Stuart Low

    Discussion in FAPI call is to propose some text to explicitly disable refresh token cycling in FAPI 2.0.

  9. Nat Sakimura

    Just to note: FAPI 1.0 by no means requires nor even advises refresh token rotation. The assumption is that since strong client authentication is there, refresh token is NOT rotated.

    OpenID Connect does not assume refresh token rotation. In fact, it has been an assumption that it is NOT rotated as long as client is authenticated.

    RFC6749 has the following text:

    The authorization server MUST verify the binding between the refresh
       token and client identity whenever the client identity can be
       authenticated.  When client authentication is not possible, the
       authorization server SHOULD deploy other means to detect refresh
       token abuse.
    
       For example, the authorization server could employ refresh token
       rotation in which a new refresh token is issued with every access
       token refresh response.  
    

    This is only requiring the verification of the refresh token and the client. It is only a “possibility” expressed by “could” to use rotation to achieve the binding in the case where client authentication is not possible. When client authentication is being done, it is harmful from the security perspective as it decrease the availability by introducing the issues cited in this ticket.

    Perhaps we should issue interpretation notes on this issue for FAPI 1.0 as well and potentially for OpenID Connect 1.0 Core as well.

  10. Stuart Low

    A potential implementation challenge has come about regarding refresh token cycling removal. Fundamentally if there is a desire to migrate between two OPs whereby key material is replaced and the refresh token is long lived, refresh token cycling could be used to allow the new OP to verify an old refresh token then proceed to issue a new refresh token (ie. signed by its own native key set). While this seems entirely like an implementation issue (not a security one) I wondered what the alternative would be? Is it a case of needing to wait for refresh tokens to expire or forcing users through authorisation flow again?

  11. Joseph Heenan

    @stuart That’s definitely an interesting problem, but I don’t think it’s one that justifies doing refresh token rotation regularly (given the above problems with doing so), and doing it as a “one off” is likely still problematic (if rotation isn’t happening regularly, it’s highly likely that some clients will not properly handle rotation).

    I think in a transition from one OP implementation to another, and taking into account that banking regulators take a dim view of forcing users through the authorization flow due to changes / problems within a bank, the onus is on the bank / new OP to figure out a way to relatively permanently accept refresh tokens from the old OP.

    As an update, Brazil OpenBanking did ban refresh token rotation in the end: https://github.com/OpenBanking-Brasil/specs-seguranca/blame/504e498c670001e98dd694c275b4855f2bc86387/open-banking-brasil-financial-api-1_ID3.md#L233

  12. Torsten Lodderstedt

    As already indicated by Nat, RT rotation was always meant as (last resort) measure for replay detection for public clients (It's an example given in a conditional SHOULD clause!). Given FAPI 2.0 does not support public clients at all, I don’t understand why we even discuss RT rotation.

  13. Dave Tonge

    We had some more discussion around this. We discussed maybe adding a clause that discourages refresh token rotation, but doesn’t disallow it. But as Joseph mentions above this could have other consequences.

  14. Joseph Heenan

    There was further discussion on this on today’s FAPI call, basically around the point Stuart made above - that if an implementation uses stateless (e.g. a JWS/JWE) refresh tokens then disallowing refresh token rotation prevents that implementation from rotating keys.

    There was some discussion about whether stateless refresh tokens were a good architecture, which I don’t believe reached a clear conclusion.

    I believe there was a consensus that folks mustn’t do refresh token unless there’s a clear requirement to do so, like rotating an underlying key.

    The possible ways forward seem to be:

    1. Move forward to disallow refresh token (as some ecosystems have done), essentially/effectively ruling out stateless refresh token implementations. or:
    2. Not disallow refresh token rotation, but suggest some solution to solve the problem of refresh tokens getting lost on rotation (like requiring systems that do rotate refresh tokens to accept old refresh tokens for some time even after a new one is issued - whilst noting that this would need to be specific to confidential/FAPI clients, as in the non-FAPI world where public clients are permitted replay of old refresh tokens shouldn’t be allowed for public clients). or:
    3. Say nothing and Ignore the problem with problem with refresh tokens getting lost on rotation in practice in multiple ecosystems.

  15. Torsten Lodderstedt

    Do we have figures about how serious the „refresh tokens get lost in rotation“ problem is? Can we compare these to error cases, where the exchange of a code for an access token fails?

  16. Joseph Heenan

    Do we have figures about how serious the „refresh tokens get lost in rotation“ problem is?

    I’m not sure if we do. At least I don’t have any detailed data to hand, but I am aware of a number of incidents where banks essentially managed to invalidate every refresh token a fintech was holding, and there have been sufficient instances that the topic has come up many times.

    Can we compare these to error cases, where the exchange of a code for an access token fails?

    I can see where you are going here, and it’s a good question.

    The two counter points are:

    1. If the auth code → access token exchange fails, the user is still directly involved and can try again (i.e. a much simpler exercise, and one much more likely to succeed, than trying to contact a user via email to renew a consent)
    2. The refresh token exchange happens orders of magnitude more - e.g. in the UK / in the EU under PSD2, where a consent is currently renewed manually by the user every 90 days, if we assume a provider is pulling the user’s transactions 4 times a day, and that the access token lifetime is under 6 hours, then you have 360 refresh token exchanges for every 1 auth code exchange, and some providers chose to rotate the refresh token on all 360 exchanges. [The UK has decided to remove the 90 days requirement, which makes things worse.]

    So refresh token loss both has a bigger impact on the user experience and is a more common operation (compared to auth code exchange), at least in the use cases where the fintech is regularly pulling updated transaction data/similar.

  17. Nat Sakimura

    We will try to come to the conclusion next week (Jan 20) so everybody who is interested, please chime in now.

  18. Joseph Heenan

    Discussed again on today’s call. A wording like this might work:

    authorization server MUST NOT use refresh token rotation unless, in the case a reply with a new refresh token is not fully processed by the client, retrying the request (with the previous refresh token) will succeed.

    i.e. if something goes wrong when issuing a new refresh token, the client should be able to retry the request, using the old refresh token, and must succeed.

  19. Dave Tonge

    I like where you are going with this Joseph, it would be difficult to add a conformance test.

    We would also need to add an explanation for why the clause is required

  20. Joseph Heenan

    I like where you are going with this Joseph, it would be difficult to add a conformance test. 

    Thanks. For OPs, if they give us a new refresh token, I think we can try using the old refresh token again and the request must succeed.

    For RPs, as I think someone mentioned on the call, the implication is they would be required to support rotation. (and we already have tests for that.)

    We would also need to add an explanation for why the clause is required

    Agreed.

  21. Joseph Heenan

    On today’s call we discussed whether the RP certification tests should require refresh tokens to be supported by clients or not.

    The conclusion was that, given that servers may issue refresh tokens, clients are required to support them.

  22. Log in to comment