Skip to content

Commit

Permalink
Add guide on how to achieve 0 downtime client credential rotation
Browse files Browse the repository at this point in the history
  • Loading branch information
sergiught committed May 22, 2023
1 parent 3adf724 commit 8d147ad
Show file tree
Hide file tree
Showing 5 changed files with 273 additions and 2 deletions.
134 changes: 134 additions & 0 deletions docs/guides/client_secret_rotation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
---
page_title: Zero downtime client credentials rotation
description: |-
Achieve zero downtime client credentials rotation with the Auth0 Terraform provider.
---

# Achieving zero downtime client credentials rotation

In this guide we'll show how to rotate a client's credentials to eliminate downtime for the impacted system.

## Pre-requisites:

- The system relies on the configuration to maintain either a list of client secrets or at least two separate
configuration entries (CURRENT and NEXT) representing client secrets.
- By default, the system uses the first client secret in the list or the CURRENT configuration entry. If an error is
received during an exchange that requires client authentication and the error is known to be associated with a problem
related to client credentials, the system should be capable of retrying the operation using the next secret in the
list or the NEXT configuration entry.
- If an event occurs that forces the system to attempt to use the next secret in the list or the NEXT configuration
entry and the operation succeeds when using the new secret, the system should discard the old secret and update the
configuration in a way that the next secret (the one that succeeded) is considered to be the default/current one going
forward.

## Process (to rotate the credentials):

### Rotating a client secret

1. Generate a new value for the client secret on behalf of the system associated with the client application record.
This value should have similar entropy to the client secret values generated by the Auth0 service, minimum 48 chars and
valid chars are numbers, letters and `_`, `-`, `+`, `=`, `.` symbols.
2. Add the newly generated secret to the system configuration as the next secret in the list or in the respective entry
if separate configuration entries are used.
3. Add the new client secret generated in the first step in your terraform configuration and run `terraform apply`:

```terraform
resource "auth0_client" "my_client" {
name = "My client that needs the secret rotated"
app_type = "non_interactive"
}
resource "auth0_client_credentials" "test" {
client_id = auth0_client.my_client.id
authentication_method = "client_secret_post" ## Your target authentication method, client_secret_post or client_secret_basic.
client_secret = "<the generated client secret>"
}
```

### Rotating Private Key JWT credentials

1. Generate a new Private Key JWT credential on behalf of the system associated with the client application record.
2. Add the newly generated credential to the system configuration as the next credential in the list or in the
respective entry if separate configuration entries are used.
3. Attach the Private Key JWT credential to the client application record using Terraform and run `terraform apply`:

```terraform
resource "auth0_client" "my_client" {
name = "My client that needs the credentials rotated"
app_type = "non_interactive"
jwt_configuration {
alg = "RS256"
}
}
resource "auth0_client_credentials" "test" {
client_id = auth0_client.my_client.id
authentication_method = "private_key_jwt"
private_key_jwt {
credentials {
name = "Current Credential"
credential_type = "public_key"
algorithm = "RS256"
pem = <<EOF
-----BEGIN CERTIFICATE-----
MIIFWDCCA0ACCQDXqpBo3R...G9w0BAQsFADBuMQswCQYDVQQGEwJl
-----END CERTIFICATE-----
EOF
}
credentials {
name = "Next Credential"
credential_type = "public_key"
algorithm = "RS256"
pem = <<EOF
-----BEGIN CERTIFICATE-----
BBBIIFWDCCA0ACCQDXqpBo3R...G9w0BAQsFADBuMQswCQYDVQQGEwJl
-----END CERTIFICATE-----
EOF
}
}
}
```

4. Remove the old Private Key JWT credential on the client application record using Terraform and run `terraform apply`:

```terraform
resource "auth0_client" "my_client" {
name = "My client that needs the credentials rotated"
app_type = "non_interactive"
jwt_configuration {
alg = "RS256"
}
}
resource "auth0_client_credentials" "test" {
client_id = auth0_client.my_client.id
authentication_method = "private_key_jwt"
private_key_jwt {
credentials {
name = "Current Credential" # Next becomes current.
credential_type = "public_key"
algorithm = "RS256"
pem = <<EOF
-----BEGIN CERTIFICATE-----
BBBIIFWDCCA0ACCQDXqpBo3R...G9w0BAQsFADBuMQswCQYDVQQGEwJl
-----END CERTIFICATE-----
EOF
}
}
}
```

## Summary

Given the system is prepared to automatically fall back to use the next client credential as available in system
configuration, this process will allow rotating a credential without downtime because by the time that the new
credential takes effect in the Auth0 service, the system is already aware of that value and can automatically fall back
and retry any operation that fails due to the old credential that got rotated.
2 changes: 1 addition & 1 deletion docs/resources/client.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ resource "auth0_client" "my_client" {
### Read-Only

- `client_id` (String) The ID of the client.
- `client_secret` (String, Sensitive) Secret for the client. Keep this private. To access this attribute you need to add the `read:client_keys` scope to the Terraform client. Otherwise, the attribute will contain an empty string.
- `client_secret` (String, Sensitive, Deprecated) Secret for the client. Keep this private. To access this attribute you need to add the `read:client_keys` scope to the Terraform client. Otherwise, the attribute will contain an empty string.
- `id` (String) The ID of this resource.
- `signing_keys` (List of Map of String, Sensitive) List containing a map of the public cert of the signing key and the public cert of the signing key in PKCS7.

Expand Down
2 changes: 1 addition & 1 deletion docs/resources/global_client.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ PAGE
- `client_aliases` (List of String) List of audiences/realms for SAML protocol. Used by the wsfed addon.
- `client_id` (String) The ID of the client.
- `client_metadata` (Map of String) Metadata associated with the client, in the form of an object with string values (max 255 chars). Maximum of 10 metadata properties allowed. Field names (max 255 chars) are alphanumeric and may only include the following special characters: `:,-+=_*?"/\()<>@ [Tab] [Space]`.
- `client_secret` (String, Sensitive) Secret for the client. Keep this private. To access this attribute you need to add the `read:client_keys` scope to the Terraform client. Otherwise, the attribute will contain an empty string.
- `client_secret` (String, Sensitive, Deprecated) Secret for the client. Keep this private. To access this attribute you need to add the `read:client_keys` scope to the Terraform client. Otherwise, the attribute will contain an empty string.
- `client_secret_rotation_trigger` (Map of String) Custom metadata for the rotation. The contents of this map are arbitrary and are hashed by the provider. When the hash changes, a rotation is triggered. For example, the map could contain the user making the change, the date of the change, and a text reason for the change. For more info: [rotate-client-secret](https://auth0.com/docs/get-started/applications/rotate-client-secret).
- `cross_origin_auth` (Boolean) Whether this client can be used to make cross-origin authentication requests (`true`) or it is not allowed to make such requests (`false`). Requires the `coa_toggle_enabled` feature flag to be enabled on the tenant by the support team.
- `cross_origin_loc` (String) URL of the location in your site where the cross-origin verification takes place for the cross-origin auth flow when performing authentication in your own domain instead of Auth0 Universal Login page.
Expand Down
3 changes: 3 additions & 0 deletions internal/auth0/client/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ func NewResource() *schema.Resource {
Description: "Secret for the client. Keep this private. To access this attribute you need to add the " +
"`read:client_keys` scope to the Terraform client. Otherwise, the attribute will contain an " +
"empty string.",
Deprecated: "Reading the client secret through this attribute is deprecated and it will be " +
"removed in a future version. Migrate to the `auth0_client_credentials` resource to " +
"manage a client's secret instead.",
},
"client_secret_rotation_trigger": {
Type: schema.TypeMap,
Expand Down
134 changes: 134 additions & 0 deletions templates/guides/client_secret_rotation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
---
page_title: Zero downtime client credentials rotation
description: |-
Achieve zero downtime client credentials rotation with the Auth0 Terraform provider.
---

# Achieving zero downtime client credentials rotation

In this guide we'll show how to rotate a client's credentials to eliminate downtime for the impacted system.

## Pre-requisites:

- The system relies on the configuration to maintain either a list of client secrets or at least two separate
configuration entries (CURRENT and NEXT) representing client secrets.
- By default, the system uses the first client secret in the list or the CURRENT configuration entry. If an error is
received during an exchange that requires client authentication and the error is known to be associated with a problem
related to client credentials, the system should be capable of retrying the operation using the next secret in the
list or the NEXT configuration entry.
- If an event occurs that forces the system to attempt to use the next secret in the list or the NEXT configuration
entry and the operation succeeds when using the new secret, the system should discard the old secret and update the
configuration in a way that the next secret (the one that succeeded) is considered to be the default/current one going
forward.

## Process (to rotate the credentials):

### Rotating a client secret

1. Generate a new value for the client secret on behalf of the system associated with the client application record.
This value should have similar entropy to the client secret values generated by the Auth0 service, minimum 48 chars and
valid chars are numbers, letters and `_`, `-`, `+`, `=`, `.` symbols.
2. Add the newly generated secret to the system configuration as the next secret in the list or in the respective entry
if separate configuration entries are used.
3. Add the new client secret generated in the first step in your terraform configuration and run `terraform apply`:

```terraform
resource "auth0_client" "my_client" {
name = "My client that needs the secret rotated"
app_type = "non_interactive"
}
resource "auth0_client_credentials" "test" {
client_id = auth0_client.my_client.id
authentication_method = "client_secret_post" ## Your target authentication method, client_secret_post or client_secret_basic.
client_secret = "<the generated client secret>"
}
```

### Rotating Private Key JWT credentials

1. Generate a new Private Key JWT credential on behalf of the system associated with the client application record.
2. Add the newly generated credential to the system configuration as the next credential in the list or in the
respective entry if separate configuration entries are used.
3. Attach the Private Key JWT credential to the client application record using Terraform and run `terraform apply`:

```terraform
resource "auth0_client" "my_client" {
name = "My client that needs the credentials rotated"
app_type = "non_interactive"
jwt_configuration {
alg = "RS256"
}
}
resource "auth0_client_credentials" "test" {
client_id = auth0_client.my_client.id
authentication_method = "private_key_jwt"
private_key_jwt {
credentials {
name = "Current Credential"
credential_type = "public_key"
algorithm = "RS256"
pem = <<EOF
-----BEGIN CERTIFICATE-----
MIIFWDCCA0ACCQDXqpBo3R...G9w0BAQsFADBuMQswCQYDVQQGEwJl
-----END CERTIFICATE-----
EOF
}
credentials {
name = "Next Credential"
credential_type = "public_key"
algorithm = "RS256"
pem = <<EOF
-----BEGIN CERTIFICATE-----
BBBIIFWDCCA0ACCQDXqpBo3R...G9w0BAQsFADBuMQswCQYDVQQGEwJl
-----END CERTIFICATE-----
EOF
}
}
}
```

4. Remove the old Private Key JWT credential on the client application record using Terraform and run `terraform apply`:

```terraform
resource "auth0_client" "my_client" {
name = "My client that needs the credentials rotated"
app_type = "non_interactive"
jwt_configuration {
alg = "RS256"
}
}
resource "auth0_client_credentials" "test" {
client_id = auth0_client.my_client.id
authentication_method = "private_key_jwt"
private_key_jwt {
credentials {
name = "Current Credential" # Next becomes current.
credential_type = "public_key"
algorithm = "RS256"
pem = <<EOF
-----BEGIN CERTIFICATE-----
BBBIIFWDCCA0ACCQDXqpBo3R...G9w0BAQsFADBuMQswCQYDVQQGEwJl
-----END CERTIFICATE-----
EOF
}
}
}
```

## Summary

Given the system is prepared to automatically fall back to use the next client credential as available in system
configuration, this process will allow rotating a credential without downtime because by the time that the new
credential takes effect in the Auth0 service, the system is already aware of that value and can automatically fall back
and retry any operation that fails due to the old credential that got rotated.

0 comments on commit 8d147ad

Please sign in to comment.