From 38718a97eb34b652375599829b9d9c6725b720b5 Mon Sep 17 00:00:00 2001 From: Sergiu Ghitea <28300158+sergiught@users.noreply.github.com> Date: Fri, 19 May 2023 18:45:07 +0200 Subject: [PATCH] Add default token on delete, refactor, add recordings, add docs --- MIGRATION_GUIDE.md | 60 ++- docs/resources/client.md | 2 +- docs/resources/client_credentials.md | 129 ++++++ docs/resources/global_client.md | 2 +- .../auth0_client_credentials/import.sh | 4 + .../auth0_client_credentials/resource.tf | 58 +++ go.mod | 6 +- go.sum | 4 +- internal/acctest/http_recorder.go | 22 +- internal/auth0/client/resource.go | 5 + internal/auth0/client/resource_credentials.go | 78 ++-- .../auth0/client/resource_credentials_test.go | 122 ++++-- test/data/creds-cert-2.pem | 2 +- .../TestAccAllowUpdatingTheClientSecret.yaml | 398 ++++++++++++++++++ 14 files changed, 797 insertions(+), 95 deletions(-) create mode 100644 docs/resources/client_credentials.md create mode 100644 examples/resources/auth0_client_credentials/import.sh create mode 100644 examples/resources/auth0_client_credentials/resource.tf create mode 100644 test/data/recordings/TestAccAllowUpdatingTheClientSecret.yaml diff --git a/MIGRATION_GUIDE.md b/MIGRATION_GUIDE.md index fed1d0a39..835700bc0 100644 --- a/MIGRATION_GUIDE.md +++ b/MIGRATION_GUIDE.md @@ -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. + + + + + + + + + + +
Before (v0.47.0)After (v0.48.0)
+ +```terraform +# Example: +resource "auth0_client" "my_client" { + name = "My Client" + + token_endpoint_auth_method = "client_secret_post" +} +``` + + + +```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" +} +``` + +
+ ## 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 @@ -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 @@ -96,7 +152,7 @@ resource auth0_user_role user_owner { -### 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 diff --git a/docs/resources/client.md b/docs/resources/client.md index b53562519..57319a81b 100644 --- a/docs/resources/client.md +++ b/docs/resources/client.md @@ -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 diff --git a/docs/resources/client_credentials.md b/docs/resources/client_credentials.md new file mode 100644 index 000000000..f2c6b77ca --- /dev/null +++ b/docs/resources/client_credentials.md @@ -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 = < +## 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. + + +### 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)) + + +### 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 +``` diff --git a/docs/resources/global_client.md b/docs/resources/global_client.md index f2396a35a..a047c4302 100644 --- a/docs/resources/global_client.md +++ b/docs/resources/global_client.md @@ -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 diff --git a/examples/resources/auth0_client_credentials/import.sh b/examples/resources/auth0_client_credentials/import.sh new file mode 100644 index 000000000..3376d49f2 --- /dev/null +++ b/examples/resources/auth0_client_credentials/import.sh @@ -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 diff --git a/examples/resources/auth0_client_credentials/resource.tf b/examples/resources/auth0_client_credentials/resource.tf new file mode 100644 index 000000000..973a438a3 --- /dev/null +++ b/examples/resources/auth0_client_credentials/resource.tf @@ -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 = < /Users/sergiu.ghitea/auth0/go-auth0 -) - require ( github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver/v3 v3.1.1 // indirect diff --git a/go.sum b/go.sum index 9464751af..bb51a63b8 100644 --- a/go.sum +++ b/go.sum @@ -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.0.0-20230516085808-85d92279deba h1:h/TVKMBVjmoWmVBDcFAa0UmLG1qVM7iBKQNGT8JXlQw= -github.com/auth0/go-auth0 v0.0.0-20230516085808-85d92279deba/go.mod h1:CMHBK8TF30dmqCItdcDHVyXg0UbYxT0laf4MGDMseN0= +github.com/auth0/go-auth0 v0.0.0-20230519152811-8a17ec5dda68 h1:7trqLmwOSNo7UcbPRTknZR8HC04XiviLXBMEXekWAOs= +github.com/auth0/go-auth0 v0.0.0-20230519152811-8a17ec5dda68/go.mod h1:CMHBK8TF30dmqCItdcDHVyXg0UbYxT0laf4MGDMseN0= 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= diff --git a/internal/acctest/http_recorder.go b/internal/acctest/http_recorder.go index cde88493c..7724e6fe7 100644 --- a/internal/acctest/http_recorder.go +++ b/internal/acctest/http_recorder.go @@ -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 @@ -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) diff --git a/internal/auth0/client/resource.go b/internal/auth0/client/resource.go index e38c806e7..3066738ca 100644 --- a/internal/auth0/client/resource.go +++ b/internal/auth0/client/resource.go @@ -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, diff --git a/internal/auth0/client/resource_credentials.go b/internal/auth0/client/resource_credentials.go index 0ea7bf2db..83af99f55 100644 --- a/internal/auth0/client/resource_credentials.go +++ b/internal/auth0/client/resource_credentials.go @@ -8,7 +8,6 @@ import ( "strconv" "time" - "github.com/auth0/go-auth0" "github.com/auth0/go-auth0/management" "github.com/hashicorp/go-cty/cty" "github.com/hashicorp/go-multierror" @@ -77,12 +76,10 @@ func NewCredentialsResource() *schema.Resource { Description: "The ID of the client credential.", }, "name": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - Description: "Friendly name for a credential. " + - "Changing this will force the credential to be recreated, " + - "resulting in a new client credential ID.", + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Description: "Friendly name for a credential. ", }, "key_id": { Type: schema.TypeString, @@ -94,18 +91,14 @@ func NewCredentialsResource() *schema.Resource { Required: true, ForceNew: true, ValidateFunc: validation.StringInSlice([]string{"public_key"}, false), - Description: "Credential type. Supported types: `public_key`. " + - "Changing this will force the credential to be recreated, " + - "resulting in a new client credential ID.", + Description: "Credential type. Supported types: `public_key`. ", }, "pem": { Type: schema.TypeString, Required: true, ForceNew: true, Description: "PEM-formatted public key (SPKI and PKCS1) or X509 certificate. " + - "Must be JSON escaped. " + - "Changing this will force the credential to be recreated, " + - "resulting in a new client credential ID.", + "Must be JSON escaped. ", }, "algorithm": { Type: schema.TypeString, @@ -115,9 +108,7 @@ func NewCredentialsResource() *schema.Resource { Default: "RS256", Description: "Algorithm which will be used with the credential. " + "Can be one of `RS256`, `RS384`, `PS256`. If not specified, " + - "`RS256` will be used. " + - "Changing this will force the credential to be recreated, " + - "resulting in a new client credential ID.", + "`RS256` will be used. ", }, "parse_expiry_from_cert": { Type: schema.TypeBool, @@ -125,8 +116,8 @@ func NewCredentialsResource() *schema.Resource { ForceNew: true, Description: "Parse expiry from x509 certificate. " + "If true, attempts to parse the expiry date from the provided PEM. " + - "Changing this will force the credential to be recreated, " + - "resulting in a new client credential ID.", + "If also the `expires_at` is set the credential expiry will be set to " + + "the explicit `expires_at` value. ", }, "created_at": { Type: schema.TypeString, @@ -144,7 +135,8 @@ func NewCredentialsResource() *schema.Resource { Computed: true, ValidateFunc: validation.IsRFC3339Time, Description: "The ISO 8601 formatted date representing " + - "the expiration of the credential.", + "the expiration of the credential. It is not possible to set this to" + + "never expire after it has been set. Recreate the certificate if needed.", }, }, }, @@ -283,20 +275,34 @@ func deleteClientCredentials(_ context.Context, data *schema.ResourceData, meta api := meta.(*config.Config).GetAPI() clientID := data.Get("client_id").(string) + client, err := api.Client.Read(clientID, management.IncludeFields("client_id", "app_type")) + if err != nil { + if mErr, ok := err.(management.Error); ok && mErr.Status() == http.StatusNotFound { + data.SetId("") + return nil + } + + return diag.FromErr(err) + } + + tokenEndpointAuthMethod := "" + switch client.GetAppType() { + case "native", "spa": + tokenEndpointAuthMethod = "none" + case "regular_web", "non_interactive": + tokenEndpointAuthMethod = "client_secret_post" + default: + tokenEndpointAuthMethod = "client_secret_basic" + } authenticationMethod := data.Get("authentication_method").(string) if authenticationMethod == "private_key_jwt" { credentials, err := api.Client.ListCredentials(clientID) if err != nil { - if mErr, ok := err.(management.Error); ok && mErr.Status() == http.StatusNotFound { - data.SetId("") - return nil - } - return diag.FromErr(err) } - if err := detachCredentialsFromClient(api, clientID); err != nil { + if err := detachCredentialsFromClient(api, clientID, tokenEndpointAuthMethod); err != nil { return diag.FromErr(err) } @@ -306,11 +312,17 @@ func deleteClientCredentials(_ context.Context, data *schema.ResourceData, meta } } + data.SetId("") return nil } - data.SetId("") + if err := api.Client.Update(clientID, &management.Client{ + TokenEndpointAuthMethod: &tokenEndpointAuthMethod, + }); err != nil { + return diag.FromErr(err) + } + data.SetId("") return nil } @@ -325,11 +337,6 @@ func createPrivateKeyJWTCredentials(api *management.Management, data *schema.Res credentialsToAttach := make([]management.Credential, 0) for _, credential := range credentials { if err := api.Client.CreateCredential(clientID, credential); err != nil { - if mErr, ok := err.(management.Error); ok && mErr.Status() == http.StatusNotFound { - data.SetId("") - return nil - } - return diag.FromErr(err) } @@ -396,11 +403,12 @@ func attachCredentialsToClient(api *management.Management, clientID string, cred return updateClientWithAuthMethod(api, client) } -func detachCredentialsFromClient(api *management.Management, clientID string) error { +func detachCredentialsFromClient(api *management.Management, clientID, tokenEndpointAuthMethod string) error { client := clientWithAuthMethod{ ID: clientID, ClientAuthenticationMethods: nil, - TokenEndpointAuthMethod: auth0.String("client_secret_post"), + // API doesn't accept nil on both of these, so we temporarily set this to a default. + TokenEndpointAuthMethod: &tokenEndpointAuthMethod, } return updateClientWithAuthMethod(api, client) @@ -535,10 +543,6 @@ func flattenPrivateKeyJWT( for index, credential := range clientAuthMethods.GetPrivateKeyJWT().GetCredentials() { credential, err := api.Client.GetCredential(data.Id(), credential.GetID()) if err != nil { - if mErr, ok := err.(management.Error); ok && mErr.Status() == http.StatusNotFound { - return nil, nil - } - return nil, err } diff --git a/internal/auth0/client/resource_credentials_test.go b/internal/auth0/client/resource_credentials_test.go index dba5fc5b1..d24a8ed14 100644 --- a/internal/auth0/client/resource_credentials_test.go +++ b/internal/auth0/client/resource_credentials_test.go @@ -14,7 +14,8 @@ import ( const testAccThrowErrorWhenPrivateKeyJWT = ` resource "auth0_client" "my_client" { - name = "Acceptance Test - Client Credentials - {{.testName}}" + name = "Acceptance Test - Client Credentials - {{.testName}}" + app_type = "non_interactive" } resource "auth0_client_credentials" "my_client_credentials" { @@ -26,7 +27,8 @@ resource "auth0_client_credentials" "my_client_credentials" { const testAccCreateOneClientCredentialUsingPrivateKeyJWT = ` resource "auth0_client" "my_client" { - name = "Acceptance Test - Client Credentials - {{.testName}}" + name = "Acceptance Test - Client Credentials - {{.testName}}" + app_type = "non_interactive" jwt_configuration { alg = "RS256" @@ -54,7 +56,8 @@ EOF const testAccAddAnotherClientCredentialUsingPrivateKeyJWT = ` resource "auth0_client" "my_client" { - name = "Acceptance Test - Client Credentials - {{.testName}}" + name = "Acceptance Test - Client Credentials - {{.testName}}" + app_type = "non_interactive" jwt_configuration { alg = "RS256" @@ -92,7 +95,8 @@ EOF const testAccAddUpdateClientCredentialsExpiresAt = ` resource "auth0_client" "my_client" { - name = "Acceptance Test - Client Credentials - {{.testName}}" + name = "Acceptance Test - Client Credentials - {{.testName}}" + app_type = "non_interactive" jwt_configuration { alg = "RS256" @@ -106,10 +110,11 @@ resource "auth0_client_credentials" "test" { private_key_jwt { credentials { - name = "Testing Credentials 1" - credential_type = "public_key" - algorithm = "RS256" - expires_at = "2024-05-13T09:33:13.000Z" + name = "Testing Credentials 1" + credential_type = "public_key" + algorithm = "RS256" + parse_expiry_from_cert = true + expires_at = "2050-05-13T09:33:13.000Z" # This takes precedence. pem = <