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

[Bug]: Incompatible client_id for Google OAuth in AWS Cognito Identity Pool #39560

Open
KenkoGeek opened this issue Oct 2, 2024 · 1 comment
Labels
bug Addresses a defect in current functionality. service/cognitoidp Issues and PRs that pertain to the cognitoidp service.

Comments

@KenkoGeek
Copy link

KenkoGeek commented Oct 2, 2024

Terraform Core Version

1.5.5

AWS Provider Version

5.69.0

Affected Resource(s)

There is an error when trying to integrate Google OAuth with aws_cognito_identity_pool using the client_id from Google’s OAuth credentials.

resource "aws_cognito_identity_pool" "this" {
  identity_pool_name               = "${var.project_name}-identity-pool"
  allow_unauthenticated_identities = false

  # Cognito as identity provider
  cognito_identity_providers {
    client_id     = aws_cognito_user_pool_client.this.id
    provider_name = aws_cognito_user_pool.this.endpoint
  }

  External identity providers
   dynamic "cognito_identity_providers" {
     for_each = var.identity_providers
     content {
       client_id     = cognito_identity_providers.value.client_id
       provider_name = cognito_identity_providers.value.provider_name
     }
  }

  tags = {
    Name = "${var.project_name}-identity-pool"
  }
}
variable "identity_providers" {
  description = "Map of configuration for Cognito Identity Providers"
  type = map(object({
    client_id         = string
    client_secret     = string
    provider_name     = string
    provider_type     = string
    authorize_scopes  = string
    additional_details = map(string)
  }))
  default = {}
}
identity_providers = {
  google = {
    client_id        = "xx33eeexxxaaa.apps.googleusercontent.com "
    client_secret    = "GOaassxxddffccvvkkkk"
    provider_name    = "accounts.google.com"
    provider_type    = "Google"
    authorize_scopes = "openid,email,profile"
    additional_details = {
      project_id = "my_project_sknndhnhj123"
    }
  }
}

Problem Overview:

When setting up Google OAuth as a login provider for an aws_cognito_identity_pool, the client_id obtained from Google Cloud Console (for example, 123456789012.apps.googleusercontent.com) causes the following error:

"client_id must contain only alphanumeric characters and underscores"

However, this is the official OAuth Client ID format from Google, and Cognito expects this value when integrating Google OAuth. This issue arises due to the restriction that aws_cognito_identity_pool imposes on the client_id, where only alphanumeric characters and underscores are allowed. This limitation conflicts with the structure of Google’s OAuth Client IDs, which include periods and hyphens.

Error Output:

Error: "cognito_identity_providers.1.client_id" must contain only alphanumeric characters and underscores

  with aws_cognito_identity_pool.main,
  on main.tf line 88, in resource "aws_cognito_identity_pool" "main":
  88: resource "aws_cognito_identity_pool" "this" {

Expected Behavior

The aws_cognito_identity_pool should accept Google’s OAuth Client ID format without throwing an error, allowing integration of Google OAuth for user login.

In AWS Console and CDK is supported.

Actual Behavior

The Identity Pool rejects the Google client_id due to non-alphanumeric characters such as periods (.) and hyphens (-), even though this is the official format used by Google for OAuth Client IDs.

OAuth Client ID Format: Google uses xxx.apps.googleusercontent.com, which is not compliant with the restrictions currently imposed by AWS Cognito Identity Pool.

Relevant Error/Panic Output Snippet

Terraform planned the following actions, but then encountered a problem:

  # module.wp_butler_cognito.aws_cognito_identity_provider.these["google"] must be replaced
-/+ resource "aws_cognito_identity_provider" "these" {
      ~ attribute_mapping = {
          - "username" = "sub"
        } -> (known after apply)
      ~ id                = "us-east-2_LXXRRTT:Google" -> (known after apply)
      - idp_identifiers   = [] -> null
      ~ provider_details  = {
          - "attributes_url"                = "https://people.googleapis.com/v1/people/me?personFields=" -> null
          - "attributes_url_add_attributes" = "true" -> null
          - "authorize_url"                 = "https://accounts.google.com/o/oauth2/v2/auth" -> null
          - "oidc_issuer"                   = "https://accounts.google.com" -> null
          - "token_request_method"          = "POST" -> null
          - "token_url"                     = "https://www.googleapis.com/oauth2/v4/token" -> null
            # (3 unchanged elements hidden)
        }
      ~ provider_name     = "Google" -> "accounts.google.com" # forces replacement
        # (2 unchanged attributes hidden)
    }

Plan: 1 to add, 0 to change, 1 to destroy.
╷
│ Error: "cognito_identity_providers.1.client_id" must contain only alphanumeric characters and underscores
│ 
│   with module.wp_butler_cognito.aws_cognito_identity_pool.this,
│   on .terraform/modules/wp_butler_cognito/main.tf line 88, in resource "aws_cognito_identity_pool" "this":
│   88: resource "aws_cognito_identity_pool" "this" {
│ 
╵
::error::Terraform exited with code 1.
Error: Process completed with exit code 1.

Terraform Configuration Files

resource "aws_cognito_user_pool" "this" {
  name = "${var.project_name}-user-pool"

  auto_verified_attributes = ["email"]
  username_attributes      = ["email"]
  mfa_configuration        = "ON"

  password_policy {
    minimum_length    = 12
    require_lowercase = true
    require_numbers   = true
    require_symbols   = true
    require_uppercase = true
  }

  software_token_mfa_configuration {
    enabled = true
  }

  account_recovery_setting {
    recovery_mechanism {
      name     = "verified_email"
      priority = 1
    }
  }

  device_configuration {
    challenge_required_on_new_device = true
  }

  tags = {
    Name = "${var.project_name}-user-pool"
  }
}

# Cognito Identity Providers configuration
resource "aws_cognito_identity_provider" "these" {
  for_each = var.identity_providers

  user_pool_id  = aws_cognito_user_pool.this.id
  provider_name = each.value.provider_type
  provider_type = each.value.provider_type

  provider_details = {
    client_id        = each.value.client_id
    client_secret    = each.value.client_secret
    authorize_scopes = each.value.authorize_scopes
    team_id          = lookup(each.value.additional_details, "team_id", null)
    key_id           = lookup(each.value.additional_details, "key_id", null)
    private_key      = lookup(each.value.additional_details, "private_key", null)
  }
}

# Introduce a wait time before creating the User Pool Client
resource "null_resource" "wait_before_client_creation" {
  provisioner "local-exec" {
    command = "sleep 30"
  }
}

# Cognito User Pool Client configuration
resource "aws_cognito_user_pool_client" "this" {
  depends_on = [null_resource.wait_before_client_creation]

  user_pool_id                         = aws_cognito_user_pool.this.id
  name                                 = "${var.project_name}-app-client"
  allowed_oauth_flows                  = var.allowed_oauth_flows
  allowed_oauth_flows_user_pool_client = var.allowed_oauth_flows_user_pool_client
  allowed_oauth_scopes                 = var.allowed_oauth_scopes
  callback_urls                        = var.callback_urls
  logout_urls                          = var.logout_urls
  generate_secret                      = false

  supported_identity_providers = flatten([
    "COGNITO",
    [
      for p in keys(var.identity_providers) :
      p == "facebook" ? "Facebook" : (
        p == "google" ? "Google" : (
      p == "apple" ? "SignInWithApple" : null))
      if p != null
    ]
  ])
}

# Cognito Identity Pool configuration
resource "aws_cognito_identity_pool" "this" {
  identity_pool_name               = "${var.project_name}-identity-pool"
  allow_unauthenticated_identities = false

  # Cognito as identity provider
  cognito_identity_providers {
    client_id     = aws_cognito_user_pool_client.this.id
    provider_name = aws_cognito_user_pool.this.endpoint
  }

  # External identity providers
  dynamic "cognito_identity_providers" {
    for_each = var.identity_providers
    content {
      client_id     = cognito_identity_providers.value.client_id
      provider_name = cognito_identity_providers.value.provider_name
    }
  }

  tags = {
    Name = "${var.project_name}-identity-pool"
  }
}

resource "aws_iam_role" "authenticated_role" {
  name = "${var.project_name}-authenticated-role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17",
    Statement = [
      {
        Effect = "Allow",
        Principal = {
          Federated = "cognito-identity.amazonaws.com"
        },
        Action = "sts:AssumeRoleWithWebIdentity",
        Condition = {
          StringEquals = {
            "cognito-identity.amazonaws.com:aud" : aws_cognito_identity_pool.this.id
          },
          "ForAnyValue:StringLike" : {
            "cognito-identity.amazonaws.com:amr" : "authenticated"
          }
        }
      }
    ]
  })
}

resource "aws_cognito_identity_pool_roles_attachment" "this" {
  identity_pool_id = aws_cognito_identity_pool.this.id

  roles = {
    authenticated = aws_iam_role.authenticated_role.arn
  }
}

Steps to Reproduce

1.	Register an application in Google Cloud Console and obtain an OAuth Client ID.
•	Format of the OAuth Client ID: 123456789012.apps.googleusercontent.com.
2.	Set up an `aws_cognito_identity_pool` and configure Google OAuth as a Login Provider using the OAuth Client ID obtained from Google Cloud.
3.	Run the Terraform configuration
4.	Observe the error due to the restriction on the format of client_id.

Debug Output

No response

Panic Output

No response

Important Factoids

No response

References

No response

Would you like to implement a fix?

No

@KenkoGeek KenkoGeek added the bug Addresses a defect in current functionality. label Oct 2, 2024
Copy link

github-actions bot commented Oct 2, 2024

Community Note

Voting for Prioritization

  • Please vote on this issue by adding a 👍 reaction to the original post to help the community and maintainers prioritize this request.
  • Please see our prioritization guide for information on how we prioritize.
  • Please do not leave "+1" or other comments that do not add relevant new information or questions, they generate extra noise for issue followers and do not help prioritize the request.

Volunteering to Work on This Issue

  • If you are interested in working on this issue, please leave a comment.
  • If this would be your first contribution, please review the contribution guide.

@github-actions github-actions bot added service/cognitoidp Issues and PRs that pertain to the cognitoidp service. service/cognitoidentity Issues and PRs that pertain to the cognitoidentity service. service/iam Issues and PRs that pertain to the iam service. needs-triage Waiting for first response or review from a maintainer. labels Oct 2, 2024
@justinretzolk justinretzolk removed service/iam Issues and PRs that pertain to the iam service. needs-triage Waiting for first response or review from a maintainer. service/cognitoidentity Issues and PRs that pertain to the cognitoidentity service. labels Oct 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Addresses a defect in current functionality. service/cognitoidp Issues and PRs that pertain to the cognitoidp service.
Projects
None yet
Development

No branches or pull requests

2 participants