September 07, 2019     5min read

AWS IoT - Certificate Vending


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
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
Certificate Vending Machine Architecture

Prerequisites

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

git clone https://github.com/t04glovern/serverless-cvm

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}

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"
# }

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

dev:
  IOT_DATA_ENDPOINT: XXXXXX-ats.iot.us-east-1.amazonaws.com

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

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"}}'

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

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' > certs/iot-certificate.pem.crt
echo -n $certificatePemKey | sed 's/\\n/\n/g' | sed 's/"//g' > certs/iot-private.pem.key
echo -n $certificateRootCa | sed 's/\\n/\n/g' | sed 's/"//g' > certs/iot-root-ca.crt

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"

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

https://www.udemy.com/aws-iot-automation/
https://www.udemy.com/aws-iot-automation/