auth0/terraform-provider-auth0

Incorrect token_endpoint_auth_method for SPA in Auth0 via Terraform

Karthik6615 opened this issue · 6 comments

Checklist

  • I have looked into the README and have not found a suitable solution or answer.
  • I have looked into the documentation and have not found a suitable solution or answer.
  • I have searched the issues and have not found a suitable solution or answer.
  • I have upgraded to the latest version of this provider and the issue still persists.
  • I have searched the Auth0 Community forums and have not found a suitable solution or answer.
  • I agree to the terms within the Auth0 Code of Conduct.

Description

Hi Terraform Team,

I'm encountering a bug with the token_endpoint_auth_method when deploying a Single Page Application (SPA) via Terraform.

When created via the Auth0 Dashboard, the token_endpoint_auth_method is correctly set to none. However, when deployed via Terraform, it is set to client_secret_post.

This seems related to a feature introduced in v1.1.0 of the Terraform Auth0 provider. Currently, we are using version 1.1.2 of the provider.

Please look into this issue. More details can be found: https://github.com/auth0/terraform-provider-auth0/releases.

Thank you,
Karthik Thatipati

Screenshot 2024-05-17 at 12 22 05 PM Screenshot 2024-05-17 at 12 15 35 PM

Expectation

token_endpoint_auth_method should set to none, when creating auth0_client with app_type as spa

Reproduction

When created via the Auth0 Dashboard, the token_endpoint_auth_method is correctly set to none. However, when deployed via Terraform, it is set to client_secret_post.

This seems related to a feature introduced in v1.1.0 of the Terraform Auth0 provider. Currently, we are using version 1.1.2 of the provider.

Auth0 Terraform Provider version

1.1.2

Terraform version

1.5.4

Hey @Karthik6615,

Hope everything's going well for you! I've been tinkering with creating a resource of my own, and I'm wondering if you could lend a hand. Below is the example resource I've been working on. It seems to be functioning properly on my end:

resource "auth0_client" "frontend_client" {
  name        = "name"
  description = "description"

  client_metadata = {} // Feel free to insert your real values here

  app_type = "spa"

  // Fill in with your real values
  initiate_login_uri  = ""
  callbacks           = []
  allowed_origins     = []
  allowed_logout_urls = []
  web_origins         = []

  oidc_conformant = true
  logo_uri        = ""
  grant_types     = [
    "refresh_token",
    "authorization_code",
    "http://auth0.com/oauth/grant-type/mfa-otp"
  ]
  is_first_party  = true

  jwt_configuration {
    alg = "RS256"
  }

  refresh_token {
    rotation_type                = "rotating"
    expiration_type              = "expiring"
    token_lifetime               = 43200 // 12 hours
    idle_token_lifetime          = 28800 // 8 hours
    infinite_idle_token_lifetime = false
  }
}

If you have a similar example resource or any insights, could you please share it with me? I'd love to compare notes and gather more ideas. Thanks in advance!

I have the same problem as the issue opener. My "auth0_client" resource looks roughly like this:

