> ## Documentation Index
> Fetch the complete documentation index at: https://auth0-cq3uo.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Rotate Signing Keys

You can manually rotate a signing key periodically to change the JSON web key (JWK) key used by applications and APIs to validate tokens. If your application or API **does not** allow for this key change, and it attempts to use an expired signing key to verify a token, the authentication request will fail.

<Warning>
  Auth0 recommends that you execute signing key rotation on a development tenant first, then verify that your applications and APIs still work as expected. After you verify that everything is working properly, perform the same signing key rotation on your production tenant.
</Warning>

Although Auth0 signs with only one signing key at a time, your tenant's <Tooltip tip="OpenID: Open standard for authentication that allows applications to verify users' identities without collecting and storing login information." cta="View Glossary" href="/docs/glossary?term=OpenID">OpenID</Tooltip> Connect (OIDC) discovery document always contains multiple keys. The OIDC discovery document will always include both the current key and the next key, and it may also include the previous key if the previous key has not yet been revoked. To provide a seamless experience in case of an emergency, your application should be able to use any of the keys specified in the document. To learn more about OpenID Connect discovery documents, read [Locate JSON Web Key Sets](/docs/secure/tokens/json-web-tokens/locate-json-web-key-sets).

<Warning>
  To allow you time to update your application with the new signing key, all tokens signed with the previous key will still be valid until you revoke the previous key. To learn more, read [Revoke Signing Keys](/docs/get-started/tenant-settings/signing-keys/revoke-signing-keys).
</Warning>

You can rotate your tenant's application signing key using the <Tooltip tip="Auth0 Dashboard: Auth0's main product to configure your services." cta="View Glossary" href="/docs/glossary?term=Auth0+Dashboard">Auth0 Dashboard</Tooltip> or the Auth0 <Tooltip tip="Management API: A product to allow customers to perform administrative tasks." cta="View Glossary" href="/docs/glossary?term=Management+API">Management API</Tooltip>.

## Use the Dashboard

