Using Beam with Multiple Credentials

Introduction

Soracom Beam allows you to easily send data from a device to cloud services over a cellular connection. Beam allows you to offload encryption workloads from the device to the cloud and avoid data overhead associated with common encrypted protocols, while still maintaining end-to-end encryption. Beam also lets you manage data transfer endpoints in the cloud so that your device does not need to be reconfigured when you make a change on your backend.

For more information on Soracom Beam, take a look at the Beam documentation .

When using Beam to transfer data to AWS IoT Core, device authentication is handled using X.509 certificates. Typically, these certificates would be installed directly the device, with each device receiving its own unique set of credentials. Although this process is straightforward, it presents a number of challenges at scale, such as the manual process of generating and installing large numbers of credentials, and additional work to revoke and re-provision credentials in case a certificate is compromised.

Just as Soracom Beam allows you to offload encryption duties to the cloud, Beam can also handle credential management. In a basic use case, you can easily add your IoT Core credentials to Beam in order to accept data from your device, encrypt it, and forward it to IoT Core. Beam takes care of the authentication process with IoT Core, all without installing any certificates on the device.

While Beam will take care of encryption and authentication between Soracom and AWS, data transfer between your device and Soracom is secured using SIM authentication and encryption mechanisms built into cellular networks.

By default, Beam will only allow you to associate one set of X.509 certificates in an entry point configuration, which establishes a one-certificate to many-devices relationship. As AWS IoT Core can apply different access policies to each device certificate, you may prefer a one-certificate to one-device association instead. We can actually achieve this behavior very easily with one configuration change.

In this guide, we'll cover how to configure Beam to programmatically handle multiple credentials in order to MQTT data from multiple devices to AWS IoT Core. Let's get started!

Prerequisites

This guide assumes that you are familiar with the basics of AWS, as well as how to configure your IoT device to publish MQTT messages.

We recommend reviewing the Beam to AWS IoT Core guide , as most of the AWS IoT Core and Soracom Beam setup is the same.

In addition to the prerequisites of the Beam to AWS IoT Core guide, you will need the following:

Goal

Once we have completed this guide, we can add multiple X.509 certificates to Soracom Beam. When our devices send MQTT data to Beam, Beam will then take a look at which SIM card is sending the data in order to determine which set of credentials to use, then connect to AWS IoT Core to send the data.


Configure AWS IoT Core

Follow the steps in the Beam to AWS IoT Core guide Configure AWS IoT Core section for configuring AWS IoT Core, repeating the instructions so that you create two sets of things, credentials, and policies.

For each set, let's attach two different policies so that we can verify later that our credentials are correctly associated with our two devices:

Make sure to replace the AWS region and AWS account number with your values in the policy statements below!

Device 1

Device 1 will use a certificate that is associated with a policy that allows it full access to IoT Core, including publishing and subscribing to any topic.

Device 2

Device 2 will use a certificate that is associated with a policy that limits what it can do on IoT Core. Specifically, it will only be able to publish to the beamtest topic, and cannot subscribe to any topics.


Forwarding Destination

Once you have set up two sets of devices, don't forget to also make a note of your IoT Core Custom endpoint. Follow the instructions in the Beam to AWS IoT Core guide Find the Forwarding Destionation section, as we will need it next.


Configure Soracom Beam

The first part of configuring Beam is quite similar to the Beam configuration instructions of the Beam to AWS IoT Core guide, with just a few small changes to make things easier. Let's get Beam set up initially for Device 1.

We'll need the following files handy:

1. Create an Air SIM group

Although we can reuse an existing group, let's create a new group since we're going to do some custom configuration later.

Your Air SIM will now be added to this group. You should see your group in the Group column for the Air SIM.

2. Add a Beam Configuration

Let's open the group in order to set up Beam. You can either click the name of the group from the SIM Management page, or from the Groups page.

The certificate will automatically be selected for the Beam configuration.

Finally, click Save to save the configuration.

3. Enable Multi-Credential Usage

As you can probably guess, we will organize our credential sets (the sets of X.509 certificates from IoT Core) using an IMSI number that corresponds to the SIM card in each device. Beam understands which SIM is sending data, and therefore can simply switch between different credential sets, as long as they are named appropriately.

Of course, our current Beam configuration is still set to our device-295000012345678 credentials, which is statically set. To configure Beam to automatically replace the numbers with the IMSI of the SIM that is sending data, we need to replace the number with a placeholder variable. Beam lets us use the placeholder #{imsi} inside the credential set ID, which will then enable the dynamic credential selection.

To change device-295000012345678 to device-#{imsi}, we need to use the Soracom API to apply a custom group configuration.

You can also use the Soracom CLI to perform the configuration, if you prefer to work in the command line instead of through API.

The API should return a response in the Response section, containing JSON data about the group.

Look through the group data to find the MQTT entry point configuration. It should look something like this:

    "mqtt://beam.soracom.io:1883": {
      "enabled": true,
      "name": "MQTT",
      "addEquipmentHeader": false,
      "addSignature": false,
      "addSubscriberHeader": false,
      "customHeaders": {},
      "skipStatusCode": false,
      "useClientCert": true,
      "clientCerts": {
        "default": {
          "$credentialsId": "device-295000012345678"
        }
      },
      "useGoogleIoT": false,
      "useClientCredentials": false,
      "addDeviceIdHeader": false,
      "destination": "mqtts://abcd0012345678-ats.iot.us-east-2.amazonaws.com:8883"
    }

Now we can change device-295000012345678 into device-#{imsi}!

          "$credentialsId": "device-#{imsi}"

However, before we send the updated config back to the API, we need to modify the JSON structure a little, because the putConfigurationParameters API requires a key/value data format.

You can find more information on how to format MQTT entry point parameters here: MQTT Entry Point | SORACOM Developers

Your final config should look like this:

[
  {
    "key": "mqtt://beam.soracom.io:1883",
    "value": {
      "enabled": true,
      "name": "MQTT",
      "addEquipmentHeader": false,
      "addSignature": false,
      "addSubscriberHeader": false,
      "customHeaders": {},
      "skipStatusCode": false,
      "useClientCert": true,
      "clientCerts": {
        "default": {
          "$credentialsId": "device-#{imsi}"
        }
      },
      "useGoogleIoT": false,
      "addDeviceIdHeader": false,
        "destination": "mqtts://abcd0012345678-ats.iot.us-east-2.amazonaws.com:8883"
    }
  }
]

If you are copying and pasting, make sure to change the destination parameter to your AWS IoT Core custom endpoint. You may also need to change the $credentialsId parameter if you are using a different naming scheme.

If you received a response code of 200, all went well and your Beam configuration is now set up to handle multiple credentials.

If you see an error, you may need to double-check the formatting of the JSON config.


4. Add More Credentials

Although we have now configured Beam to handle multiple credentials, we still haven't registered the X.509 certificates from Device 2! Fortunately this process is very quick.

The dialog for registering the X.509 credentials from Device 2 mostly the same from earlier. Just remember to follow the device-#{imsi} format for the Credentials set ID.

You can repeat this process for as many devices as you'd like, and even explore the Credential createCredential API for adding new credentials programmatically.

Now with multiple credentials ready, it's time to test!


Testing Device 1

Let's test using a Raspberry Pi, since the mosquitto-clients package will provide some helpful output. If you haven't already, install the package using the following command:

sudo apt-get install mosquitto-clients

Now let's monitor the messages on AWS IoT Core by opening the Test area from our browser, and subscribing to the beamtest topic.

First, let's check that publishing to beamtest works:

mosquitto_pub -d -h beam.soracom.io -t beamtest -m 'Hello, world!'
>Sending CONNECT
>Received CONNACK (0)
>Sending PUBLISH (d0, q0, r0, m1, 'beamtest', ... (13 bytes))
>Sending DISCONNECT

No surprises there. How about publishing on a different topic? Let's subscribe to the a/different/topic topic in our browser. Then on the Raspberry Pi:

mosquitto_pub -d -h beam.soracom.io -t 'a/different/topic' -m 'So, we meet again'
>Sending CONNECT
>Received CONNACK (0)
>Sending PUBLISH (d0, q0, r0, m1, 'a/different/topic', ... (17 bytes))
>Sending DISCONNECT

Great! It looks like Device 1 should be able to publish to any topic.

Now let's try subscribing to a topic and publishing a message from IoT Core.

mosquitto_sub -d -h beam.soracom.io -t 'let/me/know'
>Sending CONNECT
>Received CONNACK (0)
>Sending SUBSCRIBE (Mid: 1, Topic: let/me/know, QoS: 0)
>Received SUBACK
>Subscribed (mid: 1): 0

Then from IoT Core's Test section, we can publish a message to the let/me/know topic, and we should see it arrive on our Pi:

>Received PUBLISH (d0, q0, r0, m0, 'let/me/know', ... (21 bytes))
>Hello from the cloud!

Looking good!


Testing Device 2

Let's run the same tests again with Device 2. Because Device 2 has our second SIM, Beam will use the AWS IoT Core credentials that are associated with its IMSI. In turn, IoT Core will apply the stricter policy that we set up at the beginning.

First up, publishing to beamtest:

mosquitto_pub -d -h beam.soracom.io -t beamtest -m 'Hello, again!'
>Sending CONNECT
>Received CONNACK (0)
>Sending PUBLISH (d0, q0, r0, m1, 'beamtest', ... (13 bytes))
>Sending DISCONNECT

Still good! Next, a topic that is not allowed in the stricter policy:

mosquitto_pub -d -h beam.soracom.io -t 'a/different/topic' -m 'Can you hear me?'
>Sending CONNECT
>Received CONNACK (0)
>Sending PUBLISH (d0, q0, r0, m1, 'a/different/topic', ... (16 bytes))
>Sending DISCONNECT

Nope, our message does not arrive at IoT Core, as we would expect. Note that from the device perspective, the publish was still successful, because the device was able to connect to Beam and publish the message. However, as our stricter IoT Core policy does not allow publishing to other topics, the message does not get past Beam.

Last, let's try subscribing:

mosquitto_sub -d -h beam.soracom.io -t 'let/me/know'
>Sending CONNECT
>Received CONNACK (0)
>Sending SUBSCRIBE (Mid: 1, Topic: let/me/know, QoS: 0)
>Sending CONNECT
>Received CONNACK (0)
>Sending SUBSCRIBE (Mid: 2, Topic: let/me/know, QoS: 0)
>Sending CONNECT
>Received CONNACK (0)
>Sending SUBSCRIBE (Mid: 3, Topic: let/me/know, QoS: 0)

Looks like our mosquitto_sub client can't stay connected. Indeed, when Beam tries to subscribe using Device 2's credentials, AWS IoT Core is rejecting the request and closing the connection. Beam then closes the connection accordingly, which means our multi-credential configuration is working as intended!


Conclusion

Congratulations, you've successfully published an MQTT message to AWS IoT Core through Soracom Beam. On top of that, you're set up to support multiple devices. Notice that we didn't need to store any of the AWS IoT Core endpoint details or certificates on the devices. Since the connection between the device and Soracom's cloud is encrypted over cellular, we just had to configure the hop between Soracom and AWS. This means that devices can be deployed at scale without having to worry about managing credentials, endpoints, or compute resources needed to manage cryptographic handshakes.