DEV Community

Cover image for AWS IoT - Certificate Vending
Nathan Glover
Nathan Glover

Posted on • Edited on • Originally published at devopstar.com

AWS IoT - Certificate Vending

This post was originally written on DevOpStar. Check it out here

If you've ever been through the process of setting up a new device with AWS IoT Core then you'll probably recall a sense of unease when creating new certificates for your devices. I'm an advocate of allowing people to create and manage their own devices, however a set of guardrails are needed to ensure that a level of consistency is adhered to. Because of this AWS Certificate Vending is a core part of all my projects.

In this post I'll be describing a pattern called Certificate Vending that can help create and manage a number of devices within an account in a secure & repeatable way.

AWS IoT Introduction

Creating a new AWS IoT device usually looks like this:

IoT Thing attaches to IoT Certificate which is included in an IoT Policy

  • Thing - The representation of the new device you plan to connect to AWS IoT
  • Certificate - A private and public x509 key for authenticating your device.
    • Attached to the Thing
  • Policy - Permission scope of the certificate.
    • Policy can contain one or more Certificates.

While setting up these settings in the UI is simple, it does leave room for human error. Because of this we'll be learning how to manage all this using Certificate Vending.

Certificate Vending Machine

The Certificate Vending Machine (CVM) was was originally an AWS Labs project. Overtime it hasn't been getting the love and care it deserves; with pull requests left open for months.

Note: A good portion of this code is based on the work done by brightsparc in his fork of aws-iot-certificate-vending-machine.

Certificate Vending Machine Architecture

Prerequisites

Before deploying you'll need to pull down the repository for the project

GitHub logo t04glovern / serverless-cvm

Based on awslabs/aws-iot-certificate-vending-machine; this deployment uses Serverless framework instead

Serverless Certificate Vending Machine

Based on awslabs/aws-iot-certificate-vending-machine this deployment uses Serverless framework instead

Serverless Certificate Vending Machine is a pattern for managing AWS IoT Devices in a secure and repeatable way. Learn how to deploy your own CVM and onboard new devices.

Architecture

Setup Serverless

npm install -g serverless
serverless config credentials --provider aws --key <ACCESS KEY ID> --secret <SECRET KEY>
Enter fullscreen mode Exit fullscreen mode

Requirements

serverless plugin install -n serverless-pseudo-parameters
Enter fullscreen mode Exit fullscreen mode

Add the following to the serveress.yml file

plugins:
  - serverless-pseudo-parameters
Enter fullscreen mode Exit fullscreen mode

Env File

Create a copy of env.yml.sample as env.yml and update the IOT_DATA_ENDPOINT variable with the endpoint address from the following commnad

aws iot describe-endpoint --endpoint-type iot:Data-ATS

# {
#     "endpointAddress": "XXXXXX-ats.iot.us-east-1.amazonaws.com"
# }
Enter fullscreen mode Exit fullscreen mode

Deploy

npm install
serverless deploy

# api keys:
#   None
# endpoints:
#   GET - https://XXXXXX.execute-api.us-east-1.amazonaws.com/dev/getcert
#   ANY - https://XXXXXX.execute-api.us-east-1.amazonaws.com/dev/shadow
# functions:
#   cvm: serverless-cvm-dev-cvm
# layers:
#   None
Enter fullscreen mode Exit fullscreen mode

Create Device

Replace the device token…


git clone https://github.com/t04glovern/serverless-cvm
Enter fullscreen mode Exit fullscreen mode

Also ensure you have the following:

Serverless Setup

Serverless Certificate Vending Machine (CVM) deploys using the Serverless framework. This can be setup on your local system using the following commands:

npm install -g serverless
serverless config credentials --provider aws --key {ACCESS KEY ID} --secret {SECRET KEY}
Enter fullscreen mode Exit fullscreen mode

