Skip to content

Latest commit

 

History

History
303 lines (217 loc) · 10.5 KB

File metadata and controls

303 lines (217 loc) · 10.5 KB

BULK CERTS REST API

Introduction

The bulk certs module allows for the creation of large batches of X.509 certificates, and optionally register them with AWS IoT.

When a batch is requested, a task is created to track the creation of certificates. Upon task creation, the creation call is returned immediately to the caller. The task itself is then split in smaller chunks to allow for quick processing. Once all chunks are complete, the overall task is complete, and the certificates can be downloaded as a single zip file.

Pre-Requisites

[Optional] Registering a custom CA with AWS IoT

When creating device certificates they can be signed by the Amazon Root certificate authority (CA), or alternatively signed by other root CAs. It is recommended that other root CAs are used due to:

  • currently all device certificates created using the Amazon Root CA are long-lived certificates. With other root CAs you have the opportunity to specify device expiration dates
  • if you need devices to self-register themselves using just-in-time registration (JITR) or just-in-time provisioning (JITP) type provisioning flows, then you must register a root CA
  • a recommended best practice is to use different CAs per device suppliers. Then in the event of a CA being compromised, just that single supplier can be notified and have a new CA issued for use with the other suppliers remaining unaffected

The following outlines the steps for registering other root CAs.

Note that a CA may be registered with just one account within a region. If your devices need the ability to connect to multiple accounts within a region, such as having the same device certificate signed by a single CA able to connect to different development, testing, and production accounts, then use the CDF provisioning module to auto-create the device certificate as part of the provisioning flow which supports multi-account registration.

1/ Register your CA with AWS IoT

If you need to create your own CA, refer to Create a CA certificate.

If you already have a CA, or have created one using the previous step, then refer to Register your CA certificate.

2/ Securely store the CA private key

To sign the device certificates with a custom CA, the CA private key is required. This module uses AWS Key Management Service (KMS) to securely store and encrypt the CA private key in AWS Systems Manager. When you deploy this module, one of the required parameters is to specify whether an existing KMS key should be used or a new one created for this purpose.

The following AWS CLI command uploads the private key file to SSM. It is recommended to use the CLI rather than copy pasting into the console to avoid possible formatting issues in the console.

Note: By convention, this module expects the SSM parameter name in the format cdf-ca-key-<CA KEY ID>, where the <CA KEY ID> is the CA certificate ID (aka CA name in the AWS Console) when it is registered in AWS IoT.

# <KMS KEY ID>: The `KmsKeyId` parameter of the `cdf-bulkcerts-<env>` CloudFormation stack
# <CA KEY ID>: the CA certificate ID (aka CA name in the AWS Console)
# <PRIVATE KEY LOCATION>: the file path of the CA private key to store in SSM
aws ssm put-parameter --type SecureString /
 --key-id <KMS KEY ID> /
 --name cdf-ca-key-<CA KEY ID> /
 --value file://<PRIVATE KEY LOCATION> --overwrite

[Optional] Creating certificates with ACMPCA

Customers who need additional security can use Private CAs in AWS Certificate Manager (ACMPCA) to manage the generation of their device certificates. Additional resources can be found here.

1/ Create a private CA in AWS ACM

if you need to create a private CA, refer to PCA Planning Documentation. Once you have created your private CA go to the next step and use its arn as value for the supplier.

Define which CAs are to be used per supplier alias

As you will see from the walkthrough below, an alias (supplierId) is required as part of the REST API call to create device certificates. Behind the scenes this alias is mapped to specific CAs to use to sign the device certificates. This mapping needs to be defined before device certificates can be created for a specific supplier.

The alias to CA ID is defined in the application configuration at time of deployment. If this mapping needs to change post deployment, then the application configuration should be updated followed by a redeployment. The following is an excerpt of a sample application configuration where aliases supplier1 and supplier2 are mapped to different custom CAs, supplier3 is mapped to the Amazon Root CA and supplier4 is mapped to the ACMPCA:

{
  ...
  "supplierRootCa": {
    "supplier1": "856058e172339c0112ede7ea58616e661946bf8a85490410f8131ce651417425",
    "supplier2": "3d2ecfdb0eba2898626291e7e18a37cee791dbc81940a39e8ce922f9ff2feb32",
    "supplier3": "AwsIotDefault",
    "supplier4" : "arn:aws:acm-pca:us-west-2:xxxxxxxxxxxx:certificate-authority/17ef9add-91a6-4c1f-b13b-0f6ec1952722"
  }
  ...
}

Refer to Application configuration for more details on what configuration may be specified.

Walkthrough

1a/ Request a batch of certificates, using pre-defined application defaults

Request
POST /supplier/<supplierId>/certificates
Accept: application/vnd.aws-cdf-v1.0+json
Content-Type: application/vnd.aws-cdf-v1.0+json

{
  "quantity": 2
}
Response
Content-Type: application/vnd.aws-cdf-v1.0+json
location: /certificates/jshs783h
x-taskid: jshs783h

{
  "taskId": "jshs783h",
  "status": "pending"
}

1b/ Request a batch of certificates, setting certificate properties

Request
POST /supplier/<supplierId>/certificates
Accept: application/vnd.aws-cdf-v1.0+json
Content-Type: application/vnd.aws-cdf-v1.0+json

{
  "quantity": 2,
  "certInfo": {
    "country": "US"
  }
}
Response
Content-Type: application/vnd.aws-cdf-v1.0+json
location: /certificates/jshs783h
x-taskid: jshs783h

{
  "taskId": "jshs783h",
  "status": "pending"
}

1c/ Request a batch of certificates, auto-generating the certificate common name (incremental method)

The following example will create 100 sequential device certificates with a commonName starting from `templateFoo::`AB1CD79EF and ending with `templateFoo::`AB1CD79F54. This commonName format of `<proviioningTemplateName>::`<deviceId> is useful in JITR provisioning flows where devices are able to self register based on information presented in the certificate. Note that the count provided in the commonName field ${incement(100)} will override the quantity value

Request
POST /supplier/<supplierId>/certificates
Accept: application/vnd.aws-cdf-v1.0+json
Content-Type: application/vnd.aws-cdf-v1.0+json
{
  "quantity": 100,
  "certInfo": {
    "commonName": "`templateFoo::`AB1CD79EF${incement(100)}",
    "includeCA": true
  }
}
Response
Content-Type: application/vnd.aws-cdf-v1.0+json
location: /certificates/jshs783h
x-taskid: jshs783h

{
  "taskId": "jshs783h",
  "status": "pending"
}

1d/ Request a batch of certificates, auto-generating the certificate common name (list method)

Th following example will create 3 device certificates with commonNames of `templateFoo::`AB1CD79EF1, `templateFoo::`AB1CD79EF2 and `templateFoo::`AB1CD79EF3. Note that the number of elements in the commonNameList array would override the quantity value

Request
POST /supplier/<supplierId>/certificates
Accept: application/vnd.aws-cdf-v1.0+json
Content-Type: application/vnd.aws-cdf-v1.0+json

{
  "quantity": 3,
  "certInfo": {
    "commonName": "`templateFoo::`${list}" ,
    "commonNameList":["AB1CD79EF1","AB1CD79EF2","AB1CD79EF3"]
  }
}
Response
Content-Type: application/vnd.aws-cdf-v1.0+json
location: /certificates/jshs783h
x-taskid: jshs783h

{
  "taskId": "jshs783h",
  "status": "pending"
}

1e/ Request a batch of certificates, auto-generating the certificate common name (static method)

The following example will create 100 device certificates with a static commonName of `templateFoo::`AB1CD79EF.

Request
POST /supplier/<supplierId>/certificates
Accept: application/vnd.aws-cdf-v1.0+json
Content-Type: application/vnd.aws-cdf-v1.0+json

{
  "quantity": 100,
  "certInfo": {
    "commonName": "`templateFoo::`AB1CD79EF${static}"
  }
}
Response
Content-Type: application/vnd.aws-cdf-v1.0+json
location: /certificates/jshs783h
x-taskid: jshs783h

{
  "taskId": "jshs783h",
  "status": "pending"
}

2a/ Attempt to download certificates when task is still in progress

If the certificate batch creation task is pending or in_progress, a 303 redirect will occur to return the task status.

Request
GET /certificates/<taskId>
Accept: application/vnd.aws-cdf-v1.0+json
Content-Type: application/vnd.aws-cdf-v1.0+json
Response
303 Redirect to /certificates/<taskId>/task
Content-Type: application/vnd.aws-cdf-v1.0+json

{
  "taskId": "jshs783h",
  "status": "in_progress",
  "chunksPending": 2,
  "chunksTotal": 12
}

2b/ Download certificate (once task complete) as a direct download of a zip file

Request
GET /certificates/<taskId>
Accept: application/vnd.aws-cdf-v1.0+json
Content-Type: application/zip
Response
Content-Type: application/zip

<Binary file>

2c/ Download certificate (once task complete) as a list of presigned urls

Request
GET /certificates/<taskId>?downloadtype=signedUrl
Accept: application/vnd.aws-cdf-v1.0+json
Content-Type: application/vnd.aws-cdf-v1.0+json
Response
Content-Type: application/vnd.aws-cdf-v1.0+json

[ "url1", "url2", ... ]

Useful Links