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:
- Two (2) Air SIM devices which can publish MQTT messages, or alternatively one (1) Air SIM device as well as one (1) additional Soracom Air SIM card
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
-
Thing configuration:
- Name - Any name you like
- Security - A set of X.509 certificates:
xxxx-certificate.pem.crt
certificatexxxx-private.pem.key
private key- The Root CA for AWS IoT certificate
-
Policy configuration:
- Name -
PubSubToAnyTopic
, or another name you prefer - Statements - the following policy statement:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "*", "Resource": "*" } ] }
- Name -
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
-
Thing configuration:
- Name - Any name you like
- Security - A set of X.509 certificates:
yyyy-certificate.pem.crt
certificateyyyy-private.pem.key
private key- The Root CA for AWS IoT certificate
-
Policy configuration:
- Name -
PubSubBeamtest
, or another name you prefer - Statements - the following policy statement:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "iot:Connect" ], "Resource": "arn:aws:iot:us-east-2:900012345678:*" }, { "Effect": "Allow", "Action": [ "iot:Publish" ], "Resource": "arn:aws:iot:us-east-2:900012345678:topic/beamtest" } ] }
- Name -
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:
- Our Device 1 X.509 certificate,
xxxx-certificate.pem.crt
- Our Device 1 X.509 private key,
xxxx-private.pem.key
- The Root CA for AWS IoT certificate
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.
- From the User Console, click the Menu icon and select SIM Management.
-
Find the Air SIMs in the list that correspond to Device 1 and Device 2, and click the to select both of them. Then click the Actions menu, and select Change group.
-
Click the Group dropdown and select Create group.... Enter a name for your group, such as
beam-to-aws-iot-multi
, then click Create. Finally, click Change Group.
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.
-
From the group settings page, click the SORACOM Beam panel.
-
Click the + button to add a new configuration, and select MQTT entry point.
-
Enter the following Destination settings:
- Type - Standard MQTT broker
- Protocol - MQTTS
- Host name - Our AWS IoT Core custom endpoint from earlier
- Port number -
8883
-
Next, we need to provide our X.509 certificate from Device 1. Click to enable Client cert, then click the + button to add the certificate.
-
Enter the Name
device-295000012345678
, replacing the IMSI with the IMSI of the SIM card used in Device 1, for this set of credentials, then copy and paste the contents of the device private key, device certificate, and Root CA for AWS IoT certificate into the corresponding fields.By naming this credential set using the IMSI of the SIM card that is used in the device, changing it later to a template will be very intuitive.
Click Register to save the certificate.
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.
-
While we're still on the Group settings page, make a note of the ID. We need this so that we know which group to configure in the API.
-
Open the Soracom Developers API Reference tool .
-
Obtain an API token by logging in using your Soracom Email address and Password, or alternatively your Auth Key ID and Secret if you have configured one.
Once you have obtained an API token, make sure to set the coverage region that applies to your SIM cards:
-
Scroll to or open the Group getGroup API. Enter the Group ID from earlier into the group_id request parameter, then click Try.
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.
-
Now let's take this updated config and pass it back to the API. Scroll to or open the Group putConfigurationParameters API. Enter the following request parameters:
group_id
- The Group ID from earliernamespace
-SoracomBeam
parameters
- The updated JSON config above
Then click Try.
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.
-
Click your account menu, then select Security.
-
Click the Credentials tab, then click Register a credentials set.
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.