The Internet of Things on AWS – Official Blog

Using AWS IoT Device Management in a Retail Scenario to Process Order Requests

In this blog post, we will simulate a common business scenario to show you how to use the group policy feature in AWS IoT Device Management. Specifically, we will describe:

  • How to create a hierarchical group structure and assign your IoT devices to different groups.
  • How to publish messages to different IoT devices based on their group-based policy.

 

Scenario

We’ll use an example of a retail shop in Seattle that publishes an order request to an IoT device gateway. The gateway sends the order message to AWS IoT Core for processing, and AWS IoT Core publishes the order message to the factory in San Francisco.

In this scenario, we will use AWS IoT Device Management to manage the fleet of IoT gateways in Seattle and the fleet of manufacturing equipment in San Francisco.

Each group will be assigned different policies.

  • For the Seattle group, devices can publish their message only through specific topics. They cannot publish information about any other shop. The Seattle group will not receive messages from AWS IoT Core.
  • For the San Francisco group, devices can subscribe only to messages designated for San Francisco. This means those devices can’t receive messages from another factory.

 

 

Notes

  • Before you begin, be aware that a group is hierarchical. You must define your parent group and child group carefully. The parent group cannot be changed after it’s created. You cannot move a group to a different parent group.
  • According to the group policy inheritance, the devices in the child groups inherit the policy of their parent group, so you must design your group hierarchy and policy inheritance carefully. In general, as a best practice, the parent group should have the least permissive group policy. Add more specific permissions to the child groups. Because of policy inheritance, if there is a conflict between the parent group and child group (for example, if there is both an Allow statement and a Deny statement on the same resource), then the action will be explicitly denied. Keep this in mind when you create your group policy tree.

 

Group configuration example

1.     Sign in to the AWS Management Console, and open the AWS IoT console. You’ll find the new Groups option under Manage. You can use the console or the following CLI commands to create a new group. For our scenario, we will first create a parent group, US, and then create two child groups, Seattle and San Francisco. You need to add two child groups into their partner group, US, and verify your group hierarchy.

# Create Parent Group#

aws iot create-thing-group --thing-group-name 'US'

# Create Child Group and Assign to Parent Group

aws iot create-thing-group --thing-group-name 'Seattle' --parent-group-name 'US'
aws iot create-thing-group --thing-group-name 'San_Francisco' --parent-group-name 'US'

2.     For our scenario, we will create two things: SeattleThing1 and SanFranciscoThing1. Each thing will be added to the thing registry and assigned to its named group. You need to attach a certificate to your newly created thing so that it can connect to the device gateway through MQTT TLS 1.2. You can use your own certificate or you can use the AWS IoT Core CA. In this example, we will use the AWS IoT Core CA to assign a new certificate to each thing.

# Create a new IoT thing#

aws iot create-thing --thing-name SeattleThing1
aws iot create-thing --thing-name SanFranciscoThing1

# Create certificate and set it as active status

# Create certificate for SeattleThing1

aws iot create-keys-and-certificate --set-as-active

# Create certificate for SanFranciscoThing1

aws iot create-keys-and-certificate --set-as-active

# Attach certificate to IoT thing

aws iot attach-thing-principal --thing-name SeattleThing1 --principal <Certificate ARN>
aws iot attach-thing-principal --thing-name SanFranciscoThing1 --principal <Certificate ARN>

# Add IoT thing to group#

aws iot add-thing-to-thing-group --thing-name SeattleThing1 --thing-group-name Seattle
aws iot add-thing-to-thing-group --thing-name SanFranciscoThing1 --thing-group-name San_Francisco

3.     Before the release of AWS IoT Device Management, you needed to attach a policy to an individual certificate and manage the policy separately. Now you can attach the policy to a group instead of individual certificates. We will create the policies based on different group assignments. The Seattle group is only allowed to publish to the Seattle order status topic, and the San Francisco group is only allowed to subscribe to the order process topic from AWS IoT Core. You can use the console or the following command to create the policies.

aws iot create-policy --policy-name <Policy Name>--policy-document <Policy Value>

a.     For the US group, we will use the least permissive policies, which only allow devices to connect to AWS IoT Core without any publish/subscribe process.

{
    "Version": "2012-10-17",
    "Statement": [
     {
       "Effect": "Allow",
       "Action": "iot:Connect",
       "Resource": "arn:aws:iot:ap-northeast-1:XXXXXXXXXXXX:client/${iot:ClientId}"
     }
   ]
}

b.     For the Seattle group, we will use the following policy:

{
    "Version": "2012-10-17",
    "Statement": [
     {
      "Effect": "Allow",
      "Action": "iot:Publish",
      "Resource": "arn:aws:iot:ap-northeast-1:XXXXXXXXXXXX:topic/Seattle/${iot:Connection.Thing.ThingName}/*"
     }
   ]
}

c.     For the San Francisco group, we will use the following policy:

{
    "Version": "2012-10-17",
    "Statement": [
     {
       "Effect": "Allow",
       "Action": "iot:Subscribe",
       "Resource": "arn:aws:iot:ap-northeast-1:XXXXXXXXXXXX:topicfilter/San_Francisco/*"
     },
     {
       "Effect": "Allow",
       "Action": "iot:Receive",
       "Resource": "arn:aws:iot:ap-northeast-1:XXXXXXXXXXXX:topic/San_Francisco/${iot:Connection.Thing.ThingName}/*"
     }
   ]
}

4.     After the policies are created, you can attach each policy to a different group individually. You can use the console or the following CLI command to attach a policy to a group.

aws iot attach-policy --target <Thing Group Arn> --policy-name <Policy Name>

5.     After the three policies are attached, you can build your order request system. In this scenario, we will use MQTT.fx to act as an MQTT client (it represents the shop in Seattle and the factory in San Francisco) to connect to AWS IoT Core.

