Is it possible to control which paths in apigateway a cognito user is allowed to call?

Hi.

Ive noticed that I can put my users into groups. Is there an easy way to let some users access admin paths in apigateway and have “normal” users only be able to access other paths?

I have this working with a custom authenticator but Im working on switching to use cognito instead.

Regards Obiwan.

And if it can be configured in serverless that would be most excelent =)

The short answer is Yes.

  1. For each of your Cognito User Groups with custom permissions you need to create an IAM role.
  2. In your Cognito user pool groups you need to set the role ARN for the group to use.
  3. In the Cognito Identity Pool you should already have an “Authenticated role” which will be our default or fallback role for users not in a group with a role assigned.
  4. Under Authentication providers > Cognito > Authenticated role selection you want to change the selection from “use default role” to “choose role from token” and set Role resolution to "Use default Authenticated role"
    this says "Use the role from the Cognito user pool group unless there isn’t one, in that case use the default role defined above
  5. In your serverless.yml file you can define the authorizer to be AIM for api gateway endpoints like so
    functionName
      events:
        - http:
            authorizer: aws_iam
    
    You can read more about that here
  6. Back to those roles, you have a default role defined in the Cognito Identity pool, this is your fallback role that any user will be given unless a group assigns a different role or you ask for a different one when you call GetCredentialsForIdentity (see note 2). Then you have the roles you assigned to groups in the Cognito User Pool. It’s time to attach policies to those roles.
  7. In an AIM policy you can specify what API gateway routes can be invoked. You can read up here about how to specify routes and methods in the policy.
  8. I recommend making an “all users” policy and then a policy for the default role and a policy for each group role. Attach the “all users” policy to the default role and all the group roles, attach the default policy to the default role, then attach each group policy to each group role. This is needed because if you have a role assigned from a group is excludes you from having the default role. So any permissions applied in the default policy would not be applied to the group roles (hence the need for the “all users” policy).

Things to keep in mind:

  1. If a user is in multiple groups the precedent attribute determines which role is applied. User groups docs
  2. You CAN request any of the roles a user is allowed to use when you call GetCredentialsForIdentity but that’s probably not needed in your case.
8 Likes

Thank you! Super helpful, worked for me, and so much simpler than a custom authorizer for my use case. One question, is it possible to configure those identity pool settings in CloudFormation?

I followed these steps exactly. And then I obtained the access token as a response from the aws cognito-idp admin-initiate-auth cli call. When I pass the access token as a value for the Authorization header to make a request to an API Gateway endpoint, I get the following response:

“message”: “Authorization header requires ‘Credential’ parameter. Authorization header requires ‘Signature’ parameter. Authorization header requires ‘SignedHeaders’ parameter. Authorization header requires existence of either a ‘X-Amz-Date’ or a ‘Date’ header…”

I have the same issue here. Not sure what I need to do to resolve it.

This is not a direct answer but definitely related. When using an ‘aws_iam’ authorizer, I could not use a simple sessionToken as my Authorization header, and had to sign my Authorization header using AWS Signature V4.

See this section in the serverless tutorial [Connect to API Gateway with IAM Auth | Serverless Stack]
Also, see this SO post that helped me https://stackoverflow.com/questions/49545475/serverless-api-gateway-aws-iam-angular-5-signing-request