• 6 min read

Navigating AWS IoT Core MQTT with Cognito Identity Pools


cover image


Integrating real-time messaging between frontend and backend services is a key requirement for many modern applications. AWS IoT Core with MQTT provides a robust solution for such communication needs, especially in Internet of Things (IoT) scenarios.


However, configuring AWS IoT Core with Cognito Identity Pools can be complex, particularly when dealing with authenticated and unauthenticated roles. This guide explores the setup process, common issues, and troubleshooting steps for using AWS IoT Core MQTT with a React application, along with a detailed look at the application’s architecture.


Application Architecture Overview

  • Frontend: React Application

Hosting: The React application is hosted using AWS S3 and distributed via CloudFront for low latency and high availability.


AWS Amplify: The frontend leverages AWS Amplify for streamlined interactions with AWS services, including authentication via Cognito and messaging via IoT Core MQTT.


Communication: The React app communicates with the backend over HTTPS, ensuring secure data transmission between the client and server.


  • Backend: Python Application using AWS CDK

API Gateway: The backend uses AWS API Gateway to expose RESTful endpoints that facilitate communication with the frontend. It acts as the entry point for all API requests from the React application.


Lambda Integrations: AWS Lambda functions are used to process requests and execute backend logic, offering a serverless approach that scales automatically with demand.


Real-Time Messaging: MQTT is employed to notify the frontend when specific events occur, such as when a user payment is processed. This real-time capability allows dynamic updates to the website, such as removing a paywall once a payment is confirmed.


Deployment Context

Multiple websites, particularly video streaming landing pages, are deployed using this architecture. They all interact with the same backend to maintain consistency and reduce redundancy.


AWS IoT Core with MQTT is used for real-time messaging, crucial for delivering instant feedback to users, such as payment confirmations.


Setting Up AWS IoT Core with Cognito Identity Pools

Cognito Identity Pools manage user identities and provide access to AWS services based on the assigned roles. In this setup, both authenticated and unauthenticated roles were configured, each with permissions to connect, subscribe, receive, and manage policies within AWS IoT Core.


Cognito Identity Pools: These pools handle user identities and allocate permissions to AWS services. Both authenticated and unauthenticated roles are set up in the Identity Pool.


Permissions: Roles are granted permissions (iot:Connect, iot:Subscribe, iot:Receive, iot:AttachPrincipalPolicy) required for interacting with AWS IoT Core.


Authenticated vs. Unauthenticated Roles: The unauthenticated role allows users to connect without logging in, while the authenticated role is used for logged-in users via Cognito User Pools.


Common Issue: AUTHORIZATION_FAILURE with Authenticated Roles

A frequent issue in this configuration is the failure of the authenticated role to connect, resulting in an AUTHORIZATION_FAILURE error, despite seemingly correct permissions. This issue typically does not affect the unauthenticated role, which functions as expected.


Problem Analysis:


The failure occurs because the authenticated user’s identity does not have a specific IoT Core policy directly attached.


Although both roles share similar permissions, the authenticated role requires the IoT policy to be explicitly linked to the identity for MQTT connections to work correctly.


Step-by-Step Solution

To resolve this, an IoT Core policy must be attached to the authenticated identity. The steps below outline how this can be achieved:


Retrieving the Cognito Identity ID: Obtaining the Cognito Identity ID is necessary to attach the IoT Core policy to the authenticated user. This ID is passed to the backend for further processing.


Attaching the IoT Core Policy Using AWS Lambda: A Lambda function can be employed to attach the IoT Core policy to the authenticated identity using AWS SDK (boto3). This enables the correct permissions dynamically when required.


Example Lambda Function:


import boto3

def attach_iot_policy(event, context):
    iot = boto3.client('iot')
    cognito_identity_id = event['identity_id']
    policy_name = 'YourIoTPolicy'
    
    response = iot.attach_policy(
        policyName=policy_name,
        target=cognito_identity_id
    )
    return response

Updating Permissions: Ensure that the authenticated role includes the iot:AttachPrincipalPolicy permission, which allows the policy to be attached to the identity. This permission is essential; without it, the Lambda function will fail, causing continued authorization errors.


Validation and Testing: After applying these configurations, thorough testing should confirm that both authenticated and unauthenticated users can connect to AWS IoT Core MQTT successfully.


Best Practices and Recommendations

Role Permissions Management: Check the permissions associated with each role carefully. Authenticated roles, in particular, need an IoT policy directly attached to the user identity for MQTT communication.


Using AWS Amplify with PubSub: AWS Amplify can simplify the process, but it’s important to manage identity roles and policies meticulously, especially when dealing with authenticated and unauthenticated users across shared browser sessions.


Debugging Authorization Failures: Authorization failures usually signal missing permissions or improperly attached policies. Reviewing role policies and ensuring correct attachment procedures are vital.


Policy Management: Utilize AWS IAM and IoT policies efficiently to manage access, aligning roles with the necessary permissions to avoid unnecessary overhead and potential security risks.


Conclusion

Navigating AWS services like IoT Core and Cognito can be intricate, especially when integrating real-time messaging and role-based access. For organizations looking to simplify this process, expert guidance can make a significant difference. Perfsys offers tailored services to help you build MVPs, transition to AWS serverless, set up custom SSO solutions, and develop new services on AWS from scratch.


Contact Perfsys today to explore how we can assist in accelerating your cloud projects and streamline your AWS journey!

Navigating AWS IoT Core MQTT with Cognito Identity Pools

Anastasiia Tokareva

Software Engineer