6.     Now, let’s get to the fun part. We can simulate the shop receiving the order in Seattle, and then any factory in San Francisco processing the order request process system using the IoT rule. We can create an IoT rule to select the OrderNumber attribute from Seattle/SeattleThing1/OrderStatus topic and republish to the San_Francisco/SanFranciscoThing1/ProcessOrder topic. In this way, the order request from the Seattle shop will be proceeded by the San Francisco factory. You need to create a rule action so that the message can be republished to the San Francisco topic. For information about the rules engine, see Rules for AWS IoT in the AWS IoT Developer Guide. You can use the console or the following CLI command to create an IoT rule:

aws iot create-topic-rule –rule-name <Rule Name> --topic-rule-payload <Rule Value>

7.     You can now publish an order message from the Seattle shop by using the MQTT.fx client.

8.     The IoT rule will select the OrderNumber attribute in this message and republish to the San Francisco factory device. You will receive the result from MQTT.fx San Francisco device.

Appendix

When you attach a policy to a group, that policy is applied to all devices in the group. We recommend that you use the TestAuthorization API to test your policy locally so that you do not impact real devices in your production environment. You can use the following command to simulate the expected result.

1.     First, use the following command to verify the current attached policy for your group:

#Use the following command to verify the current effective policy on your thing, which only has one group policy attached#

aws iot test-authorization --auth-infos "[{\"actionType\": \"CONNECT\", \"resources\":[<Thing ARN>]}, {\"actionType\": \"PUBLISH\", \"resources\": [<Topic ARN>\"]}]" --client-id <Thing Name> --principal <certificate-ARN>

The following shows the output of the command. As you can see, “CONNECT” is an allowed action, and “PUBLISH” is denied.

{
    "authResults": [
     {
       "authDecision": "ALLOWED",
       "authInfo": {
       "actionType": "CONNECT",
       "resources": [
          "arn:aws:iot:ap-northeast-1:XXXXXXXXXXX:client/SeattleThing1"
        ]
      },
     "denied": {
       "implicitDeny": {
          "policies": []
        },
     "explicitDeny": {
       "policies": []
        }
      },
      "missingContextValues": [],
       "allowed": {
         "policies": [
          {
            "policyName": "GroupManagement-US",
            "policyArn": "arn:aws:iot:ap-northeast-1:XXXXXXXXXXX:policy/GroupManagement-US"
          }
        ]
        }
      },
      {
       "authDecision": "IMPLICIT_DENY",
       "authInfo": {
         "actionType": "PUBLISH",
         "resources": [
            "arn:aws:iot:ap-northeast-1:XXXXXXXXXXX:topic/Seattle/SeattleThing1"
           ]
       },
       "denied": {
         "implicitDeny": {
            "policies": [
             {
                "policyName": "GroupManagement-US",
                "policyArn": "arn:aws:iot:ap-northeast-1:XXXXXXXXXXX:policy/GroupManagement-US"
             }
           ]
         },
       "explicitDeny": {
         "policies": []
         }
       },
       "missingContextValues": [],
           "allowed": {
               "policies": []
              }
          }
     ]
}

2.     Before you attach a new group policy for the same group, use the following command to verify the result for this new policy:

#Use the following command to verify the result after new group policy attached#

aws iot test-authorization --auth-infos "[{\"actionType\": \"CONNECT\", \"resources\": [<Thing ARN>]}, {\"actionType\": \"PUBLISH\", \"resources\": [<Topic ARN>]}]" --client-id <Thing Name> --principal <certificate-ARN> --policy-names-to-add "[<New Group Policy Name>]"

The following shows the output of the command. As you can see, both “CONNECT” and “PUBLISH” are allowed actions.

{
    "authResults": [
      {
        "authDecision": "ALLOWED",
        "authInfo": {
            "actionType": "CONNECT",
            "resources": [
                "arn:aws:iot:ap-northeast-1: XXXXXXXXXXX:client/SeattleThing1"
             ]
         },
     "denied": {
        "implicitDeny": {
            "policies": [
              {
                "policyName": "GroupManagement-Seattle",
                "policyArn": "arn:aws:iot:ap-northeast-1:XXXXXXXXXXX:policy/GroupManagement-Seattle"
              }
             ]
        },
     "explicitDeny": {
        "policies": []
        }
      },
     "missingContextValues": [],
        "allowed": {
            "policies": [
              {
                "policyName": "GroupManagement-US",
                "policyArn": "arn:aws:iot:ap-northeast-1:XXXXXXXXXXX:policy/GroupManagement-US"
              }
            ]
         }
      },
      {
     "authDecision": "ALLOWED",
        "authInfo": {
            "actionType": "PUBLISH",
            "resources": [
                "arn:aws:iot:ap-northeast-1:XXXXXXXXXXXX:topic/Seattle/SeattleThing1"
            ]
        },
     "denied": {
        "implicitDeny": {
            "policies": [
             {
                "policyName": "GroupManagement-US",
                "policyArn": "arn:aws:iot:ap-northeast-1:XXXXXXXXXXX:policy/GroupManagement-US"
             }
             ]
        },
     "explicitDeny": {
        "policies": []
      }
      },
      "missingContextValues": [],
        "allowed": {
            "policies": [
             {
                "policyName": "GroupManagement-Seattle",
                "policyArn": "arn:aws:iot:ap-northeast-1:XXXXXXXXXXX:policy/GroupManagement-Seattle"
             }
             ]
        }
      }
   ]
}

Reference links:

·      Thing Groups in the AWS IoT Developer Guide

·      AWS IoT Policies in the AWS IoT Developer Guide

·      Rules for AWS IoT in the AWS IoT Developer Guide

·      MQTT.fx download page