1

I'm using the Serverless Framework to deploy my Lambdas to CloudFormation, and the guide https://serverless-stack.com to bootstrap my project.

Upon running a test of my API, I get the following error in the console

"Invalid identity pool configuration. Check assigned IAM roles for this pool."

This question ( AWS Cognito Invalid identity pool configuration ) led me to check my Trust Relationships, and they are the same ID, so I've ruled out this as my problem.

I've tried to ping this API using the following method:

$ npx aws-api-gateway-cli-test \
--username='admin@example.com' \
--password='Passw0rd!' \
--user-pool-id='YOUR_COGNITO_USER_POOL_ID' \
--app-client-id='YOUR_COGNITO_APP_CLIENT_ID' \
--cognito-region='YOUR_COGNITO_REGION' \
--identity-pool-id='YOUR_IDENTITY_POOL_ID' \
--invoke-url='YOUR_API_GATEWAY_URL' \
--api-gateway-region='YOUR_API_GATEWAY_REGION' \
--path-template='/client' \
--method='GET' 

and I get the same error.

Also I should note that I can connect to this MYSQL instance in MYSQL Workbench without issues.

This is my serverless.yml.

In the guide, they have the iamRoleStatements uncommented. I am unsure how to modify these for my MYSQL instance.


service: myservice

# Create an optimized package for our functions
package:
  individually: true

app: my-app

provider:
  name: aws
  runtime: nodejs8.10
  region: us-east-2
  memorySize: 256
  timeout: 30

  # 'iamRoleStatements' defines the permission policy for the Lambda function.
  # In this case Lambda functions are granted with permissions to access DynamoDB.
 # iamRoleStatements:
 #   - Effect: Allow
 #     Action:
 #       - dynamodb:DescribeTable
 #       - dynamodb:Query
 #       - dynamodb:Scan
 #       - dynamodb:GetItem
 #       - dynamodb:PutItem
 #       - dynamodb:UpdateItem
 #      - dynamodb:DeleteItem
 #    Resource: "arn:aws:dynamodb:us-east-1:*:*"

  vpc:
    securityGroupIds:
      - SGID
    subnetIds:
      - subnet1
      - subnet2
      - subnet3
  environment:
    MYSQLHOST: 'HOST'
    MYSQLPORT: 'PORT'
    MYSQLUSER: 'USER'
    MYSQLPASS: 'PASS'
    MYSQLDATABASE: 'DATABSE'

functions:  
  clientFunc:
    handler: client.handler
    events:
      - http:
          path: client
          method: get
          cors: true
          authorizer: aws_iam
      - http:
          path: client/{id}
          method: get
          cors: true
          authorizer: aws_iam
      - http:
          path: client
          method: post
          cors: true
          authorizer: aws_iam
      - http:
          path: client/{id}
          method: put
          cors: true
          authorizer: aws_iam
      - http:
          path: client/{id}
          method: delete
          cors: true
          authorizer: aws_iam

plugins:
  - serverless-offline

  # Create our resources with separate CloudFormation templates
resources: 
  - ${file(resources/api-gateway-errors.yml)}

I'm a beginner with AWS, any help would be appreciated, thanks.

UPDATE:

When I login with a user on my app, I get this response from a network call to AWS cognito

IdentityId: "us-east-2:t0cc2567-8d82-4ba4-9d06-065179256373"

