https://security.stackexchange.com/questions/113296/where-should-i-store-oauth2-access-tokens
https://learn.microsoft.com/en-us/azure/architecture/example-scenario/secrets/secure-refresh-tokens
Based on the above references
OAuth2 Access Token Storage
- If the request to the 3rd party API is through your server, store the access token in the database tied to the user, encrypted with a key that is stored as an environment variable. If the database is compromised, the tokens are safe.
- If the request to the 3rd party API is directly from the mobile app, store the access token on the phone, encrypted with a unique key for each user stored in your server's database. Decentralized storage of sensitive information is more secure than centralized storage (compartmentalization). If the phone is stolen, it requires authentication to your server before the decryption key can be obtained. If your server is compromised, the tokens are not there.
OAuth2 Refresh Token Storage
When developing web services, you may need to get tokens using the OAuth 2.0 On-Behalf-Of (OBO) flow. It's critical to store the refresh tokens securely for offline access scenarios, as these tokens can give a malicious actor access to resources protected by the organization's Azure Active Directory (Azure AD). The recommended approach is not to store access tokens, but get the access tokens as needed. Securely store only the refresh tokens, with as much rigor as if they were access tokens.
One solution to securely store and update OBO refresh tokens involves using Azure Key Vault, Azure Functions, and Azure DevOps. Azure Key Vault holds the secret encryption keys for each Azure AD tenant, and an Azure Functions timer-triggered function gets the latest secret key from Key Vault. Another Azure Functions function retrieves the refresh token from the Microsoft identity platform and saves it with the latest secret key version. A database stores the latest encrypted key and opaque data. An Azure DevOps continuous delivery pipeline manages and syncs the secret rotation and token refresh processes.
The preferred way for an Azure service like Azure Functions to access Key Vault is to use the service's managed identity. You can grant access through the Azure portal, Azure CLI, or through an Azure Resource Manager (ARM) template for IaC scenarios.
You can use any database to store the tokens in encrypted form. With the cryptographic key stored as a secret, you can look up the latest version of the key in Azure Key Vault.
It's not recommended to use Azure Key Vault in the HTTP request pipeline, so cache responses whenever reasonable. In the example, Key Vault's response to the getSecret(secretId, secretVersion) call is cacheable.
You can rotate the secret key at the same time that you refresh the refresh token, so the latest token gets encrypted with the latest version of the encryption secret. This process uses the built-in Azure Functions support for timer triggers.
you can read the references for deeper information