1. Go to [Dashboard > Settings > Signing Keys](https://manage.auth0.com/#/tenant/signing_keys).

   <Frame>![Dashboard Tenant Settings Signing Keys tab](https://images.ctfassets.net/cdy7uua7fh8z/7r8t3EGctFmvkCgPrU0i2R/f79ac74dac5cded37b39bd8a8b80951d/dashboard-tenant-settings-signing-keys.png)</Frame>
2. Under **Rotation Settings**, locate **Rotate Signing Key**, and select **Rotate Key**.
3. Click **Rotate** to confirm.

   <Frame>![Dashboard Settings Signing Keys Tab Rotate Confirm](https://images.ctfassets.net/cdy7uua7fh8z/6Ofp24mgt8ZrvaxF2wLA5N/5cca1a3267ffdc07f61d7990b4e85989/Rotating_Key_Warning_-_English.png)</Frame>

## Use the Management API

1. To get a list of the signing keys, make a `GET` call to the [Get all Application Signing Keys](https://auth0.com/docs/api/management/v2#!/Keys/get_signing_keys) endpoint.
2. To rotate the signing key, make a `POST` call to the [Rotate the Application Signing Key](https://auth0.com/docs/api/management/v2#!/Keys/post_signing_keys) endpoint. Be sure to replace the `MGMT_API_ACCESS_TOKEN` placeholder value with your Management API access token.

   <CodeGroup>
     ```bash cURL lines theme={null}
     curl --request POST \
        --url 'https://{yourDomain}/api/v2/keys/signing/rotate' \
        --header 'authorization: Bearer {yourMgmtApiAccessToken}'
     ```

     ```csharp C# lines theme={null}
     var client = new RestClient("https://{yourDomain}/api/v2/keys/signing/rotate");
     var request = new RestRequest(Method.POST);
     request.AddHeader("authorization", "Bearer {yourMgmtApiAccessToken}");
     IRestResponse response = client.Execute(request);
     ```

     ```go Go lines theme={null}
     package main

     import (
        "fmt"
        "net/http"
        "io/ioutil"
     )

     func main() {

        url := "https://{yourDomain}/api/v2/keys/signing/rotate"

        req, _ := http.NewRequest("POST", url, nil)

        req.Header.Add("authorization", "Bearer {yourMgmtApiAccessToken}")

        res, _ := http.DefaultClient.Do(req)

        defer res.Body.Close()
        body, _ := ioutil.ReadAll(res.Body)

        fmt.Println(res)
        fmt.Println(string(body))

     }
     ```

     ```java Java lines theme={null}
     HttpResponse response = Unirest.post("https://{yourDomain}/api/v2/keys/signing/rotate")
        .header("authorization", "Bearer {yourMgmtApiAccessToken}")
        .asString();
     ```

     ```javascript Node.JS lines theme={null}
     var axios = require("axios").default;

     var options = {
     method: 'POST',
     url: 'https://{yourDomain}/api/v2/keys/signing/rotate',
     headers: {authorization: 'Bearer {yourMgmtApiAccessToken}'}
     };

     axios.request(options).then(function (response) {
     console.log(response.data);
     }).catch(function (error) {
     console.error(error);
     });
     ```

     ```obj-c Obj-C lines theme={null}
     #import <Foundation/Foundation.h>

     NSDictionary *headers = @{ @"authorization": @"Bearer {yourMgmtApiAccessToken}" };

     NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://{yourDomain}/api/v2/keys/signing/rotate"]
                                                           cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                        timeoutInterval:10.0];
     [request setHTTPMethod:@"POST"];
     [request setAllHTTPHeaderFields:headers];

     NSURLSession *session = [NSURLSession sharedSession];
     NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
                                               completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                                                     if (error) {
                                                        NSLog(@"%@", error);
                                                     } else {
                                                        NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
                                                        NSLog(@"%@", httpResponse);
                                                     }
                                               }];
     [dataTask resume];
     ```

     ```php PHP lines theme={null}
     $curl = curl_init();

     curl_setopt_array($curl, [
     CURLOPT_URL => "https://{yourDomain}/api/v2/keys/signing/rotate",
     CURLOPT_RETURNTRANSFER => true,
     CURLOPT_ENCODING => "",
     CURLOPT_MAXREDIRS => 10,
     CURLOPT_TIMEOUT => 30,
     CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
     CURLOPT_CUSTOMREQUEST => "POST",
     CURLOPT_HTTPHEADER => [
        "authorization: Bearer {yourMgmtApiAccessToken}"
     ],
     ]);

     $response = curl_exec($curl);
     $err = curl_error($curl);

     curl_close($curl);

     if ($err) {
     echo "cURL Error #:" . $err;
     } else {
     echo $response;
     }
     ```

     ```python Python lines theme={null}
     import http.client

     conn = http.client.HTTPSConnection("")

     headers = { 'authorization': "Bearer {yourMgmtApiAccessToken}" }

     conn.request("POST", "/{yourDomain}/api/v2/keys/signing/rotate", headers=headers)

     res = conn.getresponse()
     data = res.read()

     print(data.decode("utf-8"))
     ```

     ```ruby Ruby lines theme={null}
     require 'uri'
     require 'net/http'
     require 'openssl'

     url = URI("https://{yourDomain}/api/v2/keys/signing/rotate")

     http = Net::HTTP.new(url.host, url.port)
     http.use_ssl = true
     http.verify_mode = OpenSSL::SSL::VERIFY_NONE

     request = Net::HTTP::Post.new(url)
     request["authorization"] = 'Bearer {yourMgmtApiAccessToken}'

     response = http.request(request)
     puts response.read_body
     ```

     ```swift Swift lines theme={null}
     import Foundation

     let headers = ["authorization": "Bearer {yourMgmtApiAccessToken}"]

     let request = NSMutableURLRequest(url: NSURL(string: "https://{yourDomain}/api/v2/keys/signing/rotate")! as URL,
                                            cachePolicy: .useProtocolCachePolicy,
                                         timeoutInterval: 10.0)
     request.httpMethod = "POST"
     request.allHTTPHeaderFields = headers

     let session = URLSession.shared
     let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
     if (error != nil) {
        print(error)
     } else {
        let httpResponse = response as? HTTPURLResponse
        print(httpResponse)
     }
     })

     dataTask.resume()
     ```
   </CodeGroup>

<table class="table">
  <thead>
    <tr>
      <th><strong>Value</strong></th>
      <th><strong>Description</strong></th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>MGMT\_API\_ACCESS\_TOKEN</code></td>
      <td><a href="https://auth0.com/docs/api/management/v2/tokens">Access Token for the Management API</a> with the scopes <code>create:signing\_keys</code> and <code>update:signing\_keys</code>.</td>
    </tr>
  </tbody>
</table>

## Key rotation impact

### APIs and API gateways accepting access tokens

Most middleware and API gateways leverage the JSON web key set (JWKS) endpoint to retrieve the current and future signing keys at a certain interval. If your middleware and/or API gateways **do not** support this endpoint and require you to manually configure a `*.cer` file, you will need to coordinate the signing key rotation in Auth0 with the reconfiguration of your middleware and gateways.

### Regular web applications

When rotating the signing key in Auth0, you will need to coordinate the reconfiguration of your applications which leverage <Tooltip tip="Web Service Federation (WS-Fed): Protocol for managing user identities across domains." cta="View Glossary" href="/docs/glossary?term=WS-Fed">WS-Fed</Tooltip> or <Tooltip tip="Web Service Federation (WS-Fed): Protocol for managing user identities across domains." cta="View Glossary" href="/docs/glossary?term=SAML">SAML</Tooltip>. This typically happens when you upload the new public certificate or reconfigure the application by entering the WS-Fed/SAML metadata URL. This will change the JWKS key, which is used by applications to validate tokens, make sure your implementation does not assume JWKS keys don’t change.

## Learn more

* [Revoke Signing Keys](/docs/get-started/tenant-settings/signing-keys/revoke-signing-keys)
* [Locate JSON Web Key Sets](/docs/secure/tokens/json-web-tokens/locate-json-web-key-sets)
* [Change Application Signing Algorithms](/docs/get-started/applications/change-application-signing-algorithms)
* [View Signing Certificates](/docs/get-started/tenant-settings/signing-keys/view-signing-certificates)