There are a couple environment variables that are used for Certificate Vending that have to be set in a configuration file called env.yml. Make a copy of env.yml.sample as a base and then update the IOT_DATA_ENDPOINT with your Amazon Trust Services endpoint.

You can obtain your endpoint by running the following command:

aws iot describe-endpoint --endpoint-type iot:Data-ATS

# {
#     "endpointAddress": "XXXXXX-ats.iot.us-east-1.amazonaws.com"
# }
Enter fullscreen mode Exit fullscreen mode

An example of the env.yml can be seen below:

dev:
  IOT_DATA_ENDPOINT: XXXXXX-ats.iot.us-east-1.amazonaws.com
Enter fullscreen mode Exit fullscreen mode

CVM Deploy

Deploying Serverless Certificate Vending Machine is as easy as running the following:

npm install
serverless deploy

# api keys:
#   None
# endpoints:
#   GET - https://XXXXXX.execute-api.us-east-1.amazonaws.com/dev/getcert
#   ANY - https://XXXXXX.execute-api.us-east-1.amazonaws.com/dev/shadow
# functions:
#   cvm: serverless-cvm-dev-cvm
# layers:
#   None
Enter fullscreen mode Exit fullscreen mode

The output shows the endpoints used to generate certificates and update device shadows.

CVM Create Device

To create a new device we need to add a record to the DynamoDB table that manages device certificates.

  • serialNumber - Unique ID for the device being added
  • deviceToken - Secret token that will be provided later to make changes and generate certificates

Create a new device to test with by running the following command:

aws dynamodb put-item \
  --table-name iot-cvm-device-info \
  --item '{"deviceToken":{"S":"1234567890"},"serialNumber":{"S":"devopstar-iot-01"}}'
Enter fullscreen mode Exit fullscreen mode

CVM Retrieve Certificate

To retrieve the certificate details, navigate to the endpoint that follows (replace with your endpoint ID):

https://XXXXXX.execute-api.us-east-1.amazonaws.com/dev/getcert?serialNumber=devopstar-iot-01&deviceToken=1234567890
Enter fullscreen mode Exit fullscreen mode

Alternatively the following script can be used that makes use of jq to parse the response and save them to files for you

#!/bin/bash

# https://XXXXXX.execute-api.us-east-1.amazonaws.com/dev/getcert?serialNumber=devopstar-iot-01&deviceToken=1234567890
ENDPOINT_URL="$1"

# Retrieve Certs
certificates=$(curl $ENDPOINT_URL)
certificatePemCrt=$(echo $certificates | jq '.certificatePem')
certificatePemKey=$(echo $certificates | jq '.keyPair.PrivateKey')
certificateRootCa=$(echo $certificates | jq '.RootCA')

# Save to files
echo -n $certificatePemCrt | sed 's/\\n/\n/g' | sed 's/"//g' &gt; certs/iot-certificate.pem.crt
echo -n $certificatePemKey | sed 's/\\n/\n/g' | sed 's/"//g' &gt; certs/iot-private.pem.key
echo -n $certificateRootCa | sed 's/\\n/\n/g' | sed 's/"//g' &gt; certs/iot-root-ca.crt
Enter fullscreen mode Exit fullscreen mode

It can be executed with the following script and parameter:

./create_certs.sh "https://XXXXXX.execute-api.us-east-1.amazonaws.com/dev/getcert?serialNumber=devopstar-iot-01&deviceToken=1234567890"
Enter fullscreen mode Exit fullscreen mode

This will create the certs below in the certs folder

  • iot-certificate.pem.crt: certificatePem
  • iot-private.pem.key: keyPair.PrivateKey
  • iot-root-ca.crt: RootCA

These three files are all you'll need in order to connect your device to AWS IoT.

Learn More

If you're interesting in learning more or continuing on your IoT Adventure, be sure to check out some of the following tutorials that leverage this:

I encourage you to check out the course I produced on AWS IoT: The Hobbyists Guide to Home Automation

Top comments (0)