The Internet of Things on AWS – Official Blog

Ensure Secure Communication with AWS IoT Core Using the Certificate Vending Machine Reference Application

X.509 certificates are used to ensure secure communication between IoT devices and AWS IoT Core. Devices use these certificates to connect to AWS IoT Core using TLS mutual authentication. AWS IoT Core uses TLS mutual authentication to encrypt data as it moves between AWS IoT Core and other devices or other AWS services.

A X.509 certificate installed on devices must meet either of the following conditions:

  • It must be issued by AWS IoT Core.
  • The CA certificate used to sign an IoT device certificate must have already been imported into your AWS account and associated with your AWS IoT implementation

Because we understand that you have devices that do not meet these conditions, we provide a reference application called Certificate Vending Machine (CVM) to demonstrate how you can provision devices with certificates created in AWS IoT Core. This blog post provides the design ideas and associated source code to help you get started with CVM.

Who should use CVM?

Certificate Vending Machine is ideal for those who do not have certificates preinstalled on devices and cannot use CA certificates to provision device certificates during the manufacturing process. You can use CVM to allow the device to apply for its own certificate. Because the IoT device in our example does not have a certificate for TLS mutual authentication, we need to pay attention to three points:

·       To prevent a man-in-middle attack when devices and CVM are communicating, the server certificate should be used to validate the authenticity of the endpoint. Specifically, when generating device certificates, there must be secured communication, such as TLS tunnel or IPsec VPN, between the device and CVM.

·      An IoT device that requests a certificate should have a unique identifier, such as a serial number, client ID, or product ID that will be used for policy binding and to ensure that the device is valid.

·      All certificates submitted by CVM are AWS IoT Core certificates. If you need to use a custom CA certificate, you can use bulk provisioning. For more information, see the Just-in-Time Registration of Device Certificates on AWS IoT blog post.


Implementation methodology

The CVM implementation can be divided into three modules: IoT devices, CVM server, and AWS IoT Core.

  • IoT device
    • Requests a device certificate via HTTPS connection.
    • Submits the device serial number and the registration token when requested. The registration token is a one-time token to avoid device serial number spoofing.
  • CVM server
    • Provides remote access to IoT devices for certificate application.
    • Generates secured certificate for each IoT device that can be used to communicate to AWS IoT Core.
    • Uses DynamoDB to store information such as the device ID, key registration information, and the applied device certificate.
    • Associates IoT thing name, certificate policy, and certificate ID by querying the association table in DynamoDB. In parallel, CVM modifies the certificate status attribute in DynamoDB to ensure that a device can only register for a single active certificate.
  • AWS IoT Core
    • Generates the certificate and private key pair that is then vended to an individual IoT device.


Here is the basic CVM workflow:

Here is the CVM architecture:


Using Amazon API Gateway and AWS Lambda for scalability, here is the workflow:

  1. When the IoT device requests access to AWS IoT Core, it triggers a certificate application to CVM. The IoT device sends an API call to API Gateway for IoT device certificate application.
  2. API Gateway invokes Lambda to initiate a certificate request to AWS IoT Core.
  3. After it receives the request from API Gateway, Lambda checks Amazon DynamoDB to validate the request is legitimate and then applies to AWS IoT Core for a certificate.
  4. CVM uses the AWS SDK to make a series of API calls to AWS IoT Core. These API calls perform actions such as creating a thing in the registry and creating an associated device certificate.
  5. AWS IoT Core generates a device certificate and key pairs and returns the certificate information and the certificate ID to CVM.
  6. Lambda uses a series of API calls to associate the thing name, certificate, and policy on AWS IoT Core by querying a DynamoDB association table according to product serial number.
  7. AWS Lambda updates the DynamoDB association table with information for the current device.
  8. CVM returns the certificate to the IoT device.



To ensure the security of CVM, the AWS Lambda function must be scoped to the minimum permissions required to create a device in AWS IoT Core. To complete the certificate application and the issuance process, CVM must have IAM permissions to:

  • Access DynamoDB for querying, modifying, and updating device associations in the DynamoDB table.
  • Access AWS IoT Core to request X.509 certificates and attach IoT policies to certificates.


The following steps show how to assign the correct IAM role permissions to CVM. Here is the policy example for the IAM role with restricted permission for CVM only.


     "Version": "2012-10-17",
     "Statement": [
        "Sid": "IoTCWlogsPolicy",
        "Effect": "Allow",
        "Action": [
        "Resource": "*"
        "Sid": "cvmDynamodbPolicy",
        "Effect": "Allow",
        "Action": [
       "Resource": "arn:aws:dynamodb:us-west-2:xxxxxxxxxxxx:table/{table_name}"

Now add a trust relationship so that AWS Lambda can assume this role.

You need to create an association table in DynamoDB for the binding relationship between the device, certificate, and policy. Specifically, you need to create the following database fields in DynamoDB:

  • Product ID: IoT device ID
  • Access token: IoT token
  • timestamp: certificate request timestamp
  • applyState: request status (if the certificate is set to -1, it means that the device has already registered the certificate)
  • certID: certificate ID associated with the device

This table will be used to record all device certificate application progress to ensure only an authorized device is able to apply for a device certificate.


Code description

The following CVM reference source code uses the AWS IoT Core interface provided by the  AWS SDK for JavaScript in Node.js to complete the certificate request and add the associated thing name and policy.


//Use createKeysAndCertificate to create certificate,This API will response certificate and certificate ID

iot.createKeysAndCertificate (params = {}, callback) ⇒ AWS.Request

# if CSR is in use, you can use following API call

# iot.createCertificateFromCsr(params = {}, callback) ⇒ AWS.Request

//Attach policy to current certificate

iot.attachPrincipalPolicy(params = {}, callback) ⇒ AWS.Request

//Attach IoT thing name to current certificat

iot.attachThingPrincipal(params = {}, callback) ⇒ AWS.Request



You’ll find the source code for CVM in GitHub using the following link:



By using CVM, you can deploy device certificates on existing IoT devices so that those devices can connect to IoT platform easily and securely. We hope you found the information and code in this post helpful. Feel free to leave questions or other feedback in the comments.



AWS SDK for JavaScript