awslabs / aws-iot-certificate-vending-machine

The CVM allows a device to apply for its own certificate and installation.
Apache License 2.0
82 stars 16 forks source link
aws-iot cloudformation dynamodb lambda mqtt

AWS Iot Certificate Vending Machine

You can use the CVM allows the device to apply for their own certificate and installation.

README Languages: Chinese blog(中文)

Background Information

In order to ensure the secured communication between IoT devices and AWS IoT Core, Devices may use X.509 certificates to connect to AWS IoT using TLS mutual authentication protocols. AWS Cloud security mechanisms protect data as it moves between AWS IoT and other devices or AWS services.

Background

This mutual TLS authentication mode requires that a device certificate meets either of the following two conditions:

  1. The certificate used on the IoT device is issued by AWS IoT Core
  2. The CA certificate which is used to sign IoT device certificate is pre-imported into a customer’s AWS account and associated with their AWS IoT Core environment AWS understands that customers will have devices that currently do not have the ability to meet condition 1 or 2 immediately. Therefore, we have provided a reference application called, Certificate Vending Machine, which demonstrates how customers can provision devices with certificates created in AWS IoT.

When to use Certificate Vending Machine?

Certificate Vending Machine (CVM) is an ideal fit for customers who do not have certificates pre-installed on the devices and are unable to obtain CA certificates to pre-create device certificates during their manufacturing process. On this occasion, you can use CVM system which allows the device to apply for their own certificate and then install the certificate into storage on the device. This document provides the design ideas and associated source code, which can help customers quickly develop a CVM system. Since the original IoT device does not contain a certificate for TLS mutual authentication, we need to pay attention to three points.

Implementation Methodology

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

The basic workflow of the CVM system is as follows:

workflow

The architecture of CVM system is as follows:

Architecture

Using the API Gateway and Lambda solution for scalability, the detailed workflow is shown as follows:

1) When IoT device requests access to IoT platform, it triggers a certificate application to CVM system. Then IoT device sends the appropriate API calls to the API Gateway for IoT device certificate application. 2) AWS API Gateway invokes Lambda to initiate certificate request to IoT Core. 3) After receiving the request from API Gateway, Lambda checks DynamoDB to validate if the request is legitimate and applies for a certificate to the backend IoT Core. 4) The CVM system uses the AWS SDK to make a series of API calls to AWS IoT Core. These API calls perform actions such as creating a new thing in the AWS IoT Thing Registry and creating an associated device certificate. 5) AWS IoT Core generates a device certificate, key pairs and returns the certificate information and the certificate ID to CVM system. 6) Lambda uses a series of API calls to associate Thing Name, Certificate, and Policy on IoT Thing registry by querying pre-created DynamoDB association table according to product serial number. 7) Update all the associated information of the current device to DynamoDB association table 8) Lastly, the CVM system returns the certificate to the IoT devices

Security

In order to ensure the security of the CVM system, the AWS Lambda function needs to be scoped to the minimum permissions needed in order to create certificates. The following example shows how to assign the correct IAM role privilege to the CVM system.

First of all, you need to understand the CVM system needs to have the IAM authority to complete the certificate application and the issuance process.

The policy template for IAM role as follows, you should modify it more specifically for the minimum privilege.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "IoTCWlogsPolicy",
            "Effect": "Allow",
            "Action": [
                "logs:*",
                "iot:CreateThing",
                "iot:AttachPolicy",
                "iot:AttachThingPrincipal",
                "iot:CreatePolicy",
                "iot:CreateKeysAndCertificate"
            ],
            "Resource": "*"
        },
        {
            "Sid": "dynamodPolicy",
            "Effect": "Allow",
            "Action": [
                "dynamodb:Query",
                "dynamodb:UpdateItem"
            ],
            "Resource": "arn:aws:dynamodb:REGION:123456789012:table/TableName"
        }
    ]
}

Secondly, you need to allow lambda assume this role by adding trust relationship.

policy

In addition to the IAM authority division, you need to create an association table on DynamoDB for the binding relationship between the device, the certificate and policy. Specifically, you need to create the following database fields in DynamoDB:

How do I deploy this?

1. Deploy the CVM to your AWS account

The solution is available as a AWS CloudFormation SAM template, and included in this repository (template.yml). Click the following button to deploy it to your AWS account in the us-east-1 region:

cloudformation-launch-stack

You will need to provide some parameters to point AWS Lambda.

When the cloudformation CREATE_COMPLETE, you can see the output of Cloudformation.

[cloudformation-stack-output]

2. Add Sample Device Data to your Device Dynamodb

You must create item in your device dynamodb table, or you will see access deny.

[Add Sample Data about serialNumber & deviceToken ]

3. Use output API Gateway Link to invoke your CVM

Please use the link from the first step. https://XXXXX.execute-api.us-east-1.amazonaws.com/PROD/getcert?serialNumber=ascas&deviceToken=zxcz

Code Description

The following CVM system reference source code uses the IoT interface provided by the AWS Node.js SDK to complete the certificate request and add the associated Thing Name and Policy.

// Create cert
  iot.createKeysAndCertificate(params, function(err, certdata) {
    console.log("certdata:");
    console.log(certdata);

    if (err) console.log(err, err.stack); // an error occurred
    else{

       // Create IoT Policy for above cert
       var params = {
        policyDocument: config.PILICY_DOCUMENT, /* required */
        policyName: serialNumber /* required */
      };
      iot.createPolicy(params, function(err, data) {
        if (err) console.log(err, err.stack); // an error occurred
        else{
          console.log(data);

          // Attach policy for cert
          var params = {
            policyName: serialNumber, /* required */
            target: certdata.certificateArn /* required */
          };
          iot.attachPolicy(params, function(err, data) {

Reference Link:

http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Iot.html

License

This library is licensed under the Apache 2.0 License.