4

I am trying to make a connection between AWS IoT and my React JS APP.

I followed this tutorial (https://medium.com/serverlessguru/serverless-real-time-reactjs-app-aws-iot-mqtt-17d023954045), and it is not clear to me how to attach the Cognito Identity ID to the AWS IoT Policy.

During all my investigation, I found that this process must be done through command line.

In the article above, theses process is done by the following command line:

• Note that the “identity_pool_id” has to be considered in this command.

enter image description here

In the aws documentation (https://aws-amplify.github.io/docs/js/pubsub), it says to write the “identity_id” in the command line:

enter image description here

When I use the “identity_pool_id” in the command line, and I try to publish a message from AWS IoT, I got the following error:

enter image description here

When I use the “identity_id” in the command line, I can perform the communication between AWS IoT and the Frontend successfully:

enter image description here

The problem is that the “identity_id” is a different code for each user. Considering that I am going to have a lot of user in my application I don’t know how to perform this task.

• Am I doing the right process to consider the “identity_id” instead of “identity_pool_id”?

• If yes, how could I automatically attach the Cognito ID to the AWS IoT Policy every time I have a new user signedIn in my application?

• Are there any problem to have thousands of Cognito certificates attached in a AWS IoT Policy?

Jose Guilherme
  • 325
  • 8
  • 16

2 Answers2

1

Following answer is in chronological order corresponding to 3 questions.

  1. You can attach only identity_id (user) to IoT policy. Also, I can see you have used "attach-principal-policy" API which is deprecated now, so instead of that please use AttachPolicy API
  2. I'm unsure here, still I'd recommend to evaluate and verify it on Cognito's post confirmation trigger
  3. Absolutely right, you can attach a IoT policy to myriad of certificates; technically it is known as Simplified Permission Management

For #3, Relevant Snippet from AWS (Ref - https://aws.amazon.com/iot-core/faqs/ where find Q. What is Simplified Permission Management?)

"You can share a single generic policy for multiple devices. A generic policy can be shared among the same category of devices instead of creating a unique policy per device. For example, a policy that references the “serial-number” as a variable, can be attached to all the devices of the same model. When devices of the same serial number connect, policy variables will be automatically substituted by their serial-number."

Tejaskumar
  • 754
  • 8
  • 24
  • 2
    I'm afraid it's impossible to attach Cognito Identity on post confirmation stage (when you provide verification code). First you need to obtain an accessToken (or idToken) during sign in process and only then you are able to get Cognito Identity ID – machin Mar 19 '21 at 13:00
0

I've been searching about your second question for some time now. Here's the fix:

Given that you created the IoT Policy which grants access to the IoT services your application needs, there are three different solutions one could do:

  1. Give the iot:AttachPolicy permission for the Cognito auth role that is being assumed. Under 'ressources', give the arn of the IoT policy. In your application logic, for you the React JS app, add an API call after any successful authentication to attach the IoT policy to the current Cognito User, using the Cognito Identity ID which your application has access to.

Downside: Any user connected to the user Pool can attach the IoT policy to anything he wants. This is NOT recommended by AWS. Reason why we have this problem: the Identity ID is not accessible in the IAM policy (the {cognito-identity.amazonaws.com:sub} key does not work for this).

  1. Use Cognito post-authentication or post-confirmation triggers to trigger a lambda function which will attach the IoT Policy to the new Identity ID, as suggested in the previous answer.

Downside: When the (python) lambda function gets triggered, it seems that the cognito_identity_id in the context argument is None. The reason is that the event was triggered on the AWS side, and not directly by the React JS app's authenticated client... To fix this, the lambda function could manually call the boto3 CognitoIdentity.Client.list_identities function and check that each entity has the IoT Policy attached to itself, but even using the MaxResults argument, it doesn't seem to scale very well...

  1. The best solution seems to be creating a lambda function which attaches the IoT policy to the cognito Identity ID, present in the context argument (context.identity.cognito_identity_id), which can be done if the call to the lambda is manually done by the React JS app after authentication. The assumed Cognito Role should contain a policy with a lambda:invokefunction right on the given lambda.

Downside: the lambda function is triggered each time your app starts. But there is a fix: before triggering the lambda function, your application could make a (free-of-charge) API call to check whether the IoT policy is already attached to its current Cognito Identity ID, and if so, discard the lambda call. For this, don't forget to add a iot:ListAttachedPolicies right in the assumed Cognito Authenticated role.

Lucas Meier
  • 369
  • 3
  • 6