1

I am looking for a way to authenticate Cognito users to AWS IoT service so that a user can subscribe to an MQTT topic name as only user id (of identity pool of cognito). I do know that using a 2 step process it can be achieved.

What I don't know is a specific policy which we need to attach it to Cognito identity (a.k.a user), the policy must restrict a user to subscribe to his/her user id as MQTT topic. It implies the App can't subscribe to any other unintended topics.

Moreover, the policy needs to be dynamic (maybe using ${cognito-identity.amazonaws.com:sub} and conditions) to simplify development

It's worth noting that a user can login to multiple mobile app instances (Android and iOS) parallelly and if a user is logged in to both Android and iOS than both App instance should be able to subscribe the same topic (because user id will remain same for the same user).

Tejaskumar
  • 754
  • 8
  • 24

2 Answers2

0

Finally, I've solved. Sharing solution if it can help others. The steps are as follows:

  1. We need to attach IAM policy to authenticated users' Cognito Role. The attached policy must ALLOW operations–iot:Subscribe, iot:Connect, iot:Receive. Final policy should look as below.

    {
     "Version": "2012-10-17",
      "Statement": [
        {
        "Sid": "Stmt1232909773123",
         "Action": [
         "iot:Connect",
         "iot:Receive",
         "iot:Subscribe"
          ],
        "Effect": "Allow",
        "Resource": "*"
      }
    ]
    }
    
  2. The IoT policy which needs to be attached to identity id (of cognito) should be as below.

    {
     "Version": "2012-10-17",
     "Statement": [
      {
      "Effect": "Allow",
      "Action": "iot:Connect",
      "Resource": "arn:aws:iot:us-east-1:<account-number>:client/*"
      },
      {
      "Effect": "Allow",
      "Action": [
        "iot:Receive"
      ],
      "Resource": [
        "arn:aws:iot:us-east-1:<account-number>:topic/${cognito-identity.amazonaws.com:sub}"
      ]
     },
    {
      "Effect": "Allow",
      "Action": [
        "iot:Subscribe"
      ],
      "Resource": [
        "arn:aws:iot:us-east-1:<account-number>:topicfilter/${cognito-identity.amazonaws.com:sub}"
      ]
    }
    ] 
    }
    

NOTE: for #2, you need to put your AWS account number in policy

Tejaskumar
  • 754
  • 8
  • 24
0

Spent a lot of time on this particular issue. The documentation and error handling around variable substitution in MQTT IoT Policies are not great. The following worked for me as well. IF you're using Cognito Federated Identities, do ensure you add the IoT policy to the authenticated user role. Final note: the ${cognito-identity.amazonaws.com:sub} resolves to the identityId from Cognito developer identity, not the user-pool or JWT. At any rate, hope this helps someone else.

Cognito Authenticated Role Policy Note: this is too permissive - refine as needed.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "iot:*"
            ],
            "Effect": "Allow",
            "Resource": "*"
        }
    ]
}

MQTT IoT Policy:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "iot:Connect",
      "Resource": "arn:aws:iot:us-east-1:<account-id>:client/*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "iot:Publish",
        "iot:Receive"
      ],
      "Resource": [
        "arn:aws:iot:us-east-1:<account-id>:topic/${cognito-identity.amazonaws.com:sub}/*"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "iot:Subscribe"
      ],
      "Resource": [
        "arn:aws:iot:us-east-1:<account-id>:topicfilter/${cognito-identity.amazonaws.com:sub}/*"
      ]
    }
  ]
}
James
  • 1