AWS IoT - Certificate Vending
Tags: awsiot, cvm, iot, aws
Published: 2019-09-08 07:01:25

---
title: AWS IoT - Certificate Vending
published: true
description: 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.
canonical_url: https://devopstar.com/2019/09/07/aws-iot-certificate-vending/
cover_image: https://thepracticaldev.s3.amazonaws.com/i/8hbpo8oj7luctf0zrhnd.jpg
tags: aws-iot, cvm, iot, aws
---

*This post was originally written on [DevOpStar](https://devopstar.com/)*. Check it out [here](https://devopstar.com/2019/09/07/aws-iot-certificate-vending/)

If you've ever been through the process of setting up a new device with [AWS IoT Core](https://aws.amazon.com/iot/) 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](https://thepracticaldev.s3.amazonaws.com/i/cy3lhz2h7bmj55ceej8q.png)

* **Thing** - The representation of the new device you plan to connect to AWS IoT
* **Certificate** - A [private and public x509](https://docs.aws.amazon.com/iot/latest/developerguide/managing-device-certs.html) 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)](https://github.com/awslabs/aws-iot-certificate-vending-machine) 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](https://github.com/brightsparc) in his fork of aws-iot-certificate-vending-machine.*

![Certificate Vending Machine Architecture](https://thepracticaldev.s3.amazonaws.com/i/hjf62r151967d7ki58uw.png)

## Prerequisites

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

{% github t04glovern/serverless-cvm %}

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

Also ensure you have the following:

* [AWS CLI Setup](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html) & Authenticated
* [NodeJS Installed](https://nodejs.org/en/download/) & Updated

### Serverless Setup

Serverless Certificate Vending Machine (CVM) deploys using the [Serverless](https://serverless.com/) framework. This can be setup on your local system using the following commands:

```bash
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:

```bash
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:

```yaml
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:

```bash
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:

```bash
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):

```bash
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](https://stedolan.github.io/jq/) to parse the response and save them to files for you

```bash
#!/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
```

It can be executed with the following script and parameter:

```bash
./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:

* [Amazon Alexa controlled IoT Traffic Lights](https://devopstar.com/2019/03/08/amazon-alexa-controlled-iot-traffic-lights/)
* [AWS Sumerian Magic Cube](https://devopstar.com/2019/02/07/aws-sumerian-magic-cube/)
* [Create a Private VPN using AWS IoT Button, SNS & CloudFormation](https://devopstar.com/2019/01/12/create-a-private-vpn-using-aws-iot-button-sns-cloudformation/)

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/)