My Authenticated role for my Identity pool has the following trust relationship, but the error still appears.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "cognito-identity.amazonaws.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "cognito-identity.amazonaws.com:aud": "t0cc2567-8d82-4ba4-9d06-065179256373"
        },
        "ForAnyValue:StringLike": {
          "cognito-identity.amazonaws.com:amr": "unauthenticated"
        }
      }
    }
  ]
}
Kevin Tran
  • 137
  • 1
  • 8
  • I am a hundred percent sure the issue lies with trust relationships. I would implore you to try running Identity Pool CLI commands (getId and getIdentity), and let me know the results for the same. – Arka Mukherjee Sep 16 '19 at 05:44
  • Can you direct me to the documentation for these CLI commands? I'm unsure which ones you're talking about. – Kevin Tran Sep 16 '19 at 15:38
  • Try [this](https://docs.aws.amazon.com/cli/latest/reference/cognito-identity/get-id.html) – Arka Mukherjee Sep 16 '19 at 16:25
  • I entered this into my terminal: `aws cognito-identity get-id --identity-pool-id us-east-2:IDENTITY_POOL_ID` and I got An error occurred (NotAuthorizedException) when calling the GetId operation: Unauthenticated access is not supported for this identity pool. – Kevin Tran Sep 16 '19 at 17:28
  • That clearly means you have configured Identity Pool IAM roles incorrectly. Kindly refer to the official documentations, and fix it as necessary. You would need to select the "Tick mark" beside the "Allow Unauthenticated Access" checkbox. Or provide a relevant Logins Map in the API call. – Arka Mukherjee Sep 16 '19 at 18:17
  • I understand that but I have a hard time navigating the documentation and understanding the concepts of how each AWS service works together. I'm a total AWS beginner, but I like Dev-Ops and I want to learn more. The functionality I'm attempting to replicate for my application is similar to this guide [https://serverless-stack.com/] except the database for mine is a RDS Mysql instance, and instead of exporting functions as direct interfaces to a db, I have separate functions which run express.js instances to route CRUD for each table in the database. Can I screenshare you? please – Kevin Tran Sep 17 '19 at 01:16
  • @ArkaMukherjee I've tried some more things, including editing the trust permissions to use a specific user, as well as using the identity pool id. From what I understand, my Identity Pool has permissions to execute my API, and my Lambda has permissions to query my RDS. I'm really not sure what I'm doing wrong! – Kevin Tran Sep 17 '19 at 05:14

2 Answers2

1

I encountered the same error, in my case I was using terraform and when defining my resources I forgot to attach the authenticated IAM role to the identity pool. You do this by defining an aws_cognito_identity_pool_roles_attachment. In the UI its hard to miss: there is a big button reminding you to do it, but in terraform it is easy to forget to include a resource. This was my final configuration, you can compare with yours if you are using terraform:

# Cognito:
#
# Define the cognito federated identity pool for end-user access and the
# user pool for running regression tests.

resource "aws_cognito_identity_pool" "myaws" {
  identity_pool_name               = "myaws"
  allow_unauthenticated_identities = false
  allow_classic_flow               = false

  cognito_identity_providers {
    client_id               = aws_cognito_user_pool_client.myaws.id
    provider_name           = aws_cognito_user_pool.myaws.endpoint
    server_side_token_check = false
  }

  openid_connect_provider_arns = [
    aws_iam_openid_connect_provider.firebase.arn
  ]
}

resource "aws_iam_openid_connect_provider" "firebase" {
  url             = "https://securetoken.google.com/myawsdev"
  client_id_list  = [
    "myawsdev"
  ]
  thumbprint_list = [
    "08745487e891c19e3078c1f2a07e452950ef36f6"
  ]
}

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

  roles = {
    "authenticated" = aws_iam_role.Cognito_myawsAuth_Role.arn
  }
}

resource "aws_cognito_user_pool" "myaws" {
  name = "MyawsUserPool"

  password_policy {
    minimum_length                   = 8
    require_lowercase                = false
    require_numbers                  = false
    require_symbols                  = false
    require_uppercase                = false
    temporary_password_validity_days = 1
  }

  username_configuration {
    case_sensitive = false
  }

  admin_create_user_config {
    # This user pool is to create test accounts in integration tests.
    # To prevent real users/attackers from ever using it we require
    # developer perms to create accounts.
    allow_admin_create_user_only = true
  }
}

The role is defined as:

resource "aws_iam_role" "Cognito_myawsAuth_Role" {
  name = "Cognito_myawsAuth_Role"

  assume_role_policy = <<EOF
{   
    "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.myaws.id}"
                },
                "ForAnyValue:StringLike": {
                    "cognito-identity.amazonaws.com:amr": "authenticated"
                }
            }
        }
    ]
}
EOF
}

resource "aws_iam_policy" "CognitoAccess" {
  name = "CognitoAccess"
  
  policy = <<EOF
{   
    "Version": "2012-10-17",
    "Statement": [
        {   
            "Effect": "Allow",
            "Action": [
                "mobileanalytics:PutEvents",
                "cognito-sync:*",
                "cognito-identity:*"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}
EOF
}

resource "aws_iam_role_policy_attachment" "Cognito_myawsAuth_Role-CognitoAccess" {
  role       = aws_iam_role.Cognito_myawsAuth_Role.name
  policy_arn = aws_iam_policy.CognitoAccess.arn
}
Necro
  • 521
  • 5
  • 10
  • `aws_cognito_identity_pool_roles_attachment` and the `statement` for federation were key and not apparent in other locations. Thanks! – Howard Lince III Apr 28 '22 at 04:44
0

I know it's a year and half too but it might be helpful for someone in the future. I had a similar issue Indeed it was a trust policy issue. I am also a newbie and I am made the same obvious mistake as above. If your

"cognito-identity.amazonaws.com:aud": "Your Identity Pool Id"

references the correct identity pool. Then the next issue is this line

"cognito-identity.amazonaws.com:amr": "unauthenticated"

it should be "unauthenticated" for the unauth role and "authenticated" for auth role