resource "auth0_client" "..." {
  name                       = "..."
  description                = "..."
  app_type                   = "spa"
  callbacks                  = [var.base_url"]
  allowed_origins            = [var.base_url]
  web_origins                = [var.base_url]
  allowed_logout_urls        = [var.base_url]

  jwt_configuration {
    alg = "RS256"
  }

  grant_types = [
    "implicit",
    "authorization_code",
    "refresh_token",
    "http://auth0.com/oauth/grant-type/mfa-otp",
    "http://auth0.com/oauth/grant-type/mfa-recovery-code"
  ]
}

While the data source "auth0_client" has the option to specify token_endpoint_auth_method, I couldn't find an option to set it using the resource. And as the issue opener already mentioned, it should be set to none by default anyways when using an spa app_type.

P.s.: Found a working solution by adding another resource:

resource "auth0_client_credentials" "l..." {
  client_id = auth0_client.xxx.id

  authentication_method = "none"
}

Hey @Karthik6615,

Hope your day's going well.

Sorry for the confusion in my last message. Also, a big shoutout to @thomaswienecke for pitching in! Let me explain things a bit more clearly.

When you're creating a new Single Page Application (SPA), there's something important to note: for these new SPAs, the token_endpoint_auth_method is now set to none by default starting from provider version 1.1.0. Here's an example to make it clear:

Example :

resource "auth0_client" "frontend_client" {
  name        = "name"
  description = "description"

  client_metadata = {} // Feel free to insert your real values here

  app_type = "spa"

  // Fill in with your real values
  initiate_login_uri  = ""
  callbacks           = []
  allowed_origins     = []
  allowed_logout_urls = []
  web_origins         = []

  oidc_conformant = true
  logo_uri        = ""
  grant_types     = [
    "refresh_token",
    "authorization_code",
    "http://auth0.com/oauth/grant-type/mfa-otp"
  ]
  is_first_party  = true

  jwt_configuration {
    alg = "RS256"
  }

  refresh_token {
    rotation_type                = "rotating"
    expiration_type              = "expiring"
    token_lifetime               = 43200 // 12 hours
    idle_token_lifetime          = 28800 // 8 hours
    infinite_idle_token_lifetime = false
  }
}

However, if you're working with older provider versions (before 1.1.0), the default token_endpoint_auth_method is not set automatically. You'd need to use something like this:

Example :

resource "auth0_client" "frontend_client" {
  name        = "name"
  description = "description"

  client_metadata = {} // Feel free to insert your real values here

  app_type = "spa"

  // Fill in with your real values
  initiate_login_uri  = ""
  callbacks           = []
  allowed_origins     = []
  allowed_logout_urls = []
  web_origins         = []

  oidc_conformant = true
  logo_uri        = ""
  grant_types     = [
    "refresh_token",
    "authorization_code",
    "http://auth0.com/oauth/grant-type/mfa-otp"
  ]
  is_first_party  = true

  jwt_configuration {
    alg = "RS256"
  }

  refresh_token {
    rotation_type                = "rotating"
    expiration_type              = "expiring"
    token_lifetime               = 43200 // 12 hours
    idle_token_lifetime          = 28800 // 8 hours
    infinite_idle_token_lifetime = false
  }
}

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

  authentication_method = "none"
}

By making this adjustment, it should sort out the issue you're facing. If there's anything else you need help with or if you run into more issues, just drop a comment or open a new issue. I'm here to assist however I can.

For more detailed information, you can check out the reference link here, where it maps to the token_endpoint_auth_method. Additionally, you can review the changelog for further details on this update.

Hi Kunal,

Thank you for the information. I wanted to share an observation I made. Even though it's a single-page application, we can set authentication_method = "client_secret_post" in the auth0_client_credentials resource. Additionally, if we set authentication_method to none, the auth0_client works as expected.

Best regards,
Karthik Thatipati

Hi @Karthik6615 ,

I hope you're having a nice day!

Thanks for sharing your observation. It's interesting to note that even though it's a single-page application, we're able to set the authentication_method to "client_secret_post" in the auth0_client_credentials resource. Additionally, setting authentication_method to none seems to work as expected.


There's some subtlety here, but this behavior is expected. The dashboard has certain conventions and restrictions in place to guide developers towards safer and recommended setups. For single-page applications in the dashboard, we don't display a credentials tab since SPAs typically can't securely hold any credentials and should be treated as public clients with token_endpoint_auth_method set to none.

However, when using the management API, we allow more flexibility and freedom, enabling you to configure any authentication method. This backward compatibility feature allows you to configure an authentication method using the API. But it's worth noting that you might end up with an app tagged as an SPA, which might not align with its actual nature.

The key message here is that SPAs cannot securely hold credentials, so a SPA should only use token_endpoint_auth_method: none. Anything else is not recommended and should only be used in applications that can securely store a confidential credential.

Overall, things should continue to function as expected if you configure an authentication method using the API. However, it's essential to be mindful of the intended setup and the implications of the chosen authentication method.

If you have any questions or anything to ask, please feel free to do so here or create new issues.

Thank you!

Hi @Karthik6615 ,

I hope you're having a pleasant day!

I just wanted to inform you that I'll be closing this issue shortly. However, if you have any more issues or questions, please feel free to open a new one. I'm here to assist you further.

Best regards,