--- title: Rotate or revoke client credentials description: Learn how to rotate your client credentials regularly to stay as secure as possible. source_url: html: https://shopify.dev/docs/apps/build/authentication-authorization/client-secrets/rotate-revoke-client-credentials md: https://shopify.dev/docs/apps/build/authentication-authorization/client-secrets/rotate-revoke-client-credentials.md --- ExpandOn this page * [Step 1: Create a new client secret](https://shopify.dev/docs/apps/build/authentication-authorization/client-secrets/rotate-revoke-client-credentials#step-1-create-a-new-client-secret) * [Step 2: Configure webhooks](https://shopify.dev/docs/apps/build/authentication-authorization/client-secrets/rotate-revoke-client-credentials#step-2-configure-webhooks) * [Step 3: Configure OAuth](https://shopify.dev/docs/apps/build/authentication-authorization/client-secrets/rotate-revoke-client-credentials#step-3-configure-oauth) * [Step 4: Generate a new refresh token](https://shopify.dev/docs/apps/build/authentication-authorization/client-secrets/rotate-revoke-client-credentials#step-4-generate-a-new-refresh-token) * [Step 5: Request new access tokens](https://shopify.dev/docs/apps/build/authentication-authorization/client-secrets/rotate-revoke-client-credentials#step-5-request-new-access-tokens) * [Step 6: Revoke the old client secret](https://shopify.dev/docs/apps/build/authentication-authorization/client-secrets/rotate-revoke-client-credentials#step-6-revoke-the-old-client-secret) * [Examples](https://shopify.dev/docs/apps/build/authentication-authorization/client-secrets/rotate-revoke-client-credentials#examples) # Rotate or revoke client credentials Client credentials should be changed regularly. Employees leave, client credentials can be accidentally committed to version control, and wide-reaching security flaws can be discovered. While these situations pose security risks, in most cases you can address them without causing any downtime for your app by rotating your client credentials. Client credentials are also known as **app credentials** or **API keys**. Caution In the case of a serious security breach, you should immediately revoke your compromised client credentials before you generate new ones. This prevents a malicious attacker from accessing or modifying your users' data while you transition to new credentials. In some high-risk situations, application downtime can't be avoided while you address a security breach. *** ## Step 1: Create a new client secret To communicate securely with Shopify's API, you need to generate a new client secret. You can do this from your app's page in the [Dev Dashboard](https://shopify.dev/docs/apps/build/dev-dashboard). 1. Open the [Dev Dashboard](https://shopify.dev/docs/apps/build/dev-dashboard). 2. Click **Apps**. 3. Select your app. 4. Click **Settings**. 5. In the **Credentials > Secret** section, click **Rotate**. 6. On the **Generate new client secret?** screen, click **Generate new secret**. The new client secret displays with a **New** label. *** ## Step 2: Configure webhooks [Webhooks](https://shopify.dev/docs/apps/build/webhooks) are signed with your app's client secret to prevent forgeries. If your app uses webhooks, then configure it to accept both webhooks signed with the new client secret and webhooks signed with the old client secret until after you revoke the old secret. Caution Shopify will sign webhooks with your app's oldest unrevoked client secret. We know it can be convenient to use the same client secret configuration for both OAuth and webhook validation, but this makes it easy to incorrectly validate webhooks using only the new client secret after following the [configure OAuth step](#step-3-configure-oauth). *** ## Step 3: Configure OAuth Access tokens requested from Shopify's API using the new client secret will be secure. Configure your app to use only the new client secret when [acquiring an access token](https://shopify.dev/docs/apps/build/authentication-authorization#authorization). *** ## Step 4: Generate a new refresh token Many of the access tokens that your app stores will be associated with the old client secret. New access tokens must be requested from the Shopify API to work with the new client secret. You'll need a refresh token to generate these new access tokens. You can generate a refresh token from your app's page in the [Dev Dashboard](https://shopify.dev/docs/apps/build/dev-dashboard). Refresh tokens automatically expire after one hour. Caution Don't delete your old client secret until you've requested new access tokens for every token stored by your app. Users might not be able to open your app if you delete a client secret that still has tokens associated with it. *** ## Step 5: Request new access tokens Refresh each access token stored by your application by requesting new tokens that use your new client secret and the refresh token: ```text POST https://{store_name}.myshopify.com/admin/oauth/access_token ``` Include the following required parameters in your requests: * `client_id`: The client ID for your app. * `client_secret`: The new client secret for your app. * `refresh_token`: The refresh token you created from your app's page in the [Dev Dashboard](https://shopify.dev/docs/apps/build/dev-dashboard). * `access_token`: The access token you would like to refresh. Note The refresh token is temporary and can be used for only one hour after it has been generated. *** ## Step 6: Revoke the old client secret Now your app is using the new client secret to communicate with the Shopify API. The old client secret can now be revoked. You can revoke the old client secret from your app's page in the [Dev Dashboard](https://shopify.dev/docs/apps/build/dev-dashboard). Remember that revoking any secret will also remove the access tokens associated with it. If your app uses webhooks, then configure it to accept webhooks that are signed with the new client secret only. *** ## Examples The following examples show a basic implementation of access token rotation in different programming languages. ```ruby require "rest_client" require "json" api_key = "public-api-key" shared_secret = "newly-generated-shared-secret" refresh_token = "token-generated-from-dev-dashboard" access_token = "access-token-to-refresh" post_data = { client_id: api_key, client_secret: shared_secret, refresh_token: refresh_token, access_token: access_token, } response = RestClient.post( 'https://{shop}.myshopify.com/admin/oauth/access_token.json', post_data ) # The response includes the updated access token for future requests. access_token = JSON.parse(response.body)['access_token'] ``` ```js import fetch from "node-fetch" const apiKey = "public-api-key" const sharedSecret = "newly-generated-shared-secret" const refreshToken = "token-generated-from-dev-dashboard" let accessToken = "access-token-to-refresh" const postData = { client_id: apiKey, client_secret: sharedSecret, refresh_token: refreshToken, access_token: accessToken, } const response = await fetch("https://{shop}.myshopify.com/admin/oauth/access_token.json", { method: "post", body: JSON.stringify(postData), headers: {"Content-Type": "application/json"} }) // The response includes the updated access token for future requests. const data = await response.json() accessToken = data["access_token"] ``` ```php $api_key, "client_secret" => $shared_secret, "refresh_token" => $refresh_token, "access_token" => $access_token, ); $data_string = json_encode($post_data); $headers = array( "Content-Type: application/json", "Accept: application/json", "Content-Length:" . strlen($data_string) ); $handler = curl_init('https://{shop}.myshopify.com/admin/oauth/access_token.json'); curl_setopt($handler, CURLOPT_CUSTOMREQUEST, "POST"); curl_setopt($handler, CURLOPT_POSTFIELDS, $data_string); curl_setopt($handler, CURLOPT_RETURNTRANSFER, true); curl_setopt($handler, CURLOPT_HTTPHEADER, $headers); // The response includes the updated access token for future requests. $response = json_decode(curl_exec($handler)); $access_token = $response["access_token"]; ?> ``` *** * [Step 1: Create a new client secret](https://shopify.dev/docs/apps/build/authentication-authorization/client-secrets/rotate-revoke-client-credentials#step-1-create-a-new-client-secret) * [Step 2: Configure webhooks](https://shopify.dev/docs/apps/build/authentication-authorization/client-secrets/rotate-revoke-client-credentials#step-2-configure-webhooks) * [Step 3: Configure OAuth](https://shopify.dev/docs/apps/build/authentication-authorization/client-secrets/rotate-revoke-client-credentials#step-3-configure-oauth) * [Step 4: Generate a new refresh token](https://shopify.dev/docs/apps/build/authentication-authorization/client-secrets/rotate-revoke-client-credentials#step-4-generate-a-new-refresh-token) * [Step 5: Request new access tokens](https://shopify.dev/docs/apps/build/authentication-authorization/client-secrets/rotate-revoke-client-credentials#step-5-request-new-access-tokens) * [Step 6: Revoke the old client secret](https://shopify.dev/docs/apps/build/authentication-authorization/client-secrets/rotate-revoke-client-credentials#step-6-revoke-the-old-client-secret) * [Examples](https://shopify.dev/docs/apps/build/authentication-authorization/client-secrets/rotate-revoke-client-credentials#examples)