From 2027 Jan 1 all apps will have to use expiring offline access tokens.
While this is a good change for security - It introduces real complexity for apps that heavily rely on the API. We handle over 50 thousand merchants and for most of them we run daily background tasks like image, content and data optimization.
My questions are:
Could increase the expiring token from 1h to 24h to avoid refreshing it constantly for API heavy apps ?
How do we migrate our customers to expiring tokens which we cannot reach over email and have not logged-in to our app for months, but rely on our app to optimize their store ?
What happens if token exchange fails when using a refresh token due to Shopify or our app issues (DB timeout, worker crash, network blip on your side) ? Maybe we can get a retry count or grace period ? Like 3 retries due to failure or 5 minutes to retry.
How do we handle seasonal stores re-open once or twice a year and then freeze until next event ?
With the Jan 1, 2027 requirement for all public apps, is enforcement a hard cutoff or is there a phased rollout / grace period where non-expiring tokens return warnings before they hard-fail?
What is the exact concurrency behavior of the one-time-use refresh token? If two requests submit the same refresh token within a few hundred milliseconds, is it hard-invalidated on first use, or is there a short grace window where the old refresh token still works?
Can a single non-expiring token be exchanged for an expiring one more than once if our first exchange succeeds at Shopify but fails to persist on our side, or is that shop then locked out and requiring merchant re-auth?
Regarding 2.: From my understanding, its possible to exchange legacy access tokens for new refresh tokens without merchant interaction. See Step 4 About offline access tokens
Ah yes, I was reading about It too. While 2nd question is clear, the 7th one is really important when doing the migration. I’m sure a lot of people will mess this up and would be awesome to be able to retry a few times
Also I understand that for expiring offline access tokens, Shopify allows only one active token per app/shop combination, and issuing a new token revokes the previous one immediately.
Would Shopify consider supporting a short grace overlap window, where the current token and immediately previous token are both valid for a limited time, or allowing a maximum of two active tokens temporarily?
Our app runs distributed background workloads and heavy async tasks, not only simple request/response merchant web pages. Immediate revocation during token rotation can create race conditions across workers, queues, and long-running jobs.
A short overlap window, for example 30–180 seconds, would make rotation safer while still keeping token exposure limited. Is there any recommended Shopify-side or app-side pattern for handling this in distributed systems?
When refreshing an access token the old access token remains active until its TTL has been reached. Refreshing doesn’t immediately revoke the old access token.
@elilip thank you for making this thread, you’re raising exactly the same concerns I have.
I’ve been playing around with migrating all of our tokens and it seems like the current refresh token system will cause significant harm to our customers in the event of any issue occurring (on Shopify’s side or ours) when getting a new token.
If a new token is generated and you are unable to store the refresh token for any reason, that store is essentially disabled in your app until they re-authenticate.
I am hoping Shopify can find a secure way to allow a refresh token to be used multiple times before being revoked, to allow apps to be secure without hindering their user experience.
Only one expiring offline token can be active per app/shop combination: Acquiring a new expiring token will revoke all previous expiring tokens for that shop.
Hi @TerenceShopify - glad to hear there are steps to securing merchant’s tokens.
Rotating the offline access token with a refresh token makes sense, it’s passive and it doesn’t impede the merchants workflow.
One quick question, from what I’m reading the refresh token expires after 90 days.
It appears the only way to generate a refresh token is through an session token.
Therefore, a merchant must re-open your app within 90 days for your app to continue to function on their behalf?
UPDATE: I think I answered my own question.
The access token and the refresh token are refreshed with the grant_type=refresh_token.
This way, as long as you’re refreshing tokens before the expiry, then the merchant doesn’t need to login to authorize another minting of a refresh token/access token pair from their session token.