AppSync Cognito Group and Secret Access

0

I have an API with three different access modes: IAM, Cognito Users, and Cognito applications (using a secret). I am able to configure everything fine, for example, here's a field:

type SomeMutation @aws_iam @aws_cognito_user_pools {
    update(input: MutationInput!): Boolean!
    @aws_cognito_user_pools(cognito_groups: ["EDITORS"])
}

However, I'd also like to allow a specific server side application client to access this API. This is a client that has a client_id and client_secret, and can get a token using those values. If I don't limit based on groups, the calls from this client work fine, but as soon as I create a group restriction, the app client is no longer authorized. Ideally, I'd like to be able to configure the authorization as follows (by including an authorized client_id):

type SomeMutation @aws_iam @aws_cognito_user_pools {
    update(input: MutationInput!): Boolean!
    @aws_cognito_user_pools(cognito_groups: ["EDITORS"], cognito_clients: ["abcdefg"])
}

But I don't see any indication that this kind of control is possible. Will I have to write some custom authentication?

2 Answers
0

Hello,

For answering this query I would like to touch upon the usage of Cognito Userpool Groups firstly ->

  • In regards to Userpool Groups native functionality, you can use groups to control permissions to your resources using an IAM role.

  • When you create a group in Amazon Cognito, you specify an IAM role by providing the role’s ARN. When group members sign in using Amazon Cognito, they can receive temporary credentials from the identity pools.

  • Also note that individual users can be in multiple groups but you can assign precedence values to each group. The group with the better (lower) precedence will be chosen and its associated IAM role will be applied.

Please feel free to read more about the UserPool Groups on our AWS Doc here [1].

To summarize - The native functionality of Cognito Userpool groups is seen when integration Cognito Identity Pool with Userpool to determine which IAM role credentials are vended out.


Now in regards to using groups for API permission control, as you may know that a group is actually a part of ID token or access token. Hence, you can choose to decode the JWT token [2] and create a custom authorizer based on the fields you are interested in.

For example, here's an ID token with groups field ("cognito:groups") -

{
  "at_hash": "D-XXXXXXXXXXXXXXXXxOw",
  "sub": "226XXXXXXXXXXXXXXXXXXXXXXXXd",
  "cognito:groups": [
    "test1"
  ],
  "email_verified": true,
  "cognito:preferred_role": "arn:aws:iam::7XXXXXXXXXXXX:role/AdmXXXXXXXXple",
  "iss": "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_XXXXXXXXX3",
  "cognito:username": "test1",
  "cognito:roles": [
    "arn:aws:iam::7XXXXXXXXXXXX:role/AdmXXXXXXXXple"
  ],
  "aud": "3XXXXXXXXXXXXXXXXXXX",
  "token_use": "id",
  "auth_time": 1654193387,
 ....
}

Now, as you might know you can submit an ID or access tokens with requests to Amazon API Gateway and use an Amazon Cognito user pool authorizer for a REST API.

I have mentioned about the flow in detail on another RePost Query as well which you can check here.

If you are looking to use an authorization in terms of fields such as clients etc, then you want to look at Lambda authorizers [3] formerly known as custom authorizer. Basically, a Lambda authorizer is useful if you want to implement a custom authorization scheme that uses a bearer token authentication strategy such as OAuth or SAML, or that uses request parameters to determine the caller's identity.

Also please note if you are looking for any custom solution/code queries, then these are best answered by the Cognito developer team who you can reach out using Github directly.

https://github.com/aws-amplify/amplify-js/tree/master/packages/amazon-cognito-identity-js

We also have the dedicated AWS Solutions Architect team which addresses the architecture and design level queries for custom solutions. I would suggest you reach out directly to our Sales team as they can help you to get in touch with our Solutions Architect (SA) team.

You can request for a member of the sales (Business Development) team to contact you using any of the following methods:

> Via form:    	http://aws.amazon.com/contact-us/aws-sales/
> Via Live Chat:   https://pages.awscloud.com/live-chat-contact-us.html
> Phone support:   +1 (833) 662-9873 - 6:30am - 4:00pm (Pacific) Monday - Friday.

Finally, if you run into any issues while trying to implement the solution or run into any errors, please feel free to open a support case with premium support team so that you can share your AWS resources for troubleshooting. Please note that development/architectural queries go out of scope for the Premium Support team as we are only expertised in troubleshooting of break fixes and errors with the AWS service when customers run into errors during implementation phase. In cases of finding a viable solution for considering scalability, security and limitations, reaching out to the Solution Architects or Dev team can help in assessing the viability and building of the solution as per your requirements.


References:

[1] https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-user-groups.html

[2] https://aws.amazon.com/premiumsupport/knowledge-center/decode-verify-cognito-json-token/

[3] https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html

profile pictureAWS
SUPPORT ENGINEER
Yash_C
answered 2 years ago
  • That really doesn't answer the question in regards to AppSync. I understand how Cognito works, and yes, I can use my own authorization logic to validate it. My question was whether it was possible to validate both groups and application clients, but to the best of my understanding, that isn't possible.

0

I stumbled onto this posting when looking for the same exact answer. It took some digging into the Amplify docs to see all supported auth settings: https://docs.amplify.aws/javascript/tools/cli-legacy/auth-directive/

Ultimately this what I ended up doing that worked. We used a @model backed type for defining permissions. I have taken your example and adjusted it as follows:

type SomeType 
  @model
  @auth(
    rules: [
      { allow: groups, groups: ["Editors"] }
      { allow: groups, groupClaim: "scope", groups: ["api/admin"] }
    ]
  ) {
  fields ....
}

On the cognito user pool we then:

  1. created a resource group with an id of api with a custom scope of admin.
  2. Assigned this scope to the client that has a secret.
  3. Use this client id and secret to obtain a token via the token endpoint specifying the api/admin scope.
  4. Use this token to access the endpoint.

From how I understand it the groupClaim tells appsync to look into a non standard claim field for the group list. This points it the scope claim field and requires that the field contains the api/admin scope.

answered 4 months ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions