Skip to main content

OAuth Client Secret rotation

Overview

The Braintree GraphQL API provides mutations for creating, disabling, and deleting client secrets. This guide walks you through the steps to safely rotate a client secret using these mutations. The system will ensure that each OAuth application never has less than one enabled client secret and never has more than two secrets in total.

Audience

This guide assumes you understand making HTTP requests with headers and know how to run GraphQL mutations and queries over HTTP.

Prerequisites

IP restrictions enabled

To use the OAuth Client Secret Rotation APIs, you must have IP or hostname restrictions enabled, and you must define an allowed host IP. All client secret rotation requests must originate from that host.

An OAuth application

This guide assumes that you have an OAuth application created via the process explained in the Braintree Auth documentation. In the Braintree console, make note of your application's client ID and client secret because they will be needed for creating access tokens to access the API and the secret itself is needed for doing secret rotation.

An access token

To execute most Braintree API requests, an API key pair is required for authentication. However, the API key pair alone is insufficient for validity of client secret rotation requests. For these sensitive operations, you need an OAuth Access Token with one and only one scope named MANAGE_OAUTH_CLIENT_SECRETS. To get such an Access Token, follow the instructions in the OAuth Access Tokens Integration Guide.

Note

Access Tokens have only a three-minute time-to-live (TTL) and are intended to be used by an automated process that completes in seconds.

Overview: Rotating a client secret

Rotating a secret is a multi-step operation, designed to avoid the possibility that you will delete your enabled key and lock yourself out of the system. Here is an overview of the process:

  • Create a new client secret that will replace the old client secret that you wish to rotate. This new secret will be enabled, and you will have two enabled secrets.
  • Disable the old client secret. Once you have updated your systems to use the new secret, you should disable the old secret in preparation for deleting it.
  • Delete the old client secret. Now that the old secret is disabled, you can safely delete it.

The details of each operation are covered below.

Creating a new secret

To create a new client secret, you first create an access token with MANAGE_OAUTH_CLIENT_SECRETS scope and then use that token to call the createOAuthClientSecret mutation.

The Braintree API does not require any input for the client secret creation mutation. The OAuth application and merchant are determined by the access token provided in headers of a request. The mutation below creates a new client secret and returns the secret value.

mutation

mutation ($input: CreateOAuthClientSecretInput!) {.
createOAuthClientSecret(input: $input) {
secret
}
}

There must be an input, but no fields.

variables

{
"input": {}
}

Calls to the Braintree Making API calls documentation must include HTTP headers Braintree-Version and Authorization.

Braintree-Version: 2023-12-20
Authorization: Bearer <YOUR_ACCESS_TOKEN>

Expected response containing the brand-new OAuth client secret:

response

{
"data": {
"createOAuthClientSecret": {
"secret":"NEW_CLIENT_SECRET_VALUE"
}
}
}

Take note of the secret and save it somewhere safe. You will not be able to see it again via API calls or the control panel.

Disabling the old secret

Once you have switched your systems over to the new secret, you are ready to disable the old secret. You do that by calling the disableOAuthClientSecret mutation and passing in the old secret value to be disabled. For this operation, you can use the original access token you created from the old secret (if not timed out), or a new one made from the new secret you just created.

Again, headers are required.

Braintree-Version: 2023-12-20
Authorization: Bearer <YOUR_ACCESS_TOKEN>

The disable mutation accepts a secret value input returning the masked secret and a boolean disabled value.

mutation

mutation ($input: DisableOAuthClientSecretInput!) {
disableOAuthClientSecret(input: $input) {
oauthClientSecret {
maskedSecret
disabled
}
}
}

And the input to go along with that example:

variables

{
"input": {
"secret": "OLD_CLIENT_SECRET_VALUE"
}
}

The response from disable-secret will include the masked secret value, and a boolean disabled value which willl be true.

response

{
"oauthClientSecret": {
"maskedSecret": "*****************************ALUE",
"disabled": true
}
}

Deleting the old secret

Once you have disabled the old secret, it can be deleted. To do that, create a new access token from the new secret and call the deleteOAuthClientSecret mutation passing in the old secret value.

Note

For this mutation, a new access token must be used, one created from the new client secret because the old secret is now disabled.

Before you call delete, create that new token.

Send the new access token in the headers.

Braintree-Version: 2023-12-20
Authorization: Bearer <NEW ACCESS TOKEN>

The delete-mutation accepts the old secret value and returns nothing.

mutation

mutation ($input: DeleteOAuthClientSecretInput!) {
deleteOAuthClientSecret(input: $input) {
}
}

variables

{
"input": {
"secret": "OLD_CLIENT_SECRET_VALUE"
}
}

The delete-secret response will be empty, unless you specify a clientMutationId.

Rotation complete!

Now that the old secret is deleted, you have successfully rotated your OAuth client secret.