

# Device provisioning
<a name="iot-provision"></a>

AWS provides several different ways to provision a device and install unique client certificates on it. This section describes each way and how to select the best one for your IoT solution. These options are described in detail in the whitepaper titled [Device Manufacturing and Provisioning with X.509 Certificates in AWS IoT Core](https://docs.aws.amazon.com/whitepapers/latest/device-manufacturing-provisioning/device-manufacturing-provisioning.html). 

**Select the option that fits your situation best**
+ 

**You can install certificates on IoT devices before they are delivered**  
If you can securely install unique client certificates on your IoT devices before they are delivered for use by the end user, you want to use [*just-in-time* provisioning (JITP)](jit-provisioning.md) or [*just-in-time* registration (JITR)](auto-register-device-cert.md).

  Using JITP and JITR, the certificate authority (CA) used to sign the device certificate is registered with AWS IoT and is recognized by AWS IoT when the device first connects. The device is provisioned in AWS IoT on its first connection using the details of its provisioning template.

  For more information on single thing, JITP, JITR, and bulk provisioning of devices that have unique certificates, see [Provisioning devices that have device certificates](provision-w-cert.md).
+ 

**End users or installers can use an app to install certificates on their IoT devices**  
If you cannot securely install unique client certificates on your IoT device before they are delivered to the end user, but the end user or an installer can use an app to register the devices and install the unique device certificates, you want to use the [provisioning by trusted user](provision-wo-cert.md#trusted-user) process.

  Using a trusted user, such as an end user or an installer with a known account, can simplify the device manufacturing process. Instead of a unique client certificate, devices have a temporary certificate that enables the device to connect to AWS IoT for only 5 minutes. During that 5-minute window, the trusted user obtains a unique client certificate with a longer life and installs it on the device. The limited life of the claim certificate minimizes the risk of a compromised certificate.

  For more information, see [Provisioning by trusted user](provision-wo-cert.md#trusted-user).
+ 

**End users CANNOT use an app to install certificates on their IoT devices**  
If neither of the previous options will work in your IoT solution, the [provisioning by claim](provision-wo-cert.md#claim-based) process is an option. With this process, your IoT devices have a claim certificate that is shared by other devices in the fleet. The first time a device connects with a claim certificate, AWS IoT registers the device using its provisioning template and issues the device its unique client certificate for subsequent access to AWS IoT.

   This option enables automatic provisioning of a device when it connects to AWS IoT, but could present a larger risk in the event of a compromised claim certificate. If a claim certificate becomes compromised, you can deactivate the certificate. Deactivating the claim certificate prevents all devices with that claim certificate from being registered in the future. However; deactivating the claim certificate does not block devices that have already been provisioned.

  For more information, see [Provisioning by claim](provision-wo-cert.md#claim-based).

## Provisioning devices in AWS IoT
<a name="provisioning-in-iot"></a>

When you provision a device with AWS IoT, you must create resources so your devices and AWS IoT can communicate securely. Other resources can be created to help you manage your device fleet. The following resources can be created during the provisioning process: 
+ An IoT thing.

  IoT things are entries in the AWS IoT device registry. Each thing has a unique name and set of attributes, and is associated with a physical device. Things can be defined using a thing type or grouped into thing groups. For more information, see [Managing devices with AWS IoT](iot-thing-management.md).

   Although not required, creating a thing makes it possible to manage your device fleet more effectively by searching for devices by thing type, thing group, and thing attributes. For more information, see [Fleet indexing](iot-indexing.md).
**Note**  
To index your Thing's connectivity status data, provision your Thing and configure it so the Thing name matches the client ID used on the Connect request.
+ An X.509 certificate.

  Devices use X.509 certificates to perform mutual authentication with AWS IoT. You can register an existing certificate or have AWS IoT generate and register a new certificate for you. You associate a certificate with a device by attaching it to the thing that represents the device. You must also copy the certificate and associated private key onto the device. Devices present the certificate when connecting to AWS IoT. For more information, see [Authentication](authentication.md).
+ An IoT policy.

  IoT policies define the operations that a device can perform in AWS IoT. IoT policies are attached to device certificates. When a device presents the certificate to AWS IoT, it is granted the permissions specified in the policy. For more information, see [Authorization](iot-authorization.md). Each device needs a certificate to communicate with AWS IoT.

AWS IoT supports automated fleet provisioning using provisioning templates. Provisioning templates describe the resources AWS IoT requires to provision your device. Templates contain variables that enable you to use one template to provision multiple devices. When you provision a device, you specify values for the variables specific to the device using a dictionary or *map*. To provision another device, specify new values in the dictionary.

You can use automated provisioning whether or not your devices have unique certificates (and their associated private key).

## Fleet provisioning APIs
<a name="provisioning-apis"></a>

There are several categories of APIs used in fleet provisioning:
+ These control plane functions create and manage the fleet provisioning templates and configure trusted user policies.
  + [CreateProvisioningTemplate](https://docs.aws.amazon.com/iot/latest/apireference/API_CreateProvisioningTemplate.html)
  + [ CreateProvisioningTemplateVersion](https://docs.aws.amazon.com/iot/latest/apireference/API_CreateProvisioningTemplateVersion.html)
  + [DeleteProvisioningTemplate](https://docs.aws.amazon.com/iot/latest/apireference/API_DeleteProvisioningTemplate.html)
  + [DeleteProvisioningTemplateVersion](https://docs.aws.amazon.com/iot/latest/apireference/API_DeleteProvisioningTemplateVersion.html)
  + [DescribeProvisioningTemplate](https://docs.aws.amazon.com/iot/latest/apireference/API_DescribeProvisioningTemplate.html)
  + [DescribeProvisioningTemplateVersion](https://docs.aws.amazon.com/iot/latest/apireference/API_DescribeProvisioningTemplateVersion.html)
  + [ListProvisioningTemplates](https://docs.aws.amazon.com/iot/latest/apireference/API_ListProvisioningTemplates.html)
  + [ListProvisioningTemplateVersions](https://docs.aws.amazon.com/iot/latest/apireference/API_ListProvisioningTemplateVersions.html)
  + [UpdateProvisioningTemplate](https://docs.aws.amazon.com/iot/latest/apireference/API_UpdateProvisioningTemplate.html)
+ Trusted users can use this control plane function to generate a temporary onboarding claim. This temporary claim is passed to the device during Wi-Fi configuration or a similar method.
  + [CreateProvisioningClaim](https://docs.aws.amazon.com/iot/latest/apireference/API_CreateProvisioningClaim.html)
+ The MQTT API used during the provisioning process by devices with a provisioning claim certificate embedded in a device, or passed to it by a trusted user.
  + [CreateCertificateFromCsr](fleet-provision-api.md#create-cert-csr)
  + [CreateKeysAndCertificate](fleet-provision-api.md#create-keys-cert)
  + [RegisterThing](fleet-provision-api.md#register-thing)

# Provisioning devices that don't have device certificates using fleet provisioning
<a name="provision-wo-cert"></a>

By using AWS IoT fleet provisioning, AWS IoT can generate and securely deliver device certificates and private keys to your devices when they connect to AWS IoT for the first time. AWS IoT provides client certificates that are signed by the Amazon Root certificate authority (CA).

There are two ways to use fleet provisioning:
+ [Provisioning by claim](#claim-based)
+ [Provisioning by trusted user](#trusted-user)

## Provisioning by claim
<a name="claim-based"></a>

Devices can be manufactured with a provisioning claim certificate and private key (which are special purpose credentials) embedded in them. If these certificates are registered with AWS IoT, the service can exchange them for unique device certificates that the device can use for regular operations. This process includes the following steps:

**Before you deliver the device**

1. Call [https://docs.aws.amazon.com//iot/latest/apireference/API_CreateProvisioningTemplate.html](https://docs.aws.amazon.com//iot/latest/apireference/API_CreateProvisioningTemplate.html) to create a provisioning template. This API returns a template ARN. For more information, see [Device provisioning MQTT API](fleet-provision-api.md).

   You can also create a fleet provisioning template in the AWS IoT console. 

   1. From the navigation pane, choose the **Connect many devices** dropdown. Then, choose **Connect many devices**.

   1. Choose **Create provisioning template**.

   1. Choose the **Provisioning scenario** that best fits your installation processes. Then, choose **Next**.

   1. Complete the template workflow.

1. Create certificates and associated private keys to be used as provisioning claim certificates.

1. Register these certificates with AWS IoT and associate an IoT policy that restricts the use of the certificates. The following example IoT policy restricts the use of the certificate associated with this policy to provisioning devices.  
****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "iot:Connect"
               ],
               "Resource": "*"
           },
           {
               "Effect": "Allow",
               "Action": [
                   "iot:Publish",
                   "iot:Receive"
               ],
               "Resource": [
               "arn:aws:iot:us-east-1:123456789012:topic/$aws/certificates/create/*",
       "arn:aws:iot:us-east-1:123456789012:topic/$aws/provisioning-templates/templateName/provision/*"
               ]
           },
           {
               "Effect": "Allow",
               "Action": "iot:Subscribe",
               "Resource": [
               "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/certificates/create/*",
       "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/provisioning-templates/templateName/provision/*"
               ]
           }
       ]
   }
   ```

1. Give the AWS IoT service permission to create or update IoT resources such as things and certificates in your account when provisioning devices. Do this by attaching the `AWSIoTThingsRegistration` managed policy to an IAM role (called the provisioning role) that trusts the AWS IoT service principal.

1. Manufacture the device with the provisioning claim certificate securely embedded in it.

The device is now ready to be delivered to where it will be installed for use.

**Important**  
Provisioning claim private keys should be secured at all times, including on the device. We recommend that you use AWS IoT CloudWatch metrics and logs to monitor for indications of misuse. If you detect misuse, turn off the provisioning claim certificate so it cannot be used for device provisioning.

**To initialize the device for use**

1. The device uses the [AWS IoT Device SDKs, Mobile SDKs, and AWS IoT Device Client](iot-sdks.md) to connect to and authenticate with AWS IoT using the provisioning claim certificate that is installed on the device.
**Note**  
For security, the `certificateOwnershipToken` returned by `CreateCertificateFromCsr` and `CreateKeysAndCertificate` expires after one hour. `RegisterThing` must be called before the `certificateOwnershipToken` expires. If the certificate created by `CreateCertificateFromCsr` or `CreateKeysAndCertificate` has not been activated and has not been attached to a policy or a thing by the time the token expires, the certificate is deleted. If the token expires, the device can call `CreateCertificateFromCsr` or `CreateKeysAndCertificate` again to generate a new certificate.

1. The device obtains a permanent certificate and private key by using one of these options. The device will use the certificate and key for all future authentication with AWS IoT.

   1. Call [`CreateKeysAndCertificate`](fleet-provision-api.md#create-keys-cert) to create a new certificate and private key using the AWS certificate authority.

      Or

   1. Call [`CreateCertificateFromCsr`](fleet-provision-api.md#create-cert-csr) to generate a certificate from a certificate signing request that keeps its private key secure.

1. From the device, call [`RegisterThing`](fleet-provision-api.md#register-thing) to register the device with AWS IoT and create cloud resources.

   The Fleet Provisioning service uses a provisioning template to define and create cloud resources such as IoT things. The template can specify attributes and groups that the thing belongs to. The thing groups must exist before the new thing can be added to them.

1. After saving the permanent certificate on the device, the device must disconnect from the session that it initiated with the provisioning claim certificate and reconnect using the permanent certificate. 

The device is now ready to communicate normally with AWS IoT.

## Provisioning by trusted user
<a name="trusted-user"></a>

In many cases, a device connects to AWS IoT for the first time when a trusted user, such as an end user or installation technician, uses a mobile app to configure the device in its deployed location.

**Important**  
You must manage the trusted user's access and permission to perform this procedure. One way to do this is to provide and maintain an account for the trusted user that authenticates them and grants them access to the AWS IoT features and API operations required to perform this procedure. 

**Before you deliver the device**

1. Call [https://docs.aws.amazon.com//iot/latest/apireference/API_CreateProvisioningTemplate.html](https://docs.aws.amazon.com//iot/latest/apireference/API_CreateProvisioningTemplate.html) to create a provisioning template and return its *templateArn* and *templateName*.

1. Create an IAM role that is used by a trusted user to initiate the provisioning process. The provisioning template allows only that user to provision a device. For example:

   ```
   {
       "Effect": "Allow",
       "Action": [
           "iot:CreateProvisioningClaim"
       ],
       "Resource": [
           "arn:aws:iot:aws-region:aws-account-id:provisioningtemplate/templateName"
       ]
   }
   ```

1. Give the AWS IoT service permission to create or update IoT resources, such as things and certificates in your account when provisioning devices. You do this by attaching the `AWSIoTThingsRegistration` managed policy to an IAM role (called the *provisioning role*) that trusts the AWS IoT service principal.

1. Provide the means to identify your trusted users, such as by providing them with an account that can authenticate them and authorize their interactions with the AWS API operations necessary to register their devices.

**To initialize the device for use**

1. A trusted user signs in to your provisioning mobile app or web service.

1. The mobile app or web application uses the IAM role and calls [https://docs.aws.amazon.com//iot/latest/apireference/API_CreateProvisioningClaim.html](https://docs.aws.amazon.com//iot/latest/apireference/API_CreateProvisioningClaim.html) to obtain a temporary provisioning claim certificate from AWS IoT.
**Note**  
For security, the temporary provisioning claim certificate that `CreateProvisioningClaim` returns expires after five minutes. The following steps must successfully return a valid certificate before the temporary provisioning claim certificate expires. Temporary provisioning claim certificates do not appear in your account's list of certificates.

1. The mobile app or web application supplies the temporary provisioning claim certificate to the device along with any required configuration information, such as Wi-Fi credentials.

1. The device uses the temporary provisioning claim certificate to connect to AWS IoT using the [AWS IoT Device SDKs, Mobile SDKs, and AWS IoT Device Client](iot-sdks.md).

1. The device obtains a permanent certificate and private key by using one of these options within five minutes of connecting to AWS IoT with the temporary provisioning claim certificate. The device will use the certificate and key these options return for all future authentication with AWS IoT.

   1. Call [`CreateKeysAndCertificate`](fleet-provision-api.md#create-keys-cert) to create a new certificate and private key using the AWS certificate authority.

      Or

   1. Call [`CreateCertificateFromCsr`](fleet-provision-api.md#create-cert-csr) to generate a certificate from a certificate signing request that keeps its private key secure.
**Note**  
Remember [`CreateKeysAndCertificate`](fleet-provision-api.md#create-keys-cert) or [`CreateCertificateFromCsr`](fleet-provision-api.md#create-cert-csr) must return a valid certificate within five minutes of connecting to AWS IoT with the temporary provisioning claim certificate.

1. The device calls [`RegisterThing`](fleet-provision-api.md#register-thing) to register the device with AWS IoT and create cloud resources. 

   The Fleet Provisioning service uses a provisioning template to define and create cloud resources such as IoT things. The template can specify attributes and groups that the thing belongs to. The thing groups must exist before the new thing can be added to them.

1. After saving the permanent certificate on the device, the device must disconnect from the session that it initiated with the temporary provisioning claim certificate and reconnect using the permanent certificate. 

The device is now ready to communicate normally with AWS IoT.

## Using pre-provisioning hooks with the AWS CLI
<a name="hooks-cli-instruc"></a>

The following procedure creates a provisioning template with pre-provisioning hooks. The Lambda function used here is an example that can be modified. 

**To create and apply a pre-provisioning hook to a provisioning template**

1. Create a Lambda function that has a defined input and output. Lambda functions are highly customizable. `allowProvisioning` and `parameterOverrides` are required for creating pre-provisioning hooks. For more information about creating Lambda functions, see [Using AWS Lambda with the AWS Command Line Interface](https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-awscli.html).

   The following is an example of a Lambda function output:

   ```
   {
     "allowProvisioning": True,
     "parameterOverrides": {
       "incomingKey0": "incomingValue0",
       "incomingKey1": "incomingValue1"
     }
   }
   ```

1. AWS IoT uses resource-based policies to call Lambda, so you must give AWS IoT permission to call your Lambda function.
**Important**  
Be sure to include the `source-arn` or `source-account` in the global condition context keys of the policies attached to your Lambda action to prevent permission manipulation. For more information about this, see [Cross-service confused deputy prevention](cross-service-confused-deputy-prevention.md).

   The following is an example using [add-permission](https://docs.aws.amazon.com/cli/latest/reference/lambda/add-permission.html) give IoT permission to your Lambda.

   ```
   aws lambda add-permission \
       --function-name myLambdaFunction \
       --statement-id iot-permission \
       --action lambda:InvokeFunction \
       --principal iot.amazonaws.com
   ```

1. Add a pre-provisioning hook to a template using either the [create-provisioning-template](https://docs.aws.amazon.com/cli/latest/reference/iot/create-provisioning-template.html) or [update-provisioning-template](https://docs.aws.amazon.com/cli/latest/reference/iot/update-provisioning-template.html) command.

   The following CLI example uses the [create-provisioning-template](https://docs.aws.amazon.com/cli/latest/reference/iot/create-provisioning-template.html) to create a provisioning template that has pre-provisioning hooks:

   ```
   aws iot create-provisioning-template \
       --template-name myTemplate \
       --provisioning-role-arn arn:aws:iam:us-east-1:1234564789012:role/myRole \
       --template-body file://template.json \
       --pre-provisioning-hook file://hooks.json
   ```

   The output of this command looks like the following:

   ```
   {
       "templateArn": "arn:aws:iot:us-east-1:1234564789012:provisioningtemplate/myTemplate",
       "defaultVersionId": 1,
       "templateName": myTemplate
   }
   ```

   You can also load a parameter from a file instead of typing it all as a command line parameter value to save time. For more information, see [Loading AWS CLI Parameters from a File](https://docs.aws.amazon.com/cli/latest/userguide/cli-usage-parameters-file.html). The following shows the `template` parameter in expanded JSON format:

   ```
   {
       "Parameters" : {
           "DeviceLocation": {
               "Type": "String"
           }
       },
       "Mappings": {
           "LocationTable": {
               "Seattle": {
                   "LocationUrl": "https://example.aws"
               }
           }
       },
       "Resources" : {
           "thing" : {
               "Type" : "AWS::IoT::Thing",
               "Properties" : {
                   "AttributePayload" : {
                       "version" : "v1",
                       "serialNumber" : "serialNumber"
                   },
                   "ThingName" : {"Fn::Join":["",["ThingPrefix_",{"Ref":"SerialNumber"}]]},
                   "ThingTypeName" : {"Fn::Join":["",["ThingTypePrefix_",{"Ref":"SerialNumber"}]]},
                   "ThingGroups" : ["widgets", "WA"],
                   "BillingGroup": "BillingGroup"
               },
               "OverrideSettings" : {
                   "AttributePayload" : "MERGE",
                   "ThingTypeName" : "REPLACE",
                   "ThingGroups" : "DO_NOTHING"
               }
           },
           "certificate" : {
               "Type" : "AWS::IoT::Certificate",
               "Properties" : {
                   "CertificateId": {"Ref": "AWS::IoT::Certificate::Id"},
                   "Status" : "Active",
                   "ThingPrincipalType" : "EXCLUSIVE_THING"
               }
           },
           "policy" : {
               "Type" : "AWS::IoT::Policy",
               "Properties" : {
                   "PolicyDocument" : {
                       "Version": "2012-10-17",		 	 	 
                       "Statement": [{
                           "Effect": "Allow",
                           "Action":["iot:Publish"],
                           "Resource": ["arn:aws:iot:us-east-1:504350838278:topic/foo/bar"]
                       }]
                   }
               }
           }
       },
       "DeviceConfiguration": {
           "FallbackUrl": "https://www.example.com/test-site",
           "LocationUrl": {
               "Fn::FindInMap": ["LocationTable",{"Ref": "DeviceLocation"}, "LocationUrl"]}
       }
   }
   ```

   The following shows the `pre-provisioning-hook` parameter in expanded JSON format:

   ```
   {
        "targetArn" : "arn:aws:lambda:us-east-1:765219403047:function:pre_provisioning_test",
        "payloadVersion" : "2020-04-01"
   }
   ```

# Provisioning devices that have device certificates
<a name="provision-w-cert"></a>

AWS IoT provides three ways to provision devices when they already have a device certificate (and associated private key) on them:
+ Single-thing provisioning with a provisioning template. This is a good option if you only need to provision devices one at a time.
+ Just-in-time provisioning (JITP) with a template that provisions a device when it first connects to AWS IoT. This is a good option if you need to register large numbers of devices, but you don't have information about them that you can assemble into a bulk provisioning list.
+ Bulk registration. This option allows you to specify a list of single-thing provisioning template values that are stored in a file in an S3 bucket. This approach works well if you have a large number of known devices whose desired characteristics you can assemble into a list. 

**Topics**
+ [

# Single thing provisioning
](single-thing-provisioning.md)
+ [

# Just-in-time provisioning
](jit-provisioning.md)
+ [

# Bulk registration
](bulk-provisioning.md)

# Single thing provisioning
<a name="single-thing-provisioning"></a>

To provision a thing, use the [RegisterThing](https://docs.aws.amazon.com/iot/latest/apireference/API_RegisterThing.html) API or the `register-thing` CLI command. The `register-thing` CLI command takes the following arguments:

--template-body  
The provisioning template.

--parameters  
A list of name-value pairs for the parameters used in the provisioning template, in JSON format (for example, `{"ThingName" : "MyProvisionedThing", "CSR" : "csr-text"}`).

See [Provisioning templates](provision-template.md).

[RegisterThing](https://docs.aws.amazon.com/iot/latest/apireference/API_RegisterThing.html) or `register-thing` returns the ARNs for the resources and the text of the certificate it created:

```
{
    "certificatePem": "certificate-text",
    "resourceArns": {
    "PolicyLogicalName": "arn:aws:iot:us-west-2:123456789012:policy/2A6577675B7CD1823E271C7AAD8184F44630FFD7",
    "certificate": "arn:aws:iot:us-west-2:123456789012:cert/cd82bb924d4c6ccbb14986dcb4f40f30d892cc6b3ce7ad5008ed6542eea2b049",
    "thing": "arn:aws:iot:us-west-2:123456789012:thing/MyProvisionedThing"
    }
}
```

If a parameter is omitted from the dictionary, the default value is used. If no default value is specified, the parameter is not replaced with a value.

# Just-in-time provisioning
<a name="jit-provisioning"></a>

You can use just-in-time provisioning (JITP) to provision your devices when they first attempt to connect to AWS IoT. To provision the device, you must enable automatic registration and associate a provisioning template with the CA certificate used to sign the device certificate. Provisioning successes and errors are logged as [Device provisioning metrics](metrics_dimensions.md#provisioning-metrics) in Amazon CloudWatch.

**Topics**
+ [

## JITP overview
](#jit-provisioning-overview)
+ [

## Register CA using provisioning template
](#jit-provisioning-registerCA-template)
+ [

## Register CA using provisioning template name
](#jit-provisioning-registerCA-templateName)

## JITP overview
<a name="jit-provisioning-overview"></a>

When a device attempts to connect to AWS IoT by using a certificate signed by a registered CA certificate, AWS IoT loads the template from the CA certificate and uses it to call [RegisterThing](fleet-provision-api.md#register-thing). The JITP workflow first registers a certificate with a status value of `PENDING_ACTIVATION`. When the device provisioning flow is complete, the status of the certificate is changed to `ACTIVE`.

AWS IoT defines the following parameters that you can declare and reference in provisioning templates:
+ `AWS::IoT::Certificate::Country`
+ `AWS::IoT::Certificate::Organization`
+ `AWS::IoT::Certificate::OrganizationalUnit`
+ `AWS::IoT::Certificate::DistinguishedNameQualifier`
+ `AWS::IoT::Certificate::StateName`
+ `AWS::IoT::Certificate::CommonName`
+ `AWS::IoT::Certificate::SerialNumber`
+ `AWS::IoT::Certificate::Id`

The values for these provisioning template parameters are limited to what JITP can extract from the subject field of the certificate of the device being provisioned. The certificate must contain values for all of the parameters in the template body. The `AWS::IoT::Certificate::Id` parameter refers to an internally generated ID, not an ID that is contained in the certificate. You can get the value of this ID using the `principal()` function inside an AWS IoT rule. 

**Note**  
You can provision devices using AWS IoT Core just-in-time provisioning (JITP) feature without having to send the entire trust chain on a device's first connection to AWS IoT Core. Presenting the CA certificate is optional, but the device is required to send the [Server Name Indication (SNI)](https://datatracker.ietf.org/doc/html/rfc3546#section-3.1) extension when it connects to AWS IoT Core.

### Example template body
<a name="jit-provisioning-example-templatebody"></a>

The following JSON file is an example template body of a complete JITP template. 

```
{
   "Parameters":{
      "AWS::IoT::Certificate::CommonName":{
         "Type":"String"
      },
      "AWS::IoT::Certificate::SerialNumber":{
         "Type":"String"
      },
      "AWS::IoT::Certificate::Country":{
         "Type":"String"
      },
      "AWS::IoT::Certificate::Id":{
         "Type":"String"
      }
   },
   "Resources":{
      "thing":{
         "Type":"AWS::IoT::Thing",
         "Properties":{
            "ThingName":{
               "Ref":"AWS::IoT::Certificate::CommonName"
            },
            "AttributePayload":{
               "version":"v1",
               "serialNumber":{
                  "Ref":"AWS::IoT::Certificate::SerialNumber"
               }
            },
            "ThingTypeName":"lightBulb-versionA",
            "ThingGroups":[
               "v1-lightbulbs",
               {
                  "Ref":"AWS::IoT::Certificate::Country"
               }
            ]
         },
         "OverrideSettings":{
            "AttributePayload":"MERGE",
            "ThingTypeName":"REPLACE",
            "ThingGroups":"DO_NOTHING"
         }
      },
      "certificate":{
         "Type":"AWS::IoT::Certificate",
         "Properties":{
            "CertificateId":{
               "Ref":"AWS::IoT::Certificate::Id"
            },
            "Status":"ACTIVE"
         }
      },
      "policy":{
         "Type":"AWS::IoT::Policy",
         "Properties":{
            "PolicyDocument":"{ \"Version\": \"2012-10-17\",		 	 	  \"Statement\": [{ \"Effect\": \"Allow\", \"Action\":[\"iot:Publish\"], \"Resource\": [\"arn:aws:iot:us-east-1:123456789012:topic/foo/bar\"] }] }"
         }
      }
   }
}
```

This sample template declares values for the `AWS::IoT::Certificate::CommonName`, `AWS::IoT::Certificate::SerialNumber`, `AWS::IoT::Certificate::Country`, and `AWS::IoT::Certificate::Id` provisioning parameters that are extracted from the certificate and used in the `Resources` section. The JITP workflow then uses this template to perform the following actions:
+ Register a certificate and set its status to PENDING\$1ACTIVE.
+ Create one thing resource.
+ Create one policy resource.
+ Attach the policy to the certificate.
+ Attach the certificate to the thing.
+ Update the certificate status to ACTIVE.

The device provisioning fails if the certificate doesn't have all of the properties mentioned in the `Parameters` section of the `templateBody`. For example, if `AWS::IoT::Certificate::Country` is included in the template, but the certificate doesn't have a `Country` property, the device provisioning fails.

You can also use CloudTrail to troubleshoot issues with your JITP template. For information about the metrics that are logged in Amazon CloudWatch, see [Device provisioning metrics](metrics_dimensions.md#provisioning-metrics). For more information about provisioning templates, see [Provisioning templates](provision-template.md).

**Note**  
During the provisioning process, just-in-time provisioning (JITP) calls other AWS IoT control plane API operations. These calls might exceed the [AWS IoT Throttling Quotas](https://docs.aws.amazon.com/general/latest/gr/iot-core.html#throttling-limits) set for your account and result in throttled calls. Contact [AWS Customer Support](https://console.aws.amazon.com/support/home) to raise your throttling quotas if necessary.

## Register CA using provisioning template
<a name="jit-provisioning-registerCA-template"></a>

To register a CA by using a complete provisioning template, follow these steps: 

1. Save your provisioning template and the role ARN information like the following example as a JSON file:

   ```
   { 
        "templateBody" : "{\r\n    \"Parameters\" : {\r\n        \"AWS::IoT::Certificate::CommonName\": {\r\n            \"Type\": \"String\"\r\n        },\r\n        \"AWS::IoT::Certificate::SerialNumber\": {\r\n            \"Type\": \"String\"\r\n        },\r\n        \"AWS::IoT::Certificate::Country\": {\r\n            \"Type\": \"String\"\r\n        },\r\n        \"AWS::IoT::Certificate::Id\": {\r\n            \"Type\": \"String\"\r\n        }\r\n    },\r\n    \"Resources\": {\r\n        \"thing\": {\r\n            \"Type\": \"AWS::IoT::Thing\",\r\n            \"Properties\": {\r\n                \"ThingName\": {\r\n                    \"Ref\": \"AWS::IoT::Certificate::CommonName\"\r\n                },\r\n                \"AttributePayload\": {\r\n                    \"version\": \"v1\",\r\n                    \"serialNumber\": {\r\n                        \"Ref\": \"AWS::IoT::Certificate::SerialNumber\"\r\n                    }\r\n                },\r\n                \"ThingTypeName\": \"lightBulb-versionA\",\r\n                \"ThingGroups\": [\r\n                    \"v1-lightbulbs\",\r\n                    {\r\n                        \"Ref\": \"AWS::IoT::Certificate::Country\"\r\n                    }\r\n                ]\r\n            },\r\n            \"OverrideSettings\": {\r\n                \"AttributePayload\": \"MERGE\",\r\n                \"ThingTypeName\": \"REPLACE\",\r\n                \"ThingGroups\": \"DO_NOTHING\"\r\n            }\r\n        },\r\n        \"certificate\": {\r\n            \"Type\": \"AWS::IoT::Certificate\",\r\n            \"Properties\": {\r\n                \"CertificateId\": {\r\n                    \"Ref\": \"AWS::IoT::Certificate::Id\"\r\n                },\r\n                \"Status\": \"ACTIVE\"\r\n            },\r\n            \"OverrideSettings\": {\r\n                \"Status\": \"DO_NOTHING\"\r\n            }\r\n        },\r\n        \"policy\": {\r\n            \"Type\": \"AWS::IoT::Policy\",\r\n            \"Properties\": {\r\n                \"PolicyDocument\": \"{ \\\"Version\\\": \\\"2012-10-17		 	 	 \\\", \\\"Statement\\\": [{ \\\"Effect\\\": \\\"Allow\\\", \\\"Action\\\":[\\\"iot:Publish\\\"], \\\"Resource\\\": [\\\"arn:aws:iot:us-east-1:123456789012:topic\/foo\/bar\\\"] }] }\"\r\n            }\r\n        }\r\n    }\r\n}",
        "roleArn" : "arn:aws:iam::123456789012:role/JITPRole"
   }
   ```

   In this example, the value of the `templateBody` field must be a JSON object specified as an escaped string and can use only the values in the [preceding list](#jit-provisioning-overview). You can use a variety of tools to create the required JSON output, such as `json.dumps` (Python) or `JSON.stringify` (Node). The value of the `roleARN` field must be the ARN of a role that has the `AWSIoTThingsRegistration` attached to it. Also, your template can use an existing `PolicyName` instead of the inline `PolicyDocument` in the example. 

1. Register a CA certificate with the [RegisterCACertificate](https://docs.aws.amazon.com/iot/latest/apireference/API_RegisterCACertificate.html) API operation or the [https://docs.aws.amazon.com//cli/latest/reference/iot/register-ca-certificate.html](https://docs.aws.amazon.com//cli/latest/reference/iot/register-ca-certificate.html) CLI command. You will specify the directory of the provisioning template and role ARN information that you saved in the previous step:

   The following shows an example of how to register a CA certificate in `DEFAULT` mode using the AWS CLI:

   ```
   aws iot register-ca-certificate --ca-certificate file://your-ca-cert --verification-cert file://your-verification-cert 
                   --set-as-active --allow-auto-registration --registration-config file://your-template
   ```

   The following shows an example of how to register a CA certificate in `SNI_ONLY` mode using the AWS CLI:

   ```
   aws iot register-ca-certificate --ca-certificate file://your-ca-cert --certificate-mode SNI_ONLY
                    --set-as-active --allow-auto-registration --registration-config file://your-template
   ```

   For more information, see [Register your CA Certificates](https://docs.aws.amazon.com//iot/latest/developerguide/register-CA-cert.html).

1.  (Optional) Update the settings for a CA certificate by using the [UpdateCACertificate](https://docs.aws.amazon.com/iot/latest/apireference/API_UpdateCACertificate.html) API operation or the [https://docs.aws.amazon.com//cli/latest/reference/iot/update-ca-certificate.html](https://docs.aws.amazon.com//cli/latest/reference/iot/update-ca-certificate.html) CLI command. 

   The following shows an example of how to update a CA certificate using the AWS CLI:

   ```
   aws iot update-ca-certificate --certificate-id caCertificateId
                   --new-auto-registration-status ENABLE --registration-config file://your-template
   ```

## Register CA using provisioning template name
<a name="jit-provisioning-registerCA-templateName"></a>

To register a CA by using a provisioning template name, follow these steps:

1. Save your provisioning template body as a JSON file. You can find an example template body in [example template body](#jit-provisioning-example-templatebody).

1. To create a provisioning template, use the [CreateProvisioningTemplate](https://docs.aws.amazon.com/iot/latest/apireference/API_CreateProvisioningTemplate.html) API or the [https://docs.aws.amazon.com//cli/latest/reference/iot/create-provisioning-template.html](https://docs.aws.amazon.com//cli/latest/reference/iot/create-provisioning-template.html) CLI command:

   ```
   aws iot create-provisioning-template --template-name your-template-name \
           --template-body file://your-template-body.json --type JITP \
           --provisioning-role-arn arn:aws:iam::123456789012:role/test
   ```
**Note**  
For just-in-time provisioning (JITP), you must specify template type to be `JITP` when creating the provisioning template. For more information about the template type, see [CreateProvisioningTemplate](https://docs.aws.amazon.com/iot/latest/apireference/API_CreateProvisioningTemplate.html) in the *AWS API Reference*.

1. To register CA with template name, use the [RegisterCACertificate](https://docs.aws.amazon.com/iot/latest/apireference/API_RegisterCACertificate.html) API or the [https://docs.aws.amazon.com//cli/latest/reference/iot/register-ca-certificate.html](https://docs.aws.amazon.com//cli/latest/reference/iot/register-ca-certificate.html) CLI command:

   ```
   aws iot register-ca-certificate --ca-certificate file://your-ca-cert --verification-cert file://your-verification-cert \
           --set-as-active --allow-auto-registration --registration-config templateName=your-template-name
   ```

# Bulk registration
<a name="bulk-provisioning"></a>

You can use the [https://docs.aws.amazon.com/iot/latest/apireference/API_StartThingRegistrationTask.html](https://docs.aws.amazon.com/iot/latest/apireference/API_StartThingRegistrationTask.html) command to register things in bulk. This command takes a provisioning template, an S3 bucket name, a key name, and a role ARN that allows access to the file in the S3 bucket. The file in the S3 bucket contains the values used to replace the parameters in the template. The file must be a newline-delimited JSON file. Each line contains all of the parameter values for registering a single device. For example:

```
{"ThingName": "foo", "SerialNumber": "123", "CSR": "csr1"}
{"ThingName": "bar", "SerialNumber": "456", "CSR": "csr2"}
```

The following bulk registration-related API operations might be useful:
+ [ListThingRegistrationTasks](https://docs.aws.amazon.com/iot/latest/apireference/API_ListThingRegistrationTasks.html): Lists the current bulk thing provisioning tasks. 
+ [ DescribeThingRegistrationTask](https://docs.aws.amazon.com/iot/latest/apireference/API_DescribeThingRegistrationTask.html): Provides information about a specific bulk thing registration task.
+ [StopThingRegistrationTask](https://docs.aws.amazon.com/iot/latest/apireference/API_StopThingRegistrationTask.html): Stops a bulk thing registration task.
+ [ListThingRegistrationTaskReports](https://docs.aws.amazon.com/iot/latest/apireference/API_ListThingRegistrationTaskReports.html): Used to check the results and failures for a bulk thing registration task.

**Note**  
Only one bulk registration operation task can run at a time (per account).
Bulk registration operations call other AWS IoT control plane API operations. These calls might exceed the [AWS IoT Throttling Quotas](https://docs.aws.amazon.com/general/latest/gr/iot-core.html#throttling-limits) in your account and cause throttle errors. Contact [AWS Customer Support](https://console.aws.amazon.com/support/home) to raise your AWS IoT throttling quotas, if necessary.

# Provisioning templates
<a name="provision-template"></a>

A provisioning template is a JSON document that uses parameters to describe the resources your device must use to interact with AWS IoT. A provisioning template contains two sections: `Parameters` and `Resources`. There are two types of provisioning templates in AWS IoT. One is used for just-in-time provisioning (JITP) and bulk registration, and the second is used for fleet provisioning.

**Topics**
+ [

## Parameters section
](#parameters-section)
+ [

## Resources section
](#resources-section)
+ [

## Template example for bulk registration
](#bulk-template-example)
+ [

## Template example for just-in-time provisioning (JITP)
](#JITP-template-example)
+ [

## Fleet provisioning
](#fleet-provision-template)

## Parameters section
<a name="parameters-section"></a>

The `Parameters` section declares the parameters used in the `Resources` section. Each parameter declares a name, a type, and an optional default value. The default value is used when the dictionary passed in with the template does not contain a value for the parameter. The `Parameters` section of a template document looks like the following:

```
{
    "Parameters" : {
        "ThingName" : {
            "Type" : "String"
        },
        "SerialNumber" : {
            "Type" : "String"
        },
        "Location" : {
            "Type" : "String",
            "Default" : "WA"
        },
        "CSR" : {
            "Type" : "String"    
        }
    }
}
```

This template body snippet declares four parameters: `ThingName`, `SerialNumber`, `Location`, and `CSR`. All of these parameters are of type `String`. The `Location` parameter declares a default value of `"WA"`.

## Resources section
<a name="resources-section"></a>

The `Resources` section of the template body declares the resources required for your device to communicate with AWS IoT: a thing, a certificate, and one or more IoT policies. Each resource specifies a logical name, a type, and a set of properties.

A logical name allows you to refer to a resource elsewhere in the template.

The type specifies the kind of resource that you are declaring. Valid types are:
+ `AWS::IoT::Thing`
+ `AWS::IoT::Certificate`
+ `AWS::IoT::Policy`

The properties you specify depend on the type of resource you are declaring.

### Thing resources
<a name="thing-resources"></a>

Thing resources are declared using the following properties:
+ `ThingName`: String.
+ `AttributePayload`: Optional. A list of name-value pairs.
+ `ThingTypeName`: Optional. String for an associated thing type for the thing.
+ `ThingGroups`: Optional. A list of groups to which the thing belongs.
+ `BillingGroup`: Optional. String for an associated billing group name.
+ `PackageVersions`: Optional. String for an associated package and version names.

### Certificate resources
<a name="certificate-resources"></a>

You can specify certificates in one of the following ways:
+ A certificate signing request (CSR).
+ A certificate ID of an existing device certificate. (Only certificate IDs can be used with a fleet provisioning template.)
+ A device certificate created with a CA certificate registered with AWS IoT. If you have more than one CA certificate registered with the same subject field, you must also pass in the CA certificate used to sign the device certificate.

**Note**  
When you declare a certificate in a template, use only one of these methods. For example, if you use a CSR, you cannot also specify a certificate ID or a device certificate. For more information, see [X.509 client certificates](x509-client-certs.md). 

For more information, see [X.509 Certificate overview](authentication.md#x509-certificate-overview). 

Certificate resources are declared using the following properties:
+ `CertificateSigningRequest`: String.
+ `CertificateId`: String.
+ `CertificatePem`: String.
+ `CACertificatePem`: String.
+ `Status`: Optional. String that can be `ACTIVE` or `INACTIVE`. Defaults to ACTIVE.
+ `ThingPrincipalType`: Optional. String that specifies the type of relationship between the thing and the principal (the certificate).
  + `EXCLUSIVE_THING`: Establishes an exclusive relationship. The principal can only be attached to this specific Thing and no others.
  + `NON_EXCLUSIVE_THING`: Attaches the specified principal to things. You can attach multiple Things to the principal. This is the default value if not specified.
**Note**  
You can also provision devices without device certificates. For more information, see [Provisioning devices that don't have device certificates using fleet provisioning](provision-wo-cert.md).

Examples:
+ Certificate specified with a CSR:

  ```
  {
      "certificate" : {
          "Type" : "AWS::IoT::Certificate",
          "Properties" : {
              "CertificateSigningRequest": {"Ref" : "CSR"},
              "Status" : "ACTIVE"      
          }
      }
  }
  ```
+ Certificate specified with an existing certificate ID:

  ```
  {
      "certificate" : {
          "Type" : "AWS::IoT::Certificate",
          "Properties" : {
              "CertificateId": {"Ref" : "CertificateId"}
          }
      }
  }
  ```
+ Certificate specified with an existing certificate .pem and CA certificate .pem:

  ```
  {
      "certificate" : {
          "Type" : "AWS::IoT::Certificate",
          "Properties" : {
              "CACertificatePem": {"Ref" : "CACertificatePem"},
              "CertificatePem": {"Ref" : "CertificatePem"}
          }
      }
  }
  ```
+ Exclusively attach one thing to a principal:

  ```
  {
      "certificate" : {
          "Type" : "AWS::IoT::Certificate",
          "Properties" : {
              "ThingPrincipalType" : "EXCLUSIVE_THING"
          }
      }
  }
  ```

### Policy resources
<a name="policy-resources"></a>

Policy resources are declared using one of the following properties:
+ `PolicyName`: Optional. String. Defaults to a hash of the policy document. The `PolicyName` can only reference AWS IoT policies but not IAM policies. If you are using an existing AWS IoT policy, for the `PolicyName` property, enter the name of the policy. Do not include the `PolicyDocument` property.
+ `PolicyDocument`: Optional. A JSON object specified as an escaped string. If `PolicyDocument` is not provided, the policy must already be created.

**Note**  
If a `Policy` section is present, `PolicyName` or `PolicyDocument`, but not both, must be specified.

### Override settings
<a name="override-settings"></a>

If a template specifies a resource that already exists, the `OverrideSettings` section allows you to specify the action to take:

`DO_NOTHING`  
Leave the resource as is.

`REPLACE`  
Replace the resource with the resource specified in the template.

`FAIL`  
Cause the request to fail with a `ResourceConflictsException`.

`MERGE`  
Valid only for the `ThingGroups` and `AttributePayload` properties of a `thing`. Merge the existing attributes or group memberships of the thing with those specified in the template.

When you declare a thing resource, you can specify `OverrideSettings` for the following properties:
+ `ATTRIBUTE_PAYLOAD`
+ `THING_TYPE_NAME`
+ `THING_GROUPS`

When you declare a certificate resource, you can specify `OverrideSettings` for the `Status` property.

`OverrideSettings` are not available for policy resources.

### Resource example
<a name="resource-example"></a>

The following template snippet declares a thing, a certificate, and a policy:

```
{ 
    "Resources" : {
        "thing" : {
            "Type" : "AWS::IoT::Thing",
            "Properties" : {
                "ThingName" : {"Ref" : "ThingName"},
                "AttributePayload" : { "version" : "v1", "serialNumber" :  {"Ref" : "SerialNumber"}}, 
                "ThingTypeName" :  "lightBulb-versionA",
                "ThingGroups" : ["v1-lightbulbs", {"Ref" : "Location"}]
            },
            "OverrideSettings" : {
                "AttributePayload" : "MERGE",
                "ThingTypeName" : "REPLACE",
                "ThingGroups" : "DO_NOTHING"
            }
        },  
        "certificate" : {
            "Type" : "AWS::IoT::Certificate",
            "Properties" : {
                "CertificateSigningRequest": {"Ref" : "CSR"},
                "Status" : "ACTIVE"      
            }
        },
        "policy" : {
            "Type" : "AWS::IoT::Policy",
            "Properties" : {
                "PolicyDocument" : "{ \"Version\": \"2012-10-17\",		 	 	  \"Statement\": [{ \"Effect\": \"Allow\", \"Action\":[\"iot:Publish\"], \"Resource\": [\"arn:aws:iot:us-east-1:123456789012:topic/foo/bar\"] }] }"
            }
        }
    }
}
```

The thing is declared with:
+ The logical name `"thing"`.
+ The type `AWS::IoT::Thing`.
+  A set of thing properties.

  The thing properties include the thing name, a set of attributes, an optional thing type name, and an optional list of thing groups to which the thing belongs.

Parameters are referenced by `{"Ref":"parameter-name"}`. When the template is evaluated, the parameters are replaced with the parameter's value from the dictionary passed in with the template.

The certificate is declared with:
+ The logical name `"certificate"`.
+ The type `AWS::IoT::Certificate`.
+ A set of properties.

  The properties include the CSR for the certificate, and setting the status to `ACTIVE`. The CSR text is passed as a parameter in the dictionary passed with the template.

The policy is declared with:
+ The logical name `"policy"`.
+ The type `AWS::IoT::Policy`.
+ Either the name of an existing policy or a policy document.

## Template example for bulk registration
<a name="bulk-template-example"></a>

The following JSON file is an example of a complete provisioning template that specifies the certificate with a CSR:

(The `PolicyDocument` field value must be a JSON object specified as an escaped string.)

```
{
    "Parameters" : {
        "ThingName" : {
            "Type" : "String"
        },
        "SerialNumber" : {
            "Type" : "String"
        },
        "Location" : {
            "Type" : "String",
            "Default" : "WA"
        },
        "CSR" : {
            "Type" : "String"    
        }
    },
    "Resources" : {
        "thing" : {
            "Type" : "AWS::IoT::Thing",
            "Properties" : {
                "ThingName" : {"Ref" : "ThingName"},
                "AttributePayload" : { "version" : "v1", "serialNumber" :  {"Ref" : "SerialNumber"}}, 
                "ThingTypeName" :  "lightBulb-versionA",
                "ThingGroups" : ["v1-lightbulbs", {"Ref" : "Location"}]
            }
        },
        "certificate" : {
            "Type" : "AWS::IoT::Certificate",
            "Properties" : {
                "CertificateSigningRequest": {"Ref" : "CSR"},
                "Status" : "ACTIVE",
                "ThingPrincipalType" : "EXCLUSIVE_THING"
            }
        },
        "policy" : {
            "Type" : "AWS::IoT::Policy",
            "Properties" : {
                "PolicyDocument" : "{ \"Version\": \"2012-10-17\",		 	 	  \"Statement\": [{ \"Effect\": \"Allow\", \"Action\":[\"iot:Publish\"], \"Resource\": [\"arn:aws:iot:us-east-1:123456789012:topic/foo/bar\"] }] }"
            }
        }
    }
}
```

## Template example for just-in-time provisioning (JITP)
<a name="JITP-template-example"></a>

The following JSON file is an example of a complete provisioning template that specifies an existing certificate with a certificate ID:

```
{
   "Parameters":{
      "AWS::IoT::Certificate::CommonName":{
         "Type":"String"
      },
      "AWS::IoT::Certificate::SerialNumber":{
         "Type":"String"
      },
      "AWS::IoT::Certificate::Country":{
         "Type":"String"
      },
      "AWS::IoT::Certificate::Id":{
         "Type":"String"
      }
   },
   "Resources":{
      "thing":{
         "Type":"AWS::IoT::Thing",
         "Properties":{
            "ThingName":{
               "Ref":"AWS::IoT::Certificate::CommonName"
            },
            "AttributePayload":{
               "version":"v1",
               "serialNumber":{
                  "Ref":"AWS::IoT::Certificate::SerialNumber"
               }
            },
            "ThingTypeName":"lightBulb-versionA",
            "ThingGroups":[
               "v1-lightbulbs",
               {
                  "Ref":"AWS::IoT::Certificate::Country"
               }
            ]
         },
         "OverrideSettings":{
            "AttributePayload":"MERGE",
            "ThingTypeName":"REPLACE",
            "ThingGroups":"DO_NOTHING"
         }
      },
      "certificate":{
         "Type":"AWS::IoT::Certificate",
         "Properties":{
            "CertificateId":{
               "Ref":"AWS::IoT::Certificate::Id"
            },
            "Status":"ACTIVE",
            "ThingPrincipalType" : "EXCLUSIVE_THING"
         }
      },
      "policy":{
         "Type":"AWS::IoT::Policy",
         "Properties":{
            "PolicyDocument":"{ \"Version\": \"2012-10-17\",		 	 	  \"Statement\": [{ \"Effect\": \"Allow\", \"Action\":[\"iot:Publish\"], \"Resource\": [\"arn:aws:iot:us-east-1:123456789012:topic/foo/bar\"] }] }"
         }
      }
   }
}
```

**Important**  
You must use `CertificateId` in a template that's used for JIT provisioning.

For more information about the type of a provisioning template, see [https://docs.aws.amazon.com/iot/latest/apireference/API_CreateProvisioningTemplate.html#iot-CreateProvisioningTemplate-request-type](https://docs.aws.amazon.com/iot/latest/apireference/API_CreateProvisioningTemplate.html#iot-CreateProvisioningTemplate-request-type) in the AWS API reference.

For more information about how to use this template for just-in-time provisioning, see: [Just-in-time provisioning](https://docs.aws.amazon.com/iot/latest/developerguide/jit-provisioning.html).

## Fleet provisioning
<a name="fleet-provision-template"></a>

Fleet provisioning templates are used by AWS IoT to set up cloud and device configuration. These templates use the same parameters and resources as the JITP and bulk registration templates. For more information, see [Provisioning templates](#provision-template). Fleet provisioning templates can contain a `Mapping` section and a `DeviceConfiguration` section. You can use intrinsic functions inside a fleet provisioning template to generate a device-specific configuration. Fleet provisioning templates are named resources and are identified by ARNs (for example, `arn:aws:iot:us-west-2:1234568788:provisioningtemplate/templateName`).

### Mappings
<a name="mappings"></a>

The optional `Mappings` section matches a key to a corresponding set of named values. For example, if you want to set values based on an AWS Region, you can create a mapping that uses the AWS Region name as a key and contains the values you want to specify for each specific Region. You use the `Fn::FindInMap` intrinsic function to retrieve values in a map.

You cannot include parameters, pseudo parameters, or call intrinsic functions in the `Mappings` section.

### Device configuration
<a name="device-config"></a>

The device configuration section contains arbitrary data that you want to send to your devices when provisioning. For example: 

```
{
    "DeviceConfiguration": {
        "Foo":"Bar"
    }
}
```

If you're sending messages to your devices by using the JavaScript Object Notation (JSON) payload format, AWS IoT Core formats this data as JSON. If you're using the Concise Binary Object Representation (CBOR) payload format, AWS IoT Core formats this data as CBOR. The `DeviceConfiguration` section doesn't support nested JSON objects.

### Intrinsic functions
<a name="intrinsic-functions"></a>

Intrinsic functions are used in any section of the provisioning template except the `Mappings` section.

`Fn::Join`  
Appends a set of values into a single value, separated by the specified delimiter. If a delimiter is an empty string, the values are concatenated with no delimiter.  
`Fn::Join` is not supported for [Policy resources](#policy-resources).

`Fn::Select`  
Returns a single object from a list of objects by index.  
`Fn::Select` does not check for `null` values or if the index is out of bounds of the array. Both conditions result in a provisioning error, so make sure you chose a valid index value and the list contains non-null values.

`Fn::FindInMap`  
Returns the value corresponding to keys in a two-level map that is declared in the `Mappings` section.

`Fn::Split`  
Splits a string into a list of string values so you can select an element from the list of strings. You specify a delimiter that determines where the string is split (for example, a comma). After you split a string, use `Fn::Select` to select an element.  
For example, if a comma-delimited string of subnet IDs is imported to your stack template, you can split the string at each comma. From the list of subnet IDs, use `Fn::Select` to specify a subnet ID for a resource.

`Fn::Sub`  
Substitutes variables in an input string with values that you specify. You can use this function to construct commands or outputs that include values that aren't available until you create or update a stack.

### Template example for fleet provisioning
<a name="fleet-provisioning-example"></a>

```
{
    "Parameters" : {
        "ThingName" : {
            "Type" : "String"
        },
        "SerialNumber": {
            "Type": "String"
        },
        "DeviceLocation": {
            "Type": "String"
        }
    },
    "Mappings": {
        "LocationTable": {
            "Seattle": {
                "LocationUrl": "https://example.aws"
            }
        }
    },
    "Resources" : {
        "thing" : {
            "Type" : "AWS::IoT::Thing",
            "Properties" : {
                "AttributePayload" : { 
                    "version" : "v1",
                    "serialNumber" : "serialNumber"
                },
                "ThingName" : {"Ref" : "ThingName"},
                "ThingTypeName" : {"Fn::Join":["",["ThingPrefix_",{"Ref":"SerialNumber"}]]},
                "ThingGroups" : ["v1-lightbulbs", "WA"],
                "BillingGroup": "LightBulbBillingGroup"
            },
            "OverrideSettings" : {
                "AttributePayload" : "MERGE",
                "ThingTypeName" : "REPLACE",
                "ThingGroups" : "DO_NOTHING"
            }
        },
        "certificate" : {
            "Type" : "AWS::IoT::Certificate",
            "Properties" : {
                "CertificateId": {"Ref": "AWS::IoT::Certificate::Id"},
                "Status" : "Active",
                "ThingPrincipalType" : "EXCLUSIVE_THING"
            }
        },
        "policy" : {
            "Type" : "AWS::IoT::Policy",
            "Properties" : {
                "PolicyDocument" : {
                    "Version": "2012-10-17",		 	 	 
                    "Statement": [{
                        "Effect": "Allow",
                        "Action":["iot:Publish"],
                        "Resource": ["arn:aws:iot:us-east-1:123456789012:topic/foo/bar"]
                    }]
                }
            }
        }
    },
    "DeviceConfiguration": {
        "FallbackUrl": "https://www.example.com/test-site",
        "LocationUrl": {
            "Fn::FindInMap": ["LocationTable",{"Ref": "DeviceLocation"}, "LocationUrl"]}
        }
}
```

**Note**  
An existing provisioning template can be updated to add a [pre-provisioning hook](pre-provisioning-hook.md).

# Pre-provisioning hooks
<a name="pre-provisioning-hook"></a>

AWS recommends using pre-provisioning hook functions when creating provisioning templates to allow more control of which and how many devices your account onboards. Pre-provisioning hooks are Lambda functions that validate parameters passed from the device before allowing the device to be provisioned. This Lambda function must exist in your account before you provision a device because it's called every time a device sends a request through [RegisterThing](fleet-provision-api.md#register-thing).

**Important**  
Be sure to include the `source-arn` or `source-account` in the global condition context keys of the policies attached to your Lambda action to prevent permission manipulation. For more information about this, see [Cross-service confused deputy prevention](cross-service-confused-deputy-prevention.md).

For devices to be provisioned, your Lambda function must accept the input object and return the output object described in this section. The provisioning proceeds only if the Lambda function returns an object with `"allowProvisioning": True`.

## Pre-provision hook input
<a name="pre-provisioning-hook-input"></a>

AWS IoT sends this object to the Lambda function when a device registers with AWS IoT.

```
{
    "claimCertificateId" : "string",
    "certificateId" : "string",
    "certificatePem" : "string",
    "templateArn" : "arn:aws:iot:us-east-1:1234567890:provisioningtemplate/MyTemplate",
    "clientId" : "221a6d10-9c7f-42f1-9153-e52e6fc869c1",
    "parameters" : {
        "string" : "string",
        ...
    }
}
```

The `parameters` object passed to the Lambda function contains the properties in the `parameters` argument passed in the [RegisterThing](fleet-provision-api.md#register-thing) request payload. 

## Pre-provision hook return value
<a name="pre-provisioning-hook-output"></a>

The Lambda function must return a response that indicates whether it has authorized the provisioning request and the values of any properties to override.

The following is an example of a successful response from the pre-provisioning function.

```
{
    "allowProvisioning": true,
    "parameterOverrides" : {
        "Key": "newCustomValue",
        ...
    }
}
```

`"parameterOverrides"` values will be added to `"parameters"` parameter of the [RegisterThing](fleet-provision-api.md#register-thing) request payload.

**Note**  
If the Lambda function fails, the provisioning request fails with `ACCESS_DENIED` and an error is logged to CloudWatch Logs.
If the Lambda function doesn't return `"allowProvisioning": "true"` in the response, the provisioning request fails with `ACCESS_DENIED`.
The Lambda function must finish running and return within 5 seconds, otherwise the provisioning request fails.

## Pre-provisioning hook Lambda example
<a name="pre-provisioning-example"></a>

------
#### [ Python ]

An example of a pre-provisioning hook Lambda in Python.

```
import json

def pre_provisioning_hook(event, context):
    print(event)

    return {
        'allowProvisioning': True,
        'parameterOverrides': {
            'DeviceLocation': 'Seattle'
        }
    }
```

------
#### [ Java ]

An example of a pre-provisioning hook Lambda in Java.

Handler class:

```
package example;

import java.util.Map;
import java.util.HashMap;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;

public class PreProvisioningHook implements RequestHandler<PreProvisioningHookRequest, PreProvisioningHookResponse> {

    public PreProvisioningHookResponse handleRequest(PreProvisioningHookRequest object, Context context) {
        Map<String, String> parameterOverrides = new HashMap<String, String>();
        parameterOverrides.put("DeviceLocation", "Seattle");

        PreProvisioningHookResponse response = PreProvisioningHookResponse.builder()
                .allowProvisioning(true)
                .parameterOverrides(parameterOverrides)
                .build();

        return response;
    }

}
```

Request class:

```
package example;

import java.util.Map;
import lombok.Builder;
import lombok.Data;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class PreProvisioningHookRequest {
    private String claimCertificateId;
    private String certificateId;
    private String certificatePem;
    private String templateArn;
    private String clientId;
    private Map<String, String> parameters;
}
```

Response class:

```
package example;

import java.util.Map;
import lombok.Builder;
import lombok.Data;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;


@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class PreProvisioningHookResponse {
    private boolean allowProvisioning;
    private Map<String, String> parameterOverrides;
}
```

------
#### [ JavaScript ]

An example of a pre-provisioning hook Lambda in JavaScript.

```
exports.handler = function(event, context, callback) {
    console.log(JSON.stringify(event, null, 2));
    var reply = { 
        allowProvisioning: true,
        parameterOverrides: {
            DeviceLocation: 'Seattle'
        }
     };
     callback(null, reply);
}
```

------

# Self-managed certificate signing using AWS IoT Core certificate provider
<a name="provisioning-cert-provider"></a>

You can create an AWS IoT Core certificate provider to sign certificate signing requests (CSRs) in AWS IoT fleet provisioning. A certificate provider references a Lambda function and the [`CreateCertificateFromCsr` MQTT API for fleet provisioning](https://docs.aws.amazon.com/iot/latest/developerguide/fleet-provision-api.html#create-cert-csr). The Lambda function accepts a CSR and returns a signed client certificate.

When you don't have a certificate provider with your AWS account, the [CreateCertificateFromCsr MQTT API](https://docs.aws.amazon.com//iot/latest/developerguide/fleet-provision-api.html#create-cert-csr) is called in fleet provisioning to generate the certificate from a CSR. After you create a certificate provider, the behavior of the [CreateCertificateFromCsr MQTT API](https://docs.aws.amazon.com//iot/latest/developerguide/fleet-provision-api.html#create-cert-csr) will change and all calls to this MQTT API will invoke the certificate provider to issue the certificate.

With AWS IoT Core certificate provider, you can implement solutions that utilize private certificate authorities (CAs) such as [AWS Private CA](https://docs.aws.amazon.com/privateca/latest/userguide/PcaWelcome.html), other publicly trusted CAs, or your own Public Key Infrastructure (PKI) to sign the CSR. In addition, you can use certificate provider to customize your client certificate's fields such as validity periods, signing algorithms, issuers, and extensions.

**Important**  
You can only create one certificate provider per AWS account. The signing behavior change applies to the entire fleet that calls the [CreateCertificateFromCsr MQTT API](https://docs.aws.amazon.com//iot/latest/developerguide/fleet-provision-api.html#create-cert-csr) until you delete the certificate provider from your AWS account.

**Topics**
+ [

## How self-managed certificate signing works in fleet provisioning
](#provisioning-cert-provider-how-it-works)
+ [

## Certificate provider Lambda function input
](#provisioning-cert-provider-lambda-input)
+ [

## Certificate provider Lambda function return value
](#provisioning-cert-provider-lambda-return)
+ [

## Example Lambda function
](#provisioning-cert-provider-lambda)
+ [

## Self-managed certificate signing for fleet provisioning
](#provisioning-self-certificate-signing)
+ [

## AWS CLI commands for certificate provider
](#provisioning-cert-provider-cli)

## How self-managed certificate signing works in fleet provisioning
<a name="provisioning-cert-provider-how-it-works"></a>

### Key concepts
<a name="provisioning-cert-provider-concepts"></a>

The following concepts provide details that can help you understand how self-managed certificate signing works in AWS IoT fleet provisioning. For more information, see [Provisioning devices that don't have device certificates using fleet provisioning](https://docs.aws.amazon.com//iot/latest/developerguide/provision-wo-cert.html).

**AWS IoT fleet provisioning**  
With AWS IoT fleet provisioning (short for fleet provisioning), AWS IoT Core generates and securely delivers device certificates to your devices when they connect to AWS IoT Core for the first time. You can use fleet provisioning to connect devices that don't have device certificates to AWS IoT Core. 

**Certificate signing request (CSR)**  
In the process of fleet provisioning, a device makes a request to AWS IoT Core through the [fleet provisioning MQTT APIs](https://docs.aws.amazon.com//iot/latest/developerguide/fleet-provision-api.html). This request includes a certificate signing request (CSR), which will be signed to create a client certificate. 

**AWS managed certificate signing in fleet provisioning**  
AWS managed is the default setting for certificate signing in fleet provisioning. With AWS managed certificate signing, AWS IoT Core will sign CSRs using its own CAs.

**Self-managed certificate signing in fleet provisioning**  
Self-managed is another option for certificate signing in fleet provisioning. With self-managed certificate signing, you create an AWS IoT Core certificate provider to sign CSRs. You can use self-managed certificate signing to sign CSRs with a CA generated by AWS Private CA, other publicly trusted CA, or your own Public Key Infrastructure (PKI).

**AWS IoT Core certificate provider**  
AWS IoT Core certificate provider (short for certificate provider) is a customer-managed resource that's used for self-managed certificate signing in fleet provisioning.

### Diagram
<a name="provisioning-cert-provider-diagram"></a>

The following diagram is a simplified illustration of how self-certificate signing works in AWS IoT fleet provisioning.

![\[AWS IoT Core certificate provider for fleet provisioning\]](http://docs.aws.amazon.com/iot/latest/developerguide/images/provisioning-cert-provider.png)

+ When a new IoT device is manufactured or introduced to the fleet, it needs client certificates to authenticate itself with AWS IoT Core.
+ As part of the fleet provisioning process, the device makes a request to AWS IoT Core for client certificates through the [fleet provisioning MQTT APIs](https://docs.aws.amazon.com//iot/latest/developerguide/fleet-provision-api.html). This request includes a certificate signing request (CSR).
+ AWS IoT Core invokes the certificate provider and passes the CSR as input to the provider.
+ The certificate provider takes the CSR as input and issues a client certificate.

  For AWS managed certificate signing, AWS IoT Core signs the CSR using its own CA and issues a client certificate.
+ With the issued client certificate, the device will continue the fleet provisioning and establish a secure connection with AWS IoT Core.

## Certificate provider Lambda function input
<a name="provisioning-cert-provider-lambda-input"></a>

AWS IoT Core sends the following object to the Lambda function when a device registers with it. The value of `certificateSigningRequest` is the CSR in [Privacy-Enhanced Mail (PEM) format](https://docs.aws.amazon.com/acm/latest/userguide/import-certificate-format.html) that's provided in the `CreateCertificateFromCsr` request. The `principalId` is the ID of the principal used to connect to AWS IoT Core when making the `CreateCertificateFromCsr` request. `clientId` is the client ID set for the MQTT connection.

```
{
	"certificateSigningRequest": "string",
	"principalId": "string",
	"clientId": "string"
}
```

## Certificate provider Lambda function return value
<a name="provisioning-cert-provider-lambda-return"></a>

The Lambda function must return a response that contains the `certificatePem` value. The following is an example of a successful response. AWS IoT Core will use the return value (`certificatePem`) to create the certificate.

```
{
	"certificatePem": "string"
}
```

If the registration is successful, `CreateCertificateFromCsr` will return the same `certificatePem` in the `CreateCertificateFromCsr` response. For more information, see the response payload example of [CreateCertificateFromCsr](https://docs.aws.amazon.com/iot/latest/developerguide/fleet-provision-api.html#create-cert-csr).

## Example Lambda function
<a name="provisioning-cert-provider-lambda"></a>

Before creating a certificate provider, you must create a Lambda function to sign a CSR. The following is an example Lambda function in Python. This function calls AWS Private CA to sign the input CSR, using a private CA and the `SHA256WITHRSA` signing algorithm. The returned client certificate will be valid for one year. For more information about AWS Private CA and how to create a private CA, see [What is AWS Private CA?](https://docs.aws.amazon.com/privateca/latest/userguide/PcaWelcome.html) and [Creating a private CA](https://docs.aws.amazon.com/privateca/latest/userguide/create-CA.html).

```
import os
import time
import uuid
import boto3

def lambda_handler(event, context):
    ca_arn = os.environ['CA_ARN']
    csr = (event['certificateSigningRequest']).encode('utf-8')

    acmpca = boto3.client('acm-pca')
    cert_arn = acmpca.issue_certificate(
        CertificateAuthorityArn=ca_arn, 
        Csr=csr,
        Validity={"Type": "DAYS", "Value": 365}, 
        SigningAlgorithm='SHA256WITHRSA',
        IdempotencyToken=str(uuid.uuid4())
    )['CertificateArn']
    
    # Wait for certificate to be issued
    time.sleep(1)    
    cert_pem = acmpca.get_certificate(
        CertificateAuthorityArn=ca_arn,
        CertificateArn=cert_arn
    )['Certificate']
    
    return {
        'certificatePem': cert_pem
    }
```

**Important**  
Certificates returned by the Lambda function must have the same subject name and public key as the Certificate Signing Request (CSR).
The Lambda function must finish running in 5 seconds.
The Lambda function must be in the same AWS account and Region as the certificate provider resource.
The AWS IoT service principal must be granted the invoke permission to the Lambda function. To avoid [confused deputy issues](https://docs.aws.amazon.com//IAM/latest/UserGuide/confused-deputy.html), we recommend that you set `sourceArn` and `sourceAccount` for the invoke permissions. For more information, see [Cross-service confused deputy prevention](https://docs.aws.amazon.com//iot/latest/developerguide/cross-service-confused-deputy-prevention.html).

The following resource-based policy example for [Lambda](https://docs.aws.amazon.com//lambda/latest/dg/access-control-resource-based.html) grants AWS IoT the permission to invoke the Lambda function:

****  

```
{
	"Version":"2012-10-17",		 	 	 
	"Id": "InvokePermission",
	"Statement": [
		{
			"Sid": "LambdaAllowIotProvider",
			"Effect": "Allow",
			"Principal": {
				"Service": "iot.amazonaws.com"
			},
			"Action": "lambda:InvokeFunction",
			"Resource": "arn:aws:lambda:us-east-1:123456789012:function:my-function",
			"Condition": {
				"StringEquals": {
					"AWS:SourceAccount": "123456789012"
				},
				"ArnLike": {
				"AWS:SourceArn": "arn:aws:iot:us-east-1:123456789012:certificateprovider/my-certificate-provider"
				}
			}
		}
	]
}
```

## Self-managed certificate signing for fleet provisioning
<a name="provisioning-self-certificate-signing"></a>

You can choose self-managed certificate signing for fleet provisioning using AWS CLI or AWS Management Console.

### AWS CLI
<a name="provisioning-self-certificate-signing-cli"></a>

To choose self-managed certificate signing, you must create an AWS IoT Core certificate provider to sign CSRs in fleet provisioning. AWS IoT Core invokes the certificate provider, which takes a CSR as input and returns a client certificate. To create a certificate provider, use the `CreateCertificateProvider` API operation or the `create-certificate-provider` CLI command.

**Note**  
After you create a certificate provider, the behavior of [`CreateCertificateFromCsr` API for fleet provisioning](https://docs.aws.amazon.com/iot/latest/developerguide/fleet-provision-api.html#create-cert-csr) will change so that all calls to `CreateCertificateFromCsr` will invoke the certificate provider to create the certificates. It can take a few minutes for this behavior to change after a certificate provider is created.

```
aws iot create-certificate-provider \
                --certificateProviderName my-certificate-provider \
                --lambdaFunctionArn arn:aws:lambda:us-east-1:123456789012:function:my-function-1 \
                --accountDefaultForOperations CreateCertificateFromCsr
```

The following shows an example output for this command:

```
{
	"certificateProviderName": "my-certificate-provider",
	"certificateProviderArn": "arn:aws:iot:us-east-1:123456789012:certificateprovider:my-certificate-provider"
}
```

For more information, see `[CreateCertificateProvider](https://docs.aws.amazon.com//iot/latest/apireference/API_CreateCertificateProvider.html)` from the *AWS IoT* *API Reference*.

### AWS Management Console
<a name="provisioning-self-certificate-signing-console"></a>

To choose self-managed certificate signing using AWS Management Console, follow the steps:

1. Go to the [AWS IoT console](https://console.aws.amazon.com//iot/home).

1. On the left navigation, under **Security**, choose **Certificate signing**.

1. On the **Certificate signing** page, under **Certificate signing details**, choose **Edit certificate signing method**.

1. On the **Edit certificate signing method** page, under **Certificate signing method**, choose **Self-managed**.

1. In the **Self-managed settings** section, enter a name for certificate provider, then create or choose a Lambda function.

1. Choose **Update certificate signing**.

## AWS CLI commands for certificate provider
<a name="provisioning-cert-provider-cli"></a>

### Create certificate provider
<a name="provisioning-create-cert-provider"></a>

To create a certificate provider, use the `CreateCertificateProvider` API operation or the `create-certificate-provider` CLI command. 

**Note**  
After you create a certificate provider, the behavior of [`CreateCertificateFromCsr` API for fleet provisioning](https://docs.aws.amazon.com/iot/latest/developerguide/fleet-provision-api.html#create-cert-csr) will change so that all calls to `CreateCertificateFromCsr` will invoke the certificate provider to create the certificates. It can take a few minutes for this behavior to change after a certificate provider is created.

```
aws iot create-certificate-provider \
                --certificateProviderName my-certificate-provider \
                --lambdaFunctionArn arn:aws:lambda:us-east-1:123456789012:function:my-function-1 \
                --accountDefaultForOperations CreateCertificateFromCsr
```

The following shows an example output for this command:

```
{
	"certificateProviderName": "my-certificate-provider",
	"certificateProviderArn": "arn:aws:iot:us-east-1:123456789012:certificateprovider:my-certificate-provider"
}
```

For more information, see `[CreateCertificateProvider](https://docs.aws.amazon.com//iot/latest/apireference/API_CreateCertificateProvider.html)` from the *AWS IoT* *API Reference*.

### Update certificate provider
<a name="provisioning-update-cert-provider"></a>

To update a certificate provider, use the `UpdateCertificateProvider` API operation or the `update-certificate-provider` CLI command.

```
aws iot update-certificate-provider \
                --certificateProviderName my-certificate-provider \
                --lambdaFunctionArn arn:aws:lambda:us-east-1:123456789012:function:my-function-2 \
                --accountDefaultForOperations CreateCertificateFromCsr
```

The following shows an example output for this command:

```
{
	"certificateProviderName": "my-certificate-provider",
	"certificateProviderArn": "arn:aws:iot:us-east-1:123456789012:certificateprovider:my-certificate-provider"
}
```

For more information, see `[UpdateCertificateProvider](https://docs.aws.amazon.com//iot/latest/apireference/API_UpdateCertificateProvider.html)` from the *AWS IoT** API Reference*.

### Describe certificate provider
<a name="provisioning-describe-cert-provider"></a>

To describe a certificate provider, use the `DescribeCertificateProvider` API operation or the `describe-certificate-provider` CLI command.

```
aws iot describe-certificate-provider --certificateProviderName my-certificate-provider
```

The following shows an example output for this command:

```
{
	"certificateProviderName": "my-certificate-provider",
	"lambdaFunctionArn": "arn:aws:lambda:us-east-1:123456789012:function:my-function",
	"accountDefaultForOperations": [
		"CreateCertificateFromCsr"
	],
	"creationDate": "2022-11-03T00:15",
	"lastModifiedDate": "2022-11-18T00:15"
}
```

For more information, see `[DescribeCertificateProvider](https://docs.aws.amazon.com//iot/latest/apireference/API_DescribeCertificateProvider.html)` from the *AWS IoT* *API Reference*.

### Delete certificate provider
<a name="provisioning-delete-cert-provider"></a>

To delete a certificate provider, use the `DeleteCertificateProvider` API operation or the `delete-certificate-provider` CLI command. If you delete the certificate provider resource, the behavior of `CreateCertificateFromCsr` will resume, and AWS IoT will create certificates signed by AWS IoT from a CSR.

```
aws iot delete-certificate-provider --certificateProviderName my-certificate-provider
```

This command doesn't produce any output. 

For more information, see `[DeleteCertificateProvider](https://docs.aws.amazon.com//iot/latest/apireference/API_DeleteCertificateProvider.html)` from the *AWS IoT* *API Reference*.

### List certificate provider
<a name="provisioning-list-cert-provider"></a>

To list the certificate providers within your AWS account, use the `ListCertificateProviders` API operation or the `list-certificate-providers` CLI command.

```
aws iot list-certificate-providers
```

The following shows an example output for this command:

```
{
	"certificateProviders": [
		{
			"certificateProviderName": "my-certificate-provider",
			"certificateProviderArn": "arn:aws:iot:us-east-1:123456789012:certificateprovider:my-certificate-provider"
		}
	]
}
```

For more information, see [https://docs.aws.amazon.com//iot/latest/apireference/API_ListCertificateProviders.html](https://docs.aws.amazon.com//iot/latest/apireference/API_ListCertificateProviders.html) from the *AWS IoT* *API Reference*.

# Creating IAM policies and roles for a user installing a device
<a name="provision-create-role"></a>

**Note**  
These procedures are for use only when directed by the AWS IoT console.  
To go to this page from the console, open [create a new provisioning template](https://console.aws.amazon.com//iot/home#/provisioningtemplate/create/provisioningmethods/trustedUser).

## Why can't this be done in the AWS IoT console?
<a name="provision-create-role-why"></a>

For the most secure experience, IAM actions are performed in the IAM console. The procedures in this section walk you through the steps to create the IAM roles and policies that are needed to use the provisioning template.

## Creating an IAM policy for the user who will install a device
<a name="provision-create-role-policy"></a>

This procedure describes how to create an IAM policy that authorizes a user to install a device using a provisioning template.

While performing this procedure, you'll be switching between the IAM console and the AWS IoT console. We recommend having both consoles open at the same time while you complete this procedure.

**To create an IAM policy for the user who will install a device**

1. Open the [Policies hub in the IAM console](https://console.aws.amazon.com//iamv2/home#/policies).

1. Choose **Create Policy**.

1. On the **Create policy** page, choose the **JSON** tab.

1. Switch to the page in the AWS IoT console where you chose **Configure user policy and role**.

1. In the **Sample provisioning policy**, choose **Copy**.

1. Switch back to the IAM console.

1. In the **JSON** editor, paste the policy you copied from the AWS IoT console. This policy is specific to the template you're creating in the AWS IoT console.

1. To continue, choose **Next: Tags**.

1. On the **Add tags (Optional)** page, choose **Add tag** for each tag you want to add to this policy. You can skip this step if you don't have any tags to add.

1. To continue, choose **Next: Review**.

1. On the **Review policy** page, do the following:

   1. For **Name\$1**, enter a name for the policy that will help you remember the policy's purpose.

      Note the name you give this policy because you'll use it in the next procedure.

   1. You can choose to enter an optional description for the policy you're creating.

   1. Review the rest of this policy and its tags.

1. To finish creating the new policy, choose **Create policy**.

After you create your new policy, continue to [Creating an IAM role for the user who will install a device](#provision-create-role-role) to create the user's role entry that you'll attach this policy.

## Creating an IAM role for the user who will install a device
<a name="provision-create-role-role"></a>

These steps describe how to create an IAM role that authenticates the user who will install a device using a provisioning template.

**To create an IAM policy for the user who will install a device**

1. Open the [Role hub in the IAM console](https://console.aws.amazon.com//iamv2/home#/roles).

1. Choose **Create role**.

1. In **Select trusted entity**, choose the type of trusted entity that you want to give access to the template you're creating.

1. Choose or enter the identification of the trusted entity that you want to grant access to, and then choose **Next**.

1. On the **Add permissions** page, in **Permission policies**, in the search box, enter the name of the policy you created in the [previous procedure](#provision-create-role-policy).

1. For the policy list, choose the policy that you created in the previous procedure, and then choose **Next**.

1. In the **Name, review, and create** section, do the following:

   1. For **Role name**, enter a role name that will help you remember the role's purpose.

   1. For **Description**, you can choose to enter an optional description of the Role. This isn't required to continue.

   1. Review the values in **Step 1** and **Step 2**.

   1. For **Add tags (Optional)**, you can choose to add tags to this role. This isn't required to continue.

   1. Verify the information on this page is complete and correct, and then choose **Create role**. 

After you create the new role, return to the AWS IoT console to continue creating the template.

## Updating an existing policy to authorize a new template
<a name="provision-create-role-update"></a>

The following steps describe how to add a new template to an IAM policy that authorizes a user to install a device using a provisioning template.

**To add a new template to an existing IAM policy**

1. Open the [Policies hub in the IAM console](https://console.aws.amazon.com//iamv2/home#/policies).

1. In the search box, enter the name of the policy to update.

1. For the list below the search box, find the policy you want to update and choose the policy name.

1. For **Policy summary**, choose the **JSON** tab, if that panel isn't already visible.

1. To modify the policy document, choose **Edit policy**.

1. In the editor, choose the **JSON** tab, if that panel isn't already visible.

1. In the policy document, find the policy statement that contains the `iot:CreateProvisioningClaim` action.

   If the policy document doesn't contain a policy statement with the `iot:CreateProvisioningClaim` action, copy the following statement snippet and paste it as an additional entry in the `Statement` array in the policy document. 
**Note**  
This snippet must be placed before the closing `]` character in the `Statement` array. You might need to add a comma before or after this snippet to correct any syntax errors.

   ```
   {
       "Effect": "Allow",
       "Action": [
           "iot:CreateProvisioningClaim"
       ],
       "Resource": [
           "--PUT YOUR NEW TEMPLATE ARN HERE--"
       ]
   }
   ```

1. Switch to the page in the AWS IoT console where you chose **Modify user role permissions**.

1. Find the **Resource ARN** of the template and choose **Copy**.

1. Switch back to the IAM console.

1. Paste the copied Amazon Resource Name (ARN) at the top of the list of template ARNs in the `Statement` array so that it's the first entry.

   If this is the only ARN in the array, remove the comma at end of the value you just pasted.

1. Review the updated policy statement and correct any errors indicated by the editor.

1. To save the updated policy document, choose **Review policy**.

1. Review the policy and then choose **Save changes**.

1. Return to the AWS IoT console.

# Device provisioning MQTT API
<a name="fleet-provision-api"></a><a name="provision-mqtt-api"></a>

The Fleet Provisioning service supports the following MQTT API operations:
+ `CreateCertificateFromCsr`
+ `CreateKeysAndCertificate`
+ `RegisterThing`

This API supports response buffers in Concise Binary Object Representation (CBOR) format and JavaScript Object Notation (JSON), depending on the *payload-format* of the topic. For clarity, the response and request examples in this section are shown in JSON format.


| *payload-format* | Response format data type | 
| --- | --- | 
| cbor | Concise Binary Object Representation (CBOR) | 
| json | JavaScript Object Notation (JSON) | 

**Important**  
Before publishing a request message topic, subscribe to the response topics to receive the response. The messages used by this API use MQTT's publish/subscribe protocol to provide a request and response interaction.   
If you don't subscribe to the response topics *before* you publish a request, you might not receive the results of that request.  
IoT Core Fleet Provisioning returns the device provisioning MQTT API results through the same MQTT connection used to publish the API request.

## CreateCertificateFromCsr
<a name="create-cert-csr"></a>

Creates a certificate from a certificate signing request (CSR). AWS IoT provides client certificates that are signed by the Amazon Root certificate authority (CA). The new certificate has a `PENDING_ACTIVATION` status. When you call `RegisterThing` to provision a thing with this certificate, the certificate status changes to `ACTIVE` or `INACTIVE` as described in the template.

For more information on creating a client certificate using your Certificate Authority certificate and a certificate signing request, refer to [Create a client certificate using your CA certificate](create-device-cert.md).

**Note**  
For security, the `certificateOwnershipToken` returned by `CreateCertificateFromCsr` expires after one hour. `RegisterThing` must be called before the `certificateOwnershipToken` expires. If the certificate created by `CreateCertificateFromCsr` hasn't been activated and attached to a policy or a thing by the time the token expires, the certificate is deleted. If the token expires, the device can call `CreateCertificateFromCsr` to generate a new certificate.

### CreateCertificateFromCsr request
<a name="create-cert-csr-request"></a>

Publish a message with the `$aws/certificates/create-from-csr/payload-format` topic.

`payload-format`  
The message payload format as `cbor` or `json`.

#### CreateCertificateFromCsr request payload
<a name="create-cert-csr-request-payload"></a>

```
{
    "certificateSigningRequest": "string"
}
```

`certificateSigningRequest`  
The CSR, in PEM format.

### CreateCertificateFromCsr response
<a name="create-cert-csr-response"></a>

Subscribe to `$aws/certificates/create-from-csr/payload-format/accepted`.

`payload-format`  
The message payload format as `cbor` or `json`.

#### CreateCertificateFromCsr response payload
<a name="create-cert-csr-response-payload"></a>

```
{
    "certificateOwnershipToken": "string",
    "certificateId": "string",
    "certificatePem": "string"
}
```

`certificateOwnershipToken`  
The token to prove ownership of the certificate during provisioning. 

`certificateId`  
The ID of the certificate. Certificate management operations only take a certificateId. 

`certificatePem`  
The certificate data, in PEM format.

### CreateCertificateFromCsr error
<a name="create-cert-csr-error"></a>

To receive error responses, subscribe to `$aws/certificates/create-from-csr/payload-format/rejected`.

`payload-format`  
The message payload format as `cbor` or `json`.

#### CreateCertificateFromCsr error payload
<a name="create-cert-csr-error-payload"></a>

```
{
    "statusCode": int,
    "errorCode": "string",
    "errorMessage": "string"
}
```

`statusCode`  
The status code.

`errorCode`  
The error code.

`errorMessage`  
The error message.

## CreateKeysAndCertificate
<a name="create-keys-cert"></a>

Creates new keys and a certificate. AWS IoT provides client certificates that are signed by the Amazon Root certificate authority (CA). The new certificate has a `PENDING_ACTIVATION` status. When you call `RegisterThing` to provision a thing with this certificate, the certificate status changes to `ACTIVE` or `INACTIVE` as described in the template.

**Note**  
For security, the `certificateOwnershipToken` returned by `CreateKeysAndCertificate` expires after one hour. `RegisterThing` must be called before the `certificateOwnershipToken` expires. If the certificate created by `CreateKeysAndCertificate` hasn't been activated and attached to a policy or a thing by the time the token expires, the certificate is deleted. If the token expires, the device can call `CreateKeysAndCertificate` to generate a new certificate.

### CreateKeysAndCertificate request
<a name="create-keys-cert-request"></a>

Publish a message on `$aws/certificates/create/payload-format` with an empty message payload.

`payload-format`  
The message payload format as `cbor` or `json`.

### CreateKeysAndCertificate response
<a name="create-keys-cert-response"></a>

Subscribe to `$aws/certificates/create/payload-format/accepted`.

`payload-format`  
The message payload format as `cbor` or `json`.

#### CreateKeysAndCertificate response
<a name="create-keys-cert-response-payload"></a>

```
{
    "certificateId": "string",
    "certificatePem": "string",
    "privateKey": "string",
    "certificateOwnershipToken": "string"
}
```

`certificateId`  
The certificate ID.

`certificatePem`  
The certificate data, in PEM format.

`privateKey`  
The private key.

`certificateOwnershipToken`  
The token to prove ownership of the certificate during provisioning.

### CreateKeysAndCertificate error
<a name="create-keys-cert-error"></a>

To receive error responses, subscribe to `$aws/certificates/create/payload-format/rejected`.

`payload-format`  
The message payload format as `cbor` or `json`.

#### CreateKeysAndCertificate error payload
<a name="create-keys-cert-error-payload"></a>

```
{
    "statusCode": int,
    "errorCode": "string",
    "errorMessage": "string"
}
```

`statusCode`  
The status code.

`errorCode`  
The error code.

`errorMessage`  
The error message.

## RegisterThing
<a name="register-thing"></a>

Provisions a thing using a pre-defined template.

### RegisterThing request
<a name="register-thing-request"></a>

Publish a message on `$aws/provisioning-templates/templateName/provision/payload-format`.

`payload-format`  
The message payload format as `cbor` or `json`.

`templateName`  
The provisioning template name.

#### RegisterThing request payload
<a name="register-thing-request-payload"></a>

```
{
    "certificateOwnershipToken": "string",
    "parameters": {
        "string": "string",
        ...
    }
}
```

`certificateOwnershipToken`  
The token to prove ownership of the certificate. AWS IoT generates the token when you create a certificate over MQTT.

`parameters`  
Optional. Key-value pairs from the device that are used by the [pre-provisioning hooks](pre-provisioning-hook.md) to evaluate the registration request.

### RegisterThing response
<a name="register-thing-response"></a>

Subscribe to `$aws/provisioning-templates/templateName/provision/payload-format/accepted`.

`payload-format`  
The message payload format as `cbor` or `json`.

`templateName`  
The provisioning template name.

#### RegisterThing response payload
<a name="register-thing-response-payload"></a>

```
{
    "deviceConfiguration": {
        "string": "string",
        ...
    },
    "thingName": "string"
}
```

`deviceConfiguration`  
The device configuration defined in the template.

`thingName`  
The name of the IoT thing created during provisioning.

### RegisterThing error response
<a name="register-thing-error"></a>

To receive error responses, subscribe to `$aws/provisioning-templates/templateName/provision/payload-format/rejected`.

`payload-format`  
The message payload format as `cbor` or `json`.

`templateName`  
The provisioning template name.

#### RegisterThing error response payload
<a name="register-thing-error-payload"></a>

```
{
    "statusCode": int,
    "errorCode": "string",
    "errorMessage": "string"
}
```

`statusCode`  
The status code.

`errorCode`  
The error code.

`errorMessage`  
The error message.