Thing subscription

A “thing subscription” allows for real time access to thing data on one or more sister domains of a user. This is accomplished by giving the user privileges to subscribe to mqtt topics on the domains. This guide describes how to create the privileges needed, how to give the user the proper privileges and how to setup the mqtt connection.

The examples will use the rest API. All request require the standard authorization headers Authorization, identityId and x-api-key, but they are excluded here for the sake of brevity.

The use case

Below you can see the domain structure of this hypothetical environment. We, a user on the domain root wants to give a user on the domain userDomain access to subscribe to mqtt-topics on subscribeDomain and its subdomain subDomain.

            root
          /       \
  subscribeDomain  userDomain
        |
    subDomain

Creating the role and privilege

First we need to create a role. Send the following request to the rest API endpoint: [POST]: /permissions/roles

Body:

{
  "roleName": "subscriptionRole",
  "roleDomain": "userDomain",
  "description": "Gives thing subscription access"
}

roleDomain specifies who has access to this role. In this case it is “userDomain”. This means thas only a user that has access to “userDomain” can manage privileges for this role and add/remove the role to/from a user.

The response will be:

{
  "id": "e4d3c4a2424bb721",
  "roleName": "subscriptionRole",
  "roleDomain": "userDomain",
  "description": "Gives thing subscription access",
  "createdAt": 1539336136347,
  "updatedAt": null
}

In the response we get a generated id for the role. Make sure to save this as it will be needed later.

In order for the role to give thing subscription access, the role needs a ThingPubSub-privilege. The privilege can be created through the permissions api.

Send the following request to the rest API endpoint: [POST]: /permissions

Body:

{
  "roleId": "e4d3c4a2424bb721",
  "objectName": "ThingPubSub",
  "domains": ["subscribeDomain"],
  "read": 1
}

This request creates a privilege associated with the role “subscriptionRole” which has the id “e4d3c4a2424bb721”.

roleId specifies what role the privilege should belong to. domains specifies that we want to give access to the subscribeDomain, which implicitly also gives access to its subdomain.
objectName with value ThingPubSub specifies that we want to give the user live access to things on that domain and its subdomains. read with the value 1 specifies that we want to give read access. In this case the right to subscribe to mqtt-topics.

Note that a role can only have one privilege per object at a time.

The response will be:

{
  "id": "e4d3c4a2424bb721-ThingSubcribe-1539336136347",
  "roleId": "e4d3c4a2424bb721",
  "objectName": "domain",
  "domains": ["subscribeDomain"],
  "type": "regular",
  "create": 0,
  "read": 1,
  "update": 0,
  "delete": 0
}

create, update, delete are set to 0 by default.
The role and privilege that we need is now created. Now we are going to add this role to the user.

Adding the role to a user

Let’s say that the user that we want to give this role to is called “subscriptionUser”. The role can be added to this user through the user api.

Send a request to the rest API endpoint: [POST]: /users/subscriptionUser/roles?id=e4d3c4a2424bb721 The username is set in the path and the roleName is specified as a query parameter.

The response will be:

{
  "userName": "subscriptionUser",
  "roleId": "e4d3c4a2424bb721",
  "policyIsAttached": false
}

The attribute policyIsAttached indicates if a logged in user has been successfully updated with new real-time access to domain mqtt-topics. If true a currently logged in user will have instant access to mqtt-topics specified by the role’s ThingPubSub-privileges. Note: only ThingPubSub-privileges. If you expect immediate real-time access and policyIsAttached is false, please contact us.

Subscribing to mqtt topics

First we need to login using the regular login endpoint: [POST] /auth/login
The user should now have the iot policies attached. In order to subscribe we need to get a hold of the AWS credentials associated with the user’s identity id. They can be retrieved using the AWS SDK and the credentials received from the login response.

const cognitoIdentityPool = new aws.CognitoIdentity();
const getCredentialsParams = {
  IdentityId: loginResponse.credentials.identityId,
  Logins: {
    [`cognito-idp.${manifest.Region}.amazonaws.com/${manifest.UserPool}`]: loginResponse.credentials.token
  }
};
const cognitoResponse = await cognitoIdentityPool.getCredentialsForIdentity(getCredentialsParams).promise();

Using the aws-iot-device-sdk (https://www.npmjs.com/package/aws-iot-device-sdk) we can then use our aws credentials to subscribe to mqtt-topics.

import * as awsIot from 'aws-iot-device-sdk';
...
const props = {
      host: manifest.IotEndpointATS,
      region: manifest.Region,
      protocol: 'wss',
      clientId: 'someId',
      accessKeyId: cognitoResponse.Credentials.AccessKeyId,
      secretKey: cognitoResponse.Credentials.SecretKey,
      sessionToken: cognitoResponse.Credentials.SessionToken
    };
const broker = awsIot.device(props);

broker.on('connect', () => {
  broker.subscribe('thing-update/subscribeDomain/subDomain/#');// The thing-update topic of the subDomain
});

broker.on('message', (topic, message) => {
  // Do something with the message
})

We are now subscribed to the event mqtt topic of the subDomain. The ‘#’ at the end is a wildcard, meaning the we will get updates from all things on the subdomain (and its potencial sub domains). To subscribe to a specific thing, replace the wildcard with thingName: thing-update/subscribeDomain/subDomain/<thingName>

With a thing subscription you get access to three topics (and all “sub topics”):

event/subscribeDomain/#
thing-update/subscribeDomain/#
thing-update-delta/subscribeDomain/#