As a small preface for this topic: The ability for accessing the access tokens and refresh tokens issued by external identity providers is somewhat debated. In the broader scheme of things, Auth0 is the “client” for these identity providers and our main business with them is authentication. That is, we are looking for help authenticating the user (and getting basic information about them, which we then normalize and store and so on).
We don’t need the access token for anything else than authentication (no accessing of Google Drive, or GitHub repositories, or Facebook friends or whatever), let alone the refresh token. So it makes little sense to keep those stored after the authentication took place, as it is a security liability to keep security tokens stored when we don’t really need to.
I’m not suggesting that there are any plans of deprecating support for this behavior, and if anything like that should ever happen there would be ample time to migrate. But, from an architectural point of view, it makes far more sense to let Auth0 ask only for the scopes necessary to authenticate the user and then each individual application can request a token directly to the identity provider with the desired scopes specific to the needs of that application (or even for the action that the user is about to perform).
Asking for more powerful access tokens from the application, and only when there’s a need for it, also makes more sense from a UX perspective. If you ask for too many scopes at the authentication phase, that might scare users away.
Now, having said the above:
But what is the best recommended way how and where to store the tokens?
As I understand it’s not possible to update tokens in the Auth0 user profile?
Considering that these IdP access tokens and refresh tokens are meant for specific applications (i.e. they carry specific scopes and they don’t necessarily apply to the whole Auth0 domain where many application could potentially co-exist), the best place to store this would be in the application itself.
If we are talking about native applications, then every platform has some kind of secure storage (like the Keystore, Keychain, DPAPI on Windows).
Server-side apps can store it securely in internal databases, or you can use our
app_metadata storage in the user profile. Keep in mind, however, that
app_metadata is visible to anyone who has API access to the user, so tokens that were issued for one specific app might be accessible from other apps. That’s why I recommend that each app keeps their tokens securely on their side, especially if you have or plan to have multiple apps.
Single-page apps aren’t good at keeping secrets, so refresh tokens aren’t allowed, and access tokens should be relatively short-lived and probably just kept in memory.
Hope that helps a bit.