Share via

Refresh tokens expire after 12 hours using Microsoft Entra External ID native authentication with OTP

Niek Bijman 90 Reputation points
2024-09-26T20:59:10.17+00:00

Issue

We chose Microsoft Entra External ID for authenticating external consumers using CIAM after reading this article

We're using these Android & iOS clients to signup and signin users with OTP authentication

In the backend we carefully followed the instructions to set up everything needed for the Native Authentication + OTP (one time passcode) user flow documented here.

We've run into an issue with the refresh tokens that we receive when using Native Authentication

Our expectation is that our refresh tokens should be valid for 90 days because we're using native apps which should fall under the 'other scenarios' in the following statement by microsoft documented for Entra ID:

The default lifetime for the refresh tokens is 24 hours for single page apps and 90 days for all other scenarios.

However our refresh tokens expire after 12 hours, which leads to a bad UX in our app due to forced repeated logins

AADSTS700082: The refresh token has expired due to inactivity. The token was issued on 2024-09-25T13:42:23.0482303Z and was inactive for 12:00:00.

Microsoft Security | Microsoft Entra | Microsoft Entra External ID
Azure | Azure Startups
Azure | Azure Startups

Startups: Companies that are in their initial stages of business and typically developing a business model and seeking financing.


5 answers

Sort by: Most helpful
  1. Sasha Mars 16 Reputation points Microsoft Employee
    2026-05-19T14:02:31.0166667+00:00

    Thanks for choosing Entra External ID to authenticate external consumers in your CIAM scenario - great to see you leveraging Native Auth with OTP on mobile.

    What you’re observing with refresh tokens expiring after ~12 hours when using Native Authentication with OTP on iOS and Android aligns with behavior others have reported in similar scenarios.

    If your goal is to improve user experience and reduce frequent reauthentication, the recommended approach is to use Sign-in Frequency via Conditional Access session controls rather than relying on refresh token lifetime.

    • Sign-in Frequency lets you define how often a user must reauthenticate
    • It applies to native mobile apps (iOS and Android)
    • It provides a more predictable and controlled session experience

    You can learn more here:

    Recommendation (tokens vs. session controls)

    A simple way to think about this:

    • Refresh tokens control how the app silently gets new access tokens in the background
    • Sign-in Frequency controls when the user is required to sign in again

    In Entra External ID (especially with OTP scenarios), refresh token lifetime is not the primary lever for controlling user sessions.

    👉 Recommendation: Use Sign-in Frequency as the source of truth for session duration, and treat refresh tokens as an implementation detail managed by the platform.

    This approach gives you:

    • More predictable UX on mobile
    • Alignment with supported controls in External ID
    • Flexibility to adjust session duration without depending on token lifetime behavior

    In short: use refresh tokens for silent renewal, and use Sign-in Frequency to define the user experience.

    Was this answer helpful?

    3 people found this answer helpful.

  2. Krunal Berawala 11 Reputation points
    2025-05-14T23:26:17.99+00:00

    This issue still persist when Android & iOS clients to signup and signin users with OTP authentication.

    None of the above solutions are applicable to Entra EXTERNAL ID.

    Was this answer helpful?

    2 people found this answer helpful.
    0 comments No comments

  3. Jesper B 0 Reputation points
    2025-09-09T07:11:51.2566667+00:00

    It's really bad for my app that my email OTP users have to log in every day. My users are both young and old people. I've switched to username/password instead. But the whole idea of ​​them not having to create a password is now gone and it should be as easy as possible to sign up.

    In my frustration, I considered creating an Azure B2C tenant, but you can't do that anymore, Microsoft has closed it down for new creations. They want you to use Microsoft Intra External ID instead.

    I've tried setting up a policy for my app without success.

    I really hope Microsoft fixes this bug soon. It's been almost a year now and it hasn't been fixed yet!

    $policy = New-AzureADPolicy -Definition @('{"AccessTokenLifetime":"23:59:59","RefreshTokenLifetime":"90:00:00:00","RollingRefreshTokenLifetime":"90:00:00:00"}') -DisplayName "WebPolicyScenario" -IsOrganizationDefault $false -Type "TokenLifetimePolicy"
     
    Get-AzureADPolicy -Id $policy.Id
     
    $sp = Get-AzureADServicePrincipal -Filter "DisplayName eq 'XXX'"
    Add-AzureADServicePrincipalPolicy -Id $sp.ObjectId -RefObjectId $policy.Id
    

    User's image

    User's image

    Was this answer helpful?

    0 comments No comments

  4. Martin May 10 Reputation points
    2024-10-06T07:43:28.29+00:00

    I have the same problem - did any of the suggestions mentioned above help?

    Was this answer helpful?


  5. Anonymous
    2024-10-02T21:28:36.9433333+00:00

    Hi @Niek Bijman , the default lifetime for refresh tokens in Azure AD B2C is 24 hours for single page apps and 90 days for all other scenarios, but there are other settings that can affect the lifetime of refresh tokens, such as refresh_token_lifetime and rolling_refresh_token_lifetime.

    Make sure that the refresh_token_lifetime policy setting is set to the default value of 90 days. (Policies > Properties > Token Lifetime Policy) and set the value to 7776000 (90 days in seconds).

    Check that the rolling_refresh_token_lifetime policy setting is not set to a value that is less than 12 hours. This setting determines the maximum amount of time that a user can use a refresh token without having to reauthenticate. If this value is set to a value that is less than 12 hours, it could cause the refresh token to expire prematurely.

    Also verify that your app is using the correct scopes when requesting access tokens and refresh tokens. Make sure that you are requesting the offline_access scope when you authenticate the user. This is required to obtain a refresh token that can be used to obtain new access tokens without requiring the user to reauthenticate.

    Please let me know if you have any questions and I can help you further.

    If this answer helps you please mark "Accept Answer" so other users can reference it.

    Thank you,

    James

    Was this answer helpful?


Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.