Just-in-time registration or JITR is another option beside just-in-time provisioning to register a device with AWS IoT when it connects for the first time.
When you connect to AWS IoT with the device certificate for the first time, the service will detect an unknown certificate signed by a registered CA and will auto-register the device certificate. On successful registration, AWS IoT will publish a registration message on a reserved MQTT topic and disconnect the client.
This MQTT registration event will trigger the attached AWS Lambda rules engine action, which will complete the provisioning of the device. After these steps, your device certificate will be ready to connect and authenticate with AWS IoT.
In this exercise you will setup just-in-time registration (JITR) with your own CA (ACM PCA) and an AWS Lambda function. The Lambda function will complete the following steps to register the device with AWS IoT:
jitr_Policy
is created if it doesn’t existMake sure that the shell variables CA_ARN
and CA_CERTIFICATE_ID
are set to the arn of your private CA and to the id of your CA certificate registered with AWS IoT.
You have learned in the JITP exercise to verify that the variables have been set.
First you need to remove JITP settings from the CA
aws iot update-ca-certificate --certificate-id $CA_CERTIFICATE_ID \
--remove-auto-registration \
--new-auto-registration-status DISABLE
Verify that the provision template and role arn have been removed from the CA
aws iot describe-ca-certificate --certificate-id $CA_CERTIFICATE_ID
To set up JITR you need to enable auto registration for your own CA, create a Lambda function which provisions your device and create a topic rule which calls the Lambda function once the device certificate gets registered.
Enable just-in-time registration for your CA
aws iot update-ca-certificate --certificate-id $CA_CERTIFICATE_ID \
--new-auto-registration-status ENABLE
Verify that the auto registration status is set to ENABLE
aws iot describe-ca-certificate --certificate-id $CA_CERTIFICATE_ID
The output of the previous command should contain:
...
"autoRegistrationStatus": "ENABLE",
...
Create a Lambda function to provision your devices. The role that is required to create the Lambda function was already created for you and copied to the shell variable $ARN_LAMBDA_ROLE
# change to the directory where the lambda is stored
cd ~/provisioning/jitr
The Lambda function is implemented in Python 3.7 and uses the pyOpenSSL library to parse the certificate. As the pyOpenSSL library is not installed by default in the Lambda environment an installation package as zip file has been created already for you. This zip file will be used to create the Lambda function.
# create the lambda function
aws lambda create-function \
--region $REGION \
--function-name jitr \
--zip-file fileb://./jitr-lambda.zip \
--role $ARN_LAMBDA_ROLE \
--handler lambda_function.lambda_handler \
--runtime python3.7 \
--timeout 30 \
--memory-size 256
Verify that the lambda function has been created
aws lambda list-functions
Create an IoT topic rule. With this rule the Lambda function that you just created is called when a device certificate is auto-registered.
To create the topic rule we need to have the arn of the Lambda function. Assign the function arn to the shell variable ARN_LAMBDA
:
ARN_LAMBDA=$(aws lambda get-function --function-name jitr | jq -r '.Configuration.FunctionArn')
# verify the variable content
echo $ARN_LAMBDA
Create the IoT topic rule
aws iot create-topic-rule --rule-name JITRRule \
--topic-rule-payload "{
\"sql\": \"SELECT * FROM '\$aws/events/certificates/registered/#' WHERE certificateStatus = \\\"PENDING_ACTIVATION\\\"\",
\"description\": \"Rule for JITR\",
\"actions\": [
{
\"lambda\": {
\"functionArn\": \"$ARN_LAMBDA\"
}
}
]
}"
Verify that the topic rule has been created
aws iot get-topic-rule --rule-name JITRRule
Add a permission to the lambda function to allow the AWS IoT to invoke the function. For adding the permissions we need the topic rule arn and will store it into a shell variable
# get you AWS account id
ACCOUNT_ID=$(aws sts get-caller-identity | jq -r '.Account')
# verify that the variable has been set
echo $ACCOUNT_ID
# store topic rule arn
ARN_TOPIC_RULE=$(aws iot get-topic-rule --rule-name JITRRule | jq -r '.ruleArn')
# verify that the variable has been set
echo $ARN_TOPIC_RULE
# add permissions to the Lambda
aws lambda add-permission --function-name jitr \
--region $REGION --principal iot.amazonaws.com \
--source-arn $ARN_TOPIC_RULE --source-account $ACCOUNT_ID \
--statement-id Id-123 --action "lambda:InvokeFunction"
# verify the permissions of the function
aws lambda get-policy --function-name jitr
Create device certificate in the same way you did for JITP but use a different name for deviceCert
and the common name my-jitr-device
.
Change to the certs directory
cd ~/ACM_PCA
Set a name for your device cert
deviceCert=deviceJITRCert
Create a key and CSR
openssl req -nodes -new -newkey rsa:2048 \
-keyout $deviceCert.key \
-out $deviceCert.csr \
-subj "/C=DE/CN=my-jitr-device"
Issue a certificate with ACM PCA. You learned already howto do this in the section about just-in-time provisioning.
Create a thing key, certificate and connect to AWS IoT like you did in the JITP section of this workshop.
Connect to AWS IoT to initiate the JITR process
mosquitto_pub --cafile ~/root.ca.bundle.pem \
--cert ${deviceCert}AndCACert.crt \
--key $deviceCert.key \
-h $IOT_ENDPOINT -p 8883 -q 1 -t cmd/my-jitr-device/welcome -i my-jitr-device \
--tls-version tlsv1.2 -m '{"let-me": "in"}' -d
To verify if the JITR process finished successful try to publish a message to the topic dt/my-jitr-device/welcome
mosquitto_pub --cafile ~/root.ca.bundle.pem \
--cert ${deviceCert}.crt \
--key $deviceCert.key \
-h $IOT_ENDPOINT -p 8883 -q 1 -t dt/my-jitr-device/welcome -i my-jitr-device \
--tls-version tlsv1.2 -m '{"i am": "just-in-time registered"}' -d
If the message arrives the device has been provisioned successfully.
In case messages are not published successfully you need to troubleshoot your setup:
aws iot describe-thing --thing-name my-jitr-device
jitr_Policy
must have been created: aws iot get-policy --policy-name jitr_Policy
jitr_Policy
attached to the certificate/aws/lambda/jitr