Skip to content

IoT Core MQTT WebSocket Connect Fails (AUTHORIZATION_FAILURE)

0

I'm running into a persistent issue connecting to AWS IoT Core that I can't seem to resolve — hoping someone might have some insights.

Context

I'm trying to establish an MQTT connection over WebSockets (port 443) from an Angular application to AWS IoT Core in the us-east-2 region.

Setup

  • Client: Angular app using:
    • @aws-amplify/auth (v6+)
    • aws-iot-device-sdk-v2 (v1.26.2)
  • Authentication:
    • Amazon Cognito for user auth
    • Cognito Identity Pool: us-east-2:...
    • Temporary AWS credentials obtained via WorkspaceAuthSession({ forceRefresh: true })
    • Credentials assume IAM Role: *-authenticated-role-dev
      • Role ID: AROAX...
  • MQTT Connection:
    • SigV4 authentication over WebSockets
    • clientId is dynamically set to the Cognito Identity ID

Behavior

  • I can successfully Publish messages
  • I can connect using the AWS IoT Core Test Client
  • But — the MQTT connection from my app fails consistently

CloudWatch IoT Core logs show:

eventType: Connect
protocol: MQTT
status: Failure
reason: AUTHORIZATION_FAILURE
principalId: ...:CognitoIdentityCredentials

IAM Policy Attached to Role

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

Wildcard Test Policy

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

Troubleshooting Steps Taken

  • Verified Role ID matches principalId in logs
  • Confirmed correct policy version is attached and default
  • Waited for policy propagation
  • Confirmed using SigV4 and correct MQTT clientId
  • Verified there are no Deny statements or permission boundaries

Question

Given that the IAM policy should permit iot:Connect using the Cognito Identity ID as the MQTT clientId, why is the connection still being denied?

Could there be:

  • Hidden requirements or subtleties for IoT Core auth via Cognito Identity Pools?
  • Other misconfigurations that would cause an AUTHORIZATION_FAILURE despite the above?

Any suggestions are very appreciated!

Thanks,
—Tom

1 Answer
0

Hey Tom — great breakdown of the issue, and you're definitely close. The AUTHORIZATION_FAILURE despite a seemingly correct policy is a common but tricky AWS IoT Core + Cognito Identity problem.

🔍 Root Cause Hypothesis You're dynamically setting the MQTT clientId to the Cognito Identity ID, and your policy allows:

"Resource": "arn:aws:iot:us-east-2:<account-id>:client/${cognito-identity.amazonaws.com:sub}" But here’s the key detail:

🛑 sub and the Cognito Identity ID are not the same thing.

✅ Fix: Use ${cognito-identity.amazonaws.com:identity-id} Instead of sub In IAM, the policy should use:

"Resource": "arn:aws:iot:us-east-2:<account-id>:client/${cognito-identity.amazonaws.com:identity-id}" Because the MQTT clientId is typically set to the Cognito Identity ID, not the sub from the JWT.

So your current policy is allowing only clients named after the sub, which does not match your actual clientId, hence the AUTHORIZATION_FAILURE on iot:Connect.

✅ Corrected Policy Snippet { "Effect": "Allow", "Action": "iot:Connect", "Resource": "arn:aws:iot:us-east-2:<account-id>:client/${cognito-identity.amazonaws.com:identity-id}" } And if you're using that ID in topic names too, update those as well:

"Resource": [ "arn:aws:iot:us-east-2:<account-id>:topic/your-app/${cognito-identity.amazonaws.com:identity-id}/status", "arn:aws:iot:us-east-2:<account-id>:topic/your-app/${cognito-identity.amazonaws.com:identity-id}/notifications" ], "Resource": [ "arn:aws:iot:us-east-2:<account-id>:topicfilter/your-app/${cognito-identity.amazonaws.com:identity-id}/notifications" ] 🔁 Optional: Log the Identity ID To confirm it matches: const credentials = await Auth.currentCredentials(); console.log("Identity ID:", credentials.identityId); Best regards, Muhammad Zubair https://zeonedge.com

answered a year 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.