Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DXCDT-147: Add new auth0_client_credentials resource with support for JWT CA #588

Merged
merged 6 commits into from
May 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 58 additions & 2 deletions MIGRATION_GUIDE.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,61 @@
# Migration Guide

## Upgrading from v0.47.0 → v0.48.0

There are deprecations in this update. Please ensure you read this guide thoroughly and prepare your potential
automated workflows before upgrading.

### Deprecations

- [Client Authentication Method](#client-authentication-method)


#### Client Authentication Method


The `token_endpoint_auth_method` field on the `auth0_client` resource will continue to be available for managing the
client's authentication method. However, to ensure a smooth transition when we eventually remove the capability to
manage the authentication method through this field, we recommend proactively migrating to the newly introduced
`auth0_client_credentials` resource as this will also give you the possibility of managing the client secret.
This will help you stay prepared for future changes.

<table>
<tr>
<th>Before (v0.47.0)</th>
<th>After (v0.48.0)</th>
</tr>
<tr>
<td>

```terraform
# Example:
resource "auth0_client" "my_client" {
name = "My Client"

token_endpoint_auth_method = "client_secret_post"
}
```

</td>
<td>

```terraform
# Example:
resource "auth0_client" "my_client" {
name = "My Client"
}

resource "auth0_client_credentials" "test" {
client_id = auth0_client.my_client.id

authentication_method = "client_secret_post"
}
```

</td>
</tr>
</table>

## Upgrading from v0.46.0 → v0.47.0

There are deprecations in this update. Please ensure you read this guide thoroughly and prepare your potential
Expand All @@ -10,7 +66,7 @@ automated workflows before upgrading.
- [User Roles](#user-roles)
- [Role Permissions](#role-permissions)

### User Roles
#### User Roles

The `roles` field on the `auth0_user` resource will continue to be available for managing user roles. However, to ensure
a smooth transition when we eventually remove the capability to manage roles through this field, we recommend
Expand Down Expand Up @@ -96,7 +152,7 @@ resource auth0_user_role user_owner {
</tr>
</table>

### Role Permissions
#### Role Permissions

The `permissions` field on the `auth0_role` resource will continue to be available for managing role permissions. However, to ensure
a smooth transition when we eventually remove the capability to manage permissions through this field, we recommend
Expand Down
2 changes: 1 addition & 1 deletion docs/resources/client.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ resource "auth0_client" "my_client" {
- `refresh_token` (Block List, Max: 1) Configuration settings for the refresh tokens issued for this client. (see [below for nested schema](#nestedblock--refresh_token))
- `sso` (Boolean) Applies only to SSO clients and determines whether Auth0 will handle Single Sign-On (true) or whether the identity provider will (false).
- `sso_disabled` (Boolean) Indicates whether or not SSO is disabled.
- `token_endpoint_auth_method` (String) Defines the requested authentication method for the token endpoint. Options include `none` (public client without a client secret), `client_secret_post` (client uses HTTP POST parameters), `client_secret_basic` (client uses HTTP Basic).
- `token_endpoint_auth_method` (String, Deprecated) Defines the requested authentication method for the token endpoint. Options include `none` (public client without a client secret), `client_secret_post` (client uses HTTP POST parameters), `client_secret_basic` (client uses HTTP Basic).
- `web_origins` (List of String) URLs that represent valid web origins for use with web message response mode.

### Read-Only
Expand Down
129 changes: 129 additions & 0 deletions docs/resources/client_credentials.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
---
page_title: "Resource: auth0_client_credentials"
description: |-
With this resource, you can configure the method to use when making requests to any endpoint that requires this client to authenticate.
---

# Resource: auth0_client_credentials

With this resource, you can configure the method to use when making requests to any endpoint that requires this client to authenticate.

## Example Usage

```terraform
resource "auth0_client" "my_client" {
name = "Application - Acceptance Test"
app_type = "non_interactive"

jwt_configuration {
alg = "RS256"
}
}

# Configuring client_secret_post as an authentication method.
resource "auth0_client_credentials" "test" {
client_id = auth0_client.my_client.id

authentication_method = "client_secret_post"
}

# Configuring client_secret_basic as an authentication method.
resource "auth0_client_credentials" "test" {
client_id = auth0_client.my_client.id

authentication_method = "client_secret_basic"
}

# Configuring none as an authentication method.
resource "auth0_client_credentials" "test" {
client_id = auth0_client.my_client.id

authentication_method = "none"
}

# Configuring private_key_jwt as an authentication method.
resource "auth0_client_credentials" "test" {
client_id = auth0_client.my_client.id

authentication_method = "private_key_jwt"

private_key_jwt {
credentials {
name = "Testing Credentials 1"
credential_type = "public_key"
algorithm = "RS256"
parse_expiry_from_cert = true
pem = <<EOF
-----BEGIN CERTIFICATE-----
MIIFWDCCA0ACCQDXqpBo3R...G9w0BAQsFADBuMQswCQYDVQQGEwJl
-----END CERTIFICATE-----
EOF
}
}
}

# Configuring the client_secret.
resource "auth0_client_credentials" "test" {
client_id = auth0_client.my_client.id

authentication_method = "client_secret_basic"
client_secret = "LUFqPx+sRLjbL7peYRPFmFu-bbvE7u7og4YUNe_C345=683341"
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `authentication_method` (String) Configure the method to use when making requests to any endpoint that requires this client to authenticate. Options include `none` (public client without a client secret), `client_secret_post` (confidential client using HTTP POST parameters), `client_secret_basic` (confidential client using HTTP Basic), `private_key_jwt` (confidential client using a Private Key JWT).
- `client_id` (String) The ID of the client for which to configure the authentication method.

### Optional

- `client_secret` (String, Sensitive) Secret for the client when using `client_secret_post` or `client_secret_basic` authentication method. 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. The attribute will also be an empty string in case `private_key_jwt` is selected as an authentication method.
- `private_key_jwt` (Block List, Max: 1) Defines `private_key_jwt` client authentication method. (see [below for nested schema](#nestedblock--private_key_jwt))

### Read-Only

- `id` (String) The ID of this resource.

<a id="nestedblock--private_key_jwt"></a>
### Nested Schema for `private_key_jwt`

Required:

- `credentials` (Block List, Min: 1, Max: 2) Client credentials available for use when Private Key JWT is in use as the client authentication method. A maximum of 2 client credentials can be set. (see [below for nested schema](#nestedblock--private_key_jwt--credentials))

<a id="nestedblock--private_key_jwt--credentials"></a>
### Nested Schema for `private_key_jwt.credentials`

Required:

- `credential_type` (String) Credential type. Supported types: `public_key`.
- `pem` (String) PEM-formatted public key (SPKI and PKCS1) or X509 certificate. Must be JSON escaped.

Optional:

- `algorithm` (String) Algorithm which will be used with the credential. Can be one of `RS256`, `RS384`, `PS256`. If not specified, `RS256` will be used.
- `expires_at` (String) The ISO 8601 formatted date representing the expiration of the credential. It is not possible to set this tonever expire after it has been set. Recreate the certificate if needed.
- `name` (String) Friendly name for a credential.
- `parse_expiry_from_cert` (Boolean) Parse expiry from x509 certificate. If true, attempts to parse the expiry date from the provided PEM. If also the `expires_at` is set the credential expiry will be set to the explicit `expires_at` value.

Read-Only:

- `created_at` (String) The ISO 8601 formatted date the credential was created.
- `id` (String) The ID of the client credential.
- `key_id` (String) The key identifier of the credential, generated on creation.
- `updated_at` (String) The ISO 8601 formatted date the credential was updated.

## Import

Import is supported using the following syntax:

```shell
# A client credentials resource can be imported using the client's ID.
#
# Example:
terraform import auth0_client_credentials.my_creds AaiyAPdpYdesoKnqjj8HJqRn4T5titww
```
2 changes: 1 addition & 1 deletion docs/resources/global_client.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ PAGE
- `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.
- `sso` (Boolean) Applies only to SSO clients and determines whether Auth0 will handle Single Sign-On (true) or whether the identity provider will (false).
- `sso_disabled` (Boolean) Indicates whether or not SSO is disabled.
- `token_endpoint_auth_method` (String) Defines the requested authentication method for the token endpoint. Options include `none` (public client without a client secret), `client_secret_post` (client uses HTTP POST parameters), `client_secret_basic` (client uses HTTP Basic).
- `token_endpoint_auth_method` (String, Deprecated) Defines the requested authentication method for the token endpoint. Options include `none` (public client without a client secret), `client_secret_post` (client uses HTTP POST parameters), `client_secret_basic` (client uses HTTP Basic).
- `web_origins` (List of String) URLs that represent valid web origins for use with web message response mode.

### Read-Only
Expand Down
4 changes: 4 additions & 0 deletions examples/resources/auth0_client_credentials/import.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# A client credentials resource can be imported using the client's ID.
#
# Example:
terraform import auth0_client_credentials.my_creds AaiyAPdpYdesoKnqjj8HJqRn4T5titww
58 changes: 58 additions & 0 deletions examples/resources/auth0_client_credentials/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
resource "auth0_client" "my_client" {
name = "Application - Acceptance Test"
app_type = "non_interactive"

jwt_configuration {
alg = "RS256"
}
}

# Configuring client_secret_post as an authentication method.
resource "auth0_client_credentials" "test" {
client_id = auth0_client.my_client.id

authentication_method = "client_secret_post"
}

# Configuring client_secret_basic as an authentication method.
resource "auth0_client_credentials" "test" {
client_id = auth0_client.my_client.id

authentication_method = "client_secret_basic"
}

# Configuring none as an authentication method.
resource "auth0_client_credentials" "test" {
client_id = auth0_client.my_client.id

authentication_method = "none"
}

# Configuring private_key_jwt as an authentication method.
resource "auth0_client_credentials" "test" {
client_id = auth0_client.my_client.id

authentication_method = "private_key_jwt"

private_key_jwt {
credentials {
name = "Testing Credentials 1"
credential_type = "public_key"
algorithm = "RS256"
parse_expiry_from_cert = true
pem = <<EOF
-----BEGIN CERTIFICATE-----
MIIFWDCCA0ACCQDXqpBo3R...G9w0BAQsFADBuMQswCQYDVQQGEwJl
-----END CERTIFICATE-----
EOF
}
}
}

# Configuring the client_secret.
resource "auth0_client_credentials" "test" {
client_id = auth0_client.my_client.id

authentication_method = "client_secret_basic"
client_secret = "LUFqPx+sRLjbL7peYRPFmFu-bbvE7u7og4YUNe_C345=683341"
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/auth0/terraform-provider-auth0
go 1.20

require (
github.com/auth0/go-auth0 v0.17.1
github.com/auth0/go-auth0 v0.17.2
github.com/google/go-cmp v0.5.9
github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320
github.com/hashicorp/go-multierror v1.1.1
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj
github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI=
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/auth0/go-auth0 v0.17.1 h1:xfk6Zuit4Tigg985RPZ6tpue5VHako8KfVkjjC+6X5g=
github.com/auth0/go-auth0 v0.17.1/go.mod h1:CMHBK8TF30dmqCItdcDHVyXg0UbYxT0laf4MGDMseN0=
github.com/auth0/go-auth0 v0.17.2 h1:qEttAY4yYeEJl6wu0iOwlet26wUKA2G5YOUomfuxcy4=
github.com/auth0/go-auth0 v0.17.2/go.mod h1:Hlp4kYcvn2JSD1tAmPQ8DD7MMoiO0bwVJwTHXqJbDDE=
github.com/aybabtme/iocontrol v0.0.0-20150809002002-ad15bcfc95a0 h1:0NmehRCgyk5rljDQLKUO+cRJCnduDyn11+zGZIc9Z48=
github.com/aybabtme/iocontrol v0.0.0-20150809002002-ad15bcfc95a0/go.mod h1:6L7zgvqo0idzI7IO8de6ZC051AfXb5ipkIJ7bIA2tGA=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
Expand Down
22 changes: 17 additions & 5 deletions internal/acctest/http_recorder.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,19 @@ func redactDomain(i *cassette.Interaction, domain string) {
}

func redactSensitiveDataInClient(t *testing.T, i *cassette.Interaction, domain string) {
create := i.Request.URL == "https://"+domain+"/api/v2/clients" && i.Request.Method == http.MethodPost
read := strings.Contains(i.Request.URL, "https://"+domain+"/api/v2/clients/") && i.Request.Method == http.MethodGet
update := strings.Contains(i.Request.URL, "https://"+domain+"/api/v2/clients/") && i.Request.Method == http.MethodPatch
rotateSecret := strings.Contains(i.Request.URL, "clients") && strings.Contains(i.Request.URL, "/rotate-secret")
create := i.Request.URL == "https://"+domain+"/api/v2/clients" &&
i.Request.Method == http.MethodPost

read := strings.Contains(i.Request.URL, "https://"+domain+"/api/v2/clients/") &&
!strings.Contains(i.Request.URL, "credentials") &&
i.Request.Method == http.MethodGet

update := strings.Contains(i.Request.URL, "https://"+domain+"/api/v2/clients/") &&
!strings.Contains(i.Request.URL, "credentials") &&
i.Request.Method == http.MethodPatch

rotateSecret := strings.Contains(i.Request.URL, "clients") &&
strings.Contains(i.Request.URL, "/rotate-secret")

if create || read || update || rotateSecret {
var client management.Client
Expand All @@ -119,7 +128,10 @@ func redactSensitiveDataInClient(t *testing.T, i *cassette.Interaction, domain s
client.SigningKeys = []map[string]string{
{"cert": redacted},
}
client.ClientSecret = &redacted

if client.GetClientSecret() != "" {
client.ClientSecret = &redacted
}

clientBody, err := json.Marshal(client)
require.NoError(t, err)
Expand Down
5 changes: 5 additions & 0 deletions internal/auth0/client/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,11 @@ func NewResource() *schema.Resource {
"Options include `none` (public client without a client secret), " +
"`client_secret_post` (client uses HTTP POST parameters), " +
"`client_secret_basic` (client uses HTTP Basic).",
Deprecated: "Managing the authentication method through this attribute is deprecated and it will be " +
"changed to read-only in a future version. Migrate to the `auth0_client_credentials` resource to " +
"manage a client's authentication method instead. Check the " +
"[MIGRATION GUIDE](https://github.com/auth0/terraform-provider-auth0/blob/main/MIGRATION_GUIDE.md) " +
"on how to do that.",
},
"client_metadata": {
Type: schema.TypeMap,
Expand Down
Loading