I have Single Page Application based on Open ID Connect flow (keycloak). I wonder what are the security considerations for refresh token storage - what are the advantages and disadvantages for storing refresh token by the web/mobile application or by the API gateway.
Following the specs:
Since refresh tokens are long-term credentials, they may be subject to theft.
Refresh token is sensitive information and should be stored securely. What is more, to use the refresh token, you have to request token endpoint of Authorization Server (AS). In specs you will find that in this case AS should trust the client which is sending the refresh token request. It can be achieved by authorizing client to the token endpoint (Mutual TLS authentication, Basic Authentication - not recommended). So you need to store more sensistive information in your app.
For me, storing refresh token in browser is not secure as User-Agent (ie. Browser) can be a subject of attack (ie. dangerous addons). For mobile apps it is a little easier as new OS's gives opportunity to use the system internal secure storage, where you could store refresh token. For web apps it would good to consider a backend storage for such a purpose but here you also have to ensure correct trust relation between client app and backend.
Consider reading this: OAuth 2.0 Threat Model and Security Considerations
When using OpenID Connect, it's recommended that refresh tokens are stored in the "session store" of the SPA. This also the default behavior when using the Keycloak JS adapter. Note that since an SPA is "public", it cannot store client credentials. It is therefore important to use the "public" client option in Keycloak.