groffcole
groffcole

Reputation: 881

Using CloudFormation, how can I create an Identity Pool that authorizes based on User Pool roles?

I'm using Serverless Framework to handle my CloudFormation stuff. I'm building a User Pool with groups that have their own roles. I want to build my Identity Pool so that the Cognito provider setting for Authenticated role selection is set to Choose role from token with a Role resolultion of DENY.

This is my relevant CloudFormation - ignore the ${self:custom....} stuff:

    IdentityPool:
      Type: AWS::Cognito::IdentityPool
      Properties:
        IdentityPoolName: ${self:custom.identityPoolName}
        AllowUnauthenticatedIdentities: false
        CognitoIdentityProviders:
          - ClientId:
              Ref: UserPoolClient
            ProviderName:
              Fn::GetAtt: ["UserPool", "ProviderName"]

    IdentityPoolRoleAttachment:
      Type: AWS::Cognito::IdentityPoolRoleAttachment
      Properties:
        IdentityPoolId:
          Ref: IdentityPool
        RoleMappings:
          CognitoProvider:
            IdentityProvider:
              Fn::Join:
                - ""
                - - "cognito-idp."
                  - Ref: AWS::Region
                  - ".amazonaws.com/"
                  - Ref: UserPool
                  - ":"
                  - Ref: UserPoolClient
            Type: Token
            AmbiguousRoleResolution: Deny

This does_not work because the IdentityPoolRoleAttachment is requiring a Roles section. But I do_not want to use the authenticated and unauthenticated roles with the Identity Pool. I want the Identity Pool Cognito provider to only check the tokens being passed in.

This is the error I'm getting:

 ServerlessError: An error occurred: IdentityPoolRoleAttachment - 1 validation error detected: Value null at 'roles' failed to satisfy constraint: Member must not be null (Service: AmazonCognitoIdentity; Status Code: 400; Error Code: ValidationException; Request ID: 80026230-eaa9-4045-86d8-6fe4c07cce9d).

How can I do this? Do I need to create an empty role and assigned it to the IdentityPoolRoleAttachment?

I am able to do this without Identity Pool roles in the console.

Upvotes: 4

Views: 1068

Answers (1)

lipeiran
lipeiran

Reputation: 696

I was able to get this working without creating an empty role. roles is not required according to doc but it seems like CFN cant handle null well.

you just need to set "roles": { }.

cdk code

new CfnIdentityPoolRoleAttachment(
    this,
    'ExampleCognitoIdentityPoolRoleAttachment',
    {
        identityPoolId: identityPool.ref,
        roles: {},
        roleMappings: {
            mapping: {
                type: 'Token',
                ambiguousRoleResolution: 'Deny',
                identityProvider: `cognito-idp.${cdk.Stack.of(this).region}.amazonaws.com/${userPool.userPoolId}:${cognitoAppClient.ref}`,
            },
        },
    },
);

Cloudformation template output from cdk

"ExampleCognitoIdentityPoolRoleAttachment": {
    "Type": "AWS::Cognito::IdentityPoolRoleAttachment",
        "Properties": {
        "IdentityPoolId": {
            "Ref": "ExampleCognitoIdentityPool"
        },
        "RoleMappings": {
            "mapping": {
                "AmbiguousRoleResolution": "Deny",
                    "IdentityProvider": {
                    "Fn::Join": [
                        "",
                        [
                            "cognito-idp.eu-west-1.amazonaws.com/",
                            {
                                "Ref": "<UserPoolRef>"
                            },
                            ":",
                            {
                                "Ref": "<UserPoolAppClientRef>"
                            }
                        ]
                    ]
                },
                "Type": "Token"
            }
        },
        "Roles": { }
    },
    "Metadata": {
        "aws:cdk:path": "example-stack/ExampleCognitoIdentityPoolRoleAttachment"
    }
}

Upvotes: 1

Related Questions