From bf352fa8defe8c42e38362cbb8c23b9065c8198a Mon Sep 17 00:00:00 2001 From: Sergiu Ghitea <28300158+sergiught@users.noreply.github.com> Date: Tue, 23 May 2023 16:53:27 +0200 Subject: [PATCH] DXCDT-308: Add guide on how to achieve 0 downtime client credential rotation (#592) Co-authored-by: Will Vedder --- README.md | 5 +- docs/data-sources/client.md | 2 +- docs/data-sources/global_client.md | 2 +- docs/guides/client_secret_rotation.md | 141 ++++++++++++++++++ docs/resources/client.md | 4 +- docs/resources/client_credentials.md | 3 + docs/resources/global_client.md | 4 +- internal/auth0/client/resource.go | 16 +- templates/guides/client_secret_rotation.md | 141 ++++++++++++++++++ .../resources/client_credentials.md.tmpl | 32 ++++ 10 files changed, 341 insertions(+), 9 deletions(-) create mode 100644 docs/guides/client_secret_rotation.md create mode 100644 templates/guides/client_secret_rotation.md create mode 100644 templates/resources/client_credentials.md.tmpl diff --git a/README.md b/README.md index 530ab9182..b5660bfca 100644 --- a/README.md +++ b/README.md @@ -21,8 +21,11 @@ The Auth0 Terraform Provider is the official plugin for managing Auth0 tenant co ## Documentation -- [Quickstart Guide](./docs/guides/quickstart.md) - [Official Docs](https://registry.terraform.io/providers/auth0/auth0/latest/docs) +- [Guides] + - [Quickstart](./docs/guides/quickstart.md) + - [List available triggers for actions](./docs/guides/action_triggers.md) + - [Zero downtime client credentials rotation](./docs/guides/client_secret_rotation.md) ## Getting Started diff --git a/docs/data-sources/client.md b/docs/data-sources/client.md index bb5243117..f76bf5c49 100644 --- a/docs/data-sources/client.md +++ b/docs/data-sources/client.md @@ -40,7 +40,7 @@ data "auth0_client" "some-client-by-id" { - `callbacks` (List of String) URLs that Auth0 may call back to after a user authenticates for the client. Make sure to specify the protocol (https://) otherwise the callback may fail in some cases. With the exception of custom URI schemes for native clients, all callbacks should use protocol https://. - `client_aliases` (List of String) List of audiences/realms for SAML protocol. Used by the wsfed addon. - `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) 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) 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. Use this attribute on the `auth0_client_credentials` resource instead, to allow managing it directly. - `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. - `custom_login_page` (String) The content (HTML, CSS, JS) of the custom login page. diff --git a/docs/data-sources/global_client.md b/docs/data-sources/global_client.md index f3bc748f7..f8a3be34e 100644 --- a/docs/data-sources/global_client.md +++ b/docs/data-sources/global_client.md @@ -28,7 +28,7 @@ data "auth0_global_client" "global" {} - `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) 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) 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. Use this attribute on the `auth0_client_credentials` resource instead, to allow managing it directly. - `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. - `custom_login_page` (String) The content (HTML, CSS, JS) of the custom login page. diff --git a/docs/guides/client_secret_rotation.md b/docs/guides/client_secret_rotation.md new file mode 100644 index 000000000..50d993219 --- /dev/null +++ b/docs/guides/client_secret_rotation.md @@ -0,0 +1,141 @@ +--- +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 characters +and valid characters are numbers, letters and `_`, `-`, `+`, `=`, `.` symbols. You can make use of the +[Terraform random provider](https://registry.terraform.io/providers/hashicorp/random/latest/docs) to generate this. +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 "random_password" "client_secret" { + length = 48 + special = true + override_special = "_-+=." +} + +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 = random_password.client_secret.result # You can also patch directly with your own 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 = <@ [Tab] [Space]`. -- `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). +- `client_secret_rotation_trigger` (Map of String, Deprecated) 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). Migrate to the `auth0_client_credentials` resource to manage a client's secret directly instead. Refer to the [client secret rotation guide](Refer to the [client secret rotation guide](https://registry.terraform.io/providers/auth0/auth0/latest/docs/guides/client_secret_rotation) for instructions on how to rotate client secrets with zero downtime. - `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. - `custom_login_page` (String) The content (HTML, CSS, JS) of the custom login page. @@ -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. Use this attribute on the `auth0_client_credentials` resource instead, to allow managing it directly. - `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. diff --git a/docs/resources/client_credentials.md b/docs/resources/client_credentials.md index f2c6b77ca..efc8c7d3d 100644 --- a/docs/resources/client_credentials.md +++ b/docs/resources/client_credentials.md @@ -8,6 +8,9 @@ description: |- With this resource, you can configure the method to use when making requests to any endpoint that requires this client to authenticate. +-> Refer to the [client secret rotation guide](https://registry.terraform.io/providers/auth0/auth0/latest/docs/guides/client_secret_rotation) +for instructions on how to rotate client secrets with zero downtime. + ## Example Usage ```terraform diff --git a/docs/resources/global_client.md b/docs/resources/global_client.md index a047c4302..901dd97ce 100644 --- a/docs/resources/global_client.md +++ b/docs/resources/global_client.md @@ -40,8 +40,8 @@ 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_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). +- `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. Use this attribute on the `auth0_client_credentials` resource instead, to allow managing it directly. +- `client_secret_rotation_trigger` (Map of String, Deprecated) 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). Migrate to the `auth0_client_credentials` resource to manage a client's secret directly instead. Refer to the [client secret rotation guide](Refer to the [client secret rotation guide](https://registry.terraform.io/providers/auth0/auth0/latest/docs/guides/client_secret_rotation) for instructions on how to rotate client secrets with zero downtime. - `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. - `custom_login_page` (String) The content (HTML, CSS, JS) of the custom login page. diff --git a/internal/auth0/client/resource.go b/internal/auth0/client/resource.go index 3066738ca..cca052080 100644 --- a/internal/auth0/client/resource.go +++ b/internal/auth0/client/resource.go @@ -49,7 +49,11 @@ func NewResource() *schema.Resource { Sensitive: true, 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.", + "empty string. Use this attribute on the `auth0_client_credentials` resource instead, to allow " + + "managing it directly.", + 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, @@ -57,7 +61,15 @@ func NewResource() *schema.Resource { Description: "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).", + "For more info: [rotate-client-secret](https://auth0.com/docs/get-started/applications/rotate-client-secret). " + + "Migrate to the `auth0_client_credentials` resource to manage a client's secret directly instead. " + + "Refer to the [client secret rotation guide](Refer to the [client secret rotation guide](https://registry.terraform.io/providers/auth0/auth0/latest/docs/guides/client_secret_rotation) " + + "for instructions on how to rotate client secrets with zero downtime.", + Deprecated: "Rotating a client's 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. " + + "Refer to the [client secret rotation guide](Refer to the [client secret rotation guide](https://registry.terraform.io/providers/auth0/auth0/latest/docs/guides/client_secret_rotation) " + + "for instructions on how to rotate client secrets with zero downtime.", }, "client_aliases": { Type: schema.TypeList, diff --git a/templates/guides/client_secret_rotation.md b/templates/guides/client_secret_rotation.md new file mode 100644 index 000000000..50d993219 --- /dev/null +++ b/templates/guides/client_secret_rotation.md @@ -0,0 +1,141 @@ +--- +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 characters +and valid characters are numbers, letters and `_`, `-`, `+`, `=`, `.` symbols. You can make use of the +[Terraform random provider](https://registry.terraform.io/providers/hashicorp/random/latest/docs) to generate this. +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 "random_password" "client_secret" { + length = 48 + special = true + override_special = "_-+=." +} + +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 = random_password.client_secret.result # You can also patch directly with your own 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 = < Refer to the [client secret rotation guide](https://registry.terraform.io/providers/auth0/auth0/latest/docs/guides/client_secret_rotation) +for instructions on how to rotate client secrets with zero downtime. + +{{ if .HasExample -}} + +## Example Usage + +{{ tffile .ExampleFile }} + +{{- end }} + +{{ .SchemaMarkdown | trimspace }} + +{{ if .HasImport -}} + +## Import + +Import is supported using the following syntax: + +{{ codefile "shell" .ImportFile }} + +{{- end }}