

# Data protection in AWS IoT Core
<a name="data-protection"></a>

The AWS [shared responsibility model](https://aws.amazon.com/compliance/shared-responsibility-model/) applies to data protection in AWS IoT Core. As described in this model, AWS is responsible for protecting the global infrastructure that runs all of the AWS Cloud. You are responsible for maintaining control over your content that is hosted on this infrastructure. You are also responsible for the security configuration and management tasks for the AWS services that you use. For more information about data privacy, see the [Data Privacy FAQ](https://aws.amazon.com/compliance/data-privacy-faq/). For information about data protection in Europe, see the [AWS Shared Responsibility Model and GDPR](https://aws.amazon.com/blogs/security/the-aws-shared-responsibility-model-and-gdpr/) blog post on the *AWS Security Blog*.

For data protection purposes, we recommend that you protect AWS account credentials and set up individual users with AWS IAM Identity Center or AWS Identity and Access Management (IAM). That way, each user is given only the permissions necessary to fulfill their job duties. We also recommend that you secure your data in the following ways:
+ Use multi-factor authentication (MFA) with each account.
+ Use SSL/TLS to communicate with AWS resources. We require TLS 1.2 and recommend TLS 1.3.
+ Set up API and user activity logging with AWS CloudTrail. For information about using CloudTrail trails to capture AWS activities, see [Working with CloudTrail trails](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-trails.html) in the *AWS CloudTrail User Guide*.
+ Use AWS encryption solutions, along with all default security controls within AWS services.
+ Use advanced managed security services such as Amazon Macie, which assists in discovering and securing sensitive data that is stored in Amazon S3.
+ If you require FIPS 140-3 validated cryptographic modules when accessing AWS through a command line interface or an API, use a FIPS endpoint. For more information about the available FIPS endpoints, see [Federal Information Processing Standard (FIPS) 140-3](https://aws.amazon.com/compliance/fips/).

We strongly recommend that you never put confidential or sensitive information, such as your customers' email addresses, into tags or free-form text fields such as a **Name** field. This includes when you work with AWS IoT or other AWS services using the console, API, AWS CLI, or AWS SDKs. Any data that you enter into tags or free-form text fields used for names may be used for billing or diagnostic logs. If you provide a URL to an external server, we strongly recommend that you do not include credentials information in the URL to validate your request to that server.

For more information about data protection, see the [AWS Shared Responsibility Model and GDPR](https://aws.amazon.com/blogs/security/the-aws-shared-responsibility-model-and-gdpr/) blog post on the *AWS Security Blog*.

AWS IoT devices gather data, perform some manipulation on that data, and then send that data to another web service. You might choose to store some data on your device for a short period of time. You're responsible for providing any data protection on that data at rest. When your device sends data to AWS IoT, it does so over a TLS connection as discussed later in this section. AWS IoT devices can send data to any AWS service. For more information about each service's data security, see the documentation for that service. AWS IoT can be configured to write logs to CloudWatch Logs and log AWS IoT API calls to AWS CloudTrail. For more information about data security for these services, see [ Authentication and Access Control for Amazon CloudWatch](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/auth-and-access-control-cw.html) and [Encrypting CloudTrail Log Files with AWS KMS managed keys](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/encrypting-cloudtrail-log-files-with-aws-kms.html).

## Data encryption in AWS IoT
<a name="data-protection-encrypt"></a>

By default, all AWS IoT data in transit and at rest is encrypted. [Data in transit is encrypted using TLS](transport-security.md), and data at rest is encrypted using AWS owned keys. AWS IoT supports customer managed AWS KMS keys (KMS keys) from AWS Key Management Service (AWS KMS). However, Device Advisor and AWS IoT Wireless use only an AWS owned key to encrypt customer data.

 

# Transport security in AWS IoT Core
<a name="transport-security"></a>

TLS (Transport Layer Security) is a cryptographic protocol that is designed for secure communication over a computer network. The AWS IoT Core Device Gateway requires customers to encrypt all communication while in-transit by using TLS for connections from devices to the Gateway. TLS is used to achieve confidentiality of the application protocols (MQTT, HTTP, and WebSocket) supported by AWS IoT Core. TLS support is available in a number of programming languages and operating systems. Data within AWS is encrypted by the specific AWS service. For more information about data encryption on other AWS services, see the security documentation for that service.

**Topics**
+ [TLS protocols](#tls-ssl-policy)
+ [Security policies](#tls-policy-table)
+ [Important notes for transport security in AWS IoT Core](#tls-ssl-core)
+ [Transport security for LoRaWAN wireless devices](#tls-lorawan)

## TLS protocols
<a name="tls-ssl-policy"></a>

AWS IoT Core supports the following versions of the TLS protocol:
+ TLS 1.3 
+ TLS 1.2

With AWS IoT Core, you can configure the TLS settings (for [TLS 1.2](https://en.wikipedia.org/wiki/Transport_Layer_Security#TLS_1.2) and [TLS 1.3](https://en.wikipedia.org/wiki/Transport_Layer_Security#TLS_1.3)) in domain configurations. For more information, see [Configuring TLS settings in domain configurations](iot-endpoints-tls-config.md).

## Security policies
<a name="tls-policy-table"></a>

A security policy is a combination of TLS protocols and their ciphers that determine which protocols and ciphers are supported during TLS negotiations between a client and a server. You can configure your devices to use predefined security policies based on your needs. Note that AWS IoT Core doesn't support custom security policies.

You can choose one of the predefined security policies for your devices when connecting them to AWS IoT Core. The names of the most recent predefined security policies in AWS IoT Core include version information based on the year and month that they were released. The default predefined security policy is `IoTSecurityPolicy_TLS13_1_2_2022_10`. To specify a security policy, you can use the AWS IoT console or the AWS CLI. For more information, see [Configuring TLS settings in domain configurations](iot-endpoints-tls-config.md).

The following table describes the most recent predefined security policies that AWS IoT Core supports. The `IotSecurityPolicy_` has been removed from policy names in the heading row so that they fit.


| **Security policy** | TLS13\$11\$13\$12022\$110 | TLS13\$11\$12\$12022\$110 | TLS12\$11\$12\$12022\$110 | TLS12\$11\$10\$12016\$101\$1 | TLS12\$11\$10\$12015\$101\$1 | 
| --- | --- | --- | --- | --- | --- | 
| TCP Port |  443/8443/8883  |  443/8443/8883  |  443/8443/8883  | 443 | 8443/8883 | 443 | 8443/8883 | 
| TLS Protocols | 
| TLS 1.2 |  | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 
| TLS 1.3 | ✓ | ✓ |  |  |  |  |  | 
| TLS Ciphers | 
| TLS\$1AES\$1128\$1GCM\$1SHA256 | ✓ | ✓ |  |  |  |  |  | 
| TLS\$1AES\$1256\$1GCM\$1SHA384 | ✓ | ✓ |  |  |  |  |  | 
| TLS\$1CHACHA20\$1POLY1305\$1SHA256 | ✓ | ✓ |  |  |  |  |  | 
| ECDHE-RSA-AES128-GCM-SHA256 |  | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 
| ECDHE-RSA-AES128-SHA256 |  | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 
| ECDHE-RSA-AES128-SHA |  | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 
| ECDHE-RSA-AES256-GCM-SHA384 |  | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 
| ECDHE-RSA-AES256-SHA384 |  | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 
| ECDHE-RSA-AES256-SHA |  | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 
| AES128-GCM-SHA256 |  | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 
| AES128-SHA256 |  | ✓ | ✓ | ✓ |  | ✓ | ✓ | 
| AES128-SHA |  | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 
| AES256-GCM-SHA384 |  | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 
| AES256-SHA256 |  | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 
| AES256-SHA |  | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 
| DHE-RSA-AES256-SHA |  |  |  |  |  | ✓ | ✓ | 
| ECDHE-ECDSA-AES128-GCM-SHA256 |  | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 
| ECDHE-ECDSA-AES128-SHA256 |  | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 
| ECDHE-ECDSA-AES128-SHA |  | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 
| ECDHE-ECDSA-AES256-GCM-SHA384 |  | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 
| ECDHE-ECDSA-AES256-SHA384 |  | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 
| ECDHE-ECDSA-AES256-SHA |  | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 

**Note**  
`TLS12_1_0_2016_01` is only available in the following AWS Regions: ap-east-1, ap-northeast-2, ap-south-1, ap-southeast-2, ca-central-1, cn-north-1, cn-northwest-1, eu-north-1, eu-west-2, eu-west-3, me-south-1, sa-east-1, us-east-2, us-gov-west-1, us-gov-west-2, us-west-1.  
`TLS12_1_0_2015_01` is only available in the following AWS Regions: ap-northeast-1, ap-southeast-1, eu-central-1, eu-west-1, us-east-1, us-west-2.

## Important notes for transport security in AWS IoT Core
<a name="tls-ssl-core"></a>

For devices that connect to AWS IoT Core using [MQTT](https://docs.aws.amazon.com//iot/latest/developerguide/mqtt.html), TLS encrypts the connection between the devices and the broker, and AWS IoT Core uses TLS client authentication to identify devices. For more information, see [Client authentication](https://docs.aws.amazon.com//iot/latest/developerguide/client-authentication.html). For devices that connect to AWS IoT Core using [HTTP](https://docs.aws.amazon.com//iot/latest/developerguide/http.html), TLS encrypts the connection between the devices and the broker, and authentication is delegated to AWS Signature Version 4. For more information, see [Signing requests with Signature Version 4](https://docs.aws.amazon.com//general/latest/gr/create-signed-request.html) in the *AWS General Reference*.

When you connect devices to AWS IoT Core, sending the [Server Name Indication (SNI) extension](https://tools.ietf.org/html/rfc3546#section-3.1) is not required but highly recommended. To use features such as [multi-account registration](https://docs.aws.amazon.com//iot/latest/developerguide/x509-client-certs.html#multiple-account-cert), [custom domains](https://docs.aws.amazon.com//iot/latest/developerguide/iot-custom-endpoints-configurable-custom.html), [VPC endpoints](https://docs.aws.amazon.com//iot/latest/developerguide/IoTCore-VPC.html), and [configured TLS policies](https://docs.aws.amazon.com//iot/latest/developerguide/iot-endpoints-tls-config.html), you must use the SNI extension and provide the complete endpoint address in the `host_name` field. The `host_name` field must contain the endpoint you are calling. That endpoint must be one of the following:
+ The `endpointAddress` returned by `aws iot [describe-endpoint](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iot/describe-endpoint.html) --endpoint-type iot:Data-ATS`
+ The `domainName` returned by `aws iot [describe-domain-configuration](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iot/describe-domain-configuration.html) –-domain-configuration-name "domain_configuration_name"`

Connections attempted by devices with the incorrect or invalid `host_name` value will fail. AWS IoT Core will log failures to CloudWatch for the authentication type of [Custom Authentication](https://docs.aws.amazon.com//iot/latest/developerguide/custom-authentication.html).

AWS IoT Core doesn't support the [SessionTicket TLS extension](https://www.ietf.org/rfc/rfc5077.txt).

## Transport security for LoRaWAN wireless devices
<a name="tls-lorawan"></a>

LoRaWAN devices follow the security practices described in [LoRaWAN ™ SECURITY: A White Paper Prepared for the LoRa Alliance™ by Gemalto, Actility, and Semtech](https://lora-alliance.org/sites/default/files/2019-05/lorawan_security_whitepaper.pdf). 

For more information about transport security with LoRaWAN devices, see [LoRaWAN data and transport security](https://docs.aws.amazon.com/iot-wireless/latest/developerguide/iot-lorawan-security.html).

# Data encryption in AWS IoT
<a name="data-encryption"></a>

Data protection refers to protecting data while in-transit (as it travels to and from AWS IoT Core) and at rest (while it is stored on devices or by other AWS services). All data sent to AWS IoT Core is sent over an TLS connection using MQTT, HTTPS, and WebSocket protocols, making it secure by default while in transit. AWS IoT Core collects data from devices and then sends it to other AWS services for further processing. For more information about data encryption on other AWS services, see the security documentation for that service. For more information, see [Data encryption at rest](encryption-at-rest.md).

FreeRTOS provides a PKCS\$111 library that abstracts key storage, accessing cryptographic objects and managing sessions. It is your responsibility to use this library to encrypt data at rest on your devices. For more information, see [ FreeRTOS Public Key Cryptography Standard (PKCS) \$111 Library](https://docs.aws.amazon.com/freertos/latest/userguide/security-pkcs.html).

# Data encryption at rest in AWS IoT Core
<a name="encryption-at-rest"></a>

By default, all AWS IoT Core data at rest is encrypted using AWS owned keys. AWS IoT Core also supports symmetric customer managed keys from AWS Key Management Service (AWS KMS). With customer managed keys, you can create, own, and manage the AWS KMS keys in your AWS account. AWS IoT Core will use your KMS keys to encrypt your data at rest. You have full control over these KMS keys, including creating and maintaining their key policies. You can also configure IAM policies for the roles that access AWS KMS to control permissions for these keys.

## AWS owned keys
<a name="aws-owned-keys"></a>

AWS owned keys are a collection of KMS keys that an AWS service owns and manages for use in multiple AWS accounts. AWS services can use AWS owned keys to protect your data. By default, AWS IoT Core encrypts data at rest using AWS owned keys. These keys are managed by the service. You can't view, manage, or use AWS owned keys. However, you don't need to take any actions to protect these keys.

For more information about AWS owned keys, see [AWS owned keys](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#aws-owned-key) in the *AWS Key Management Service Developer Guide*.

## Customer managed keys
<a name="customer-managed-keys"></a>

Customer managed keys are KMS keys in your AWS account that you create, own, and manage. You have full control over these AWS KMS keys, including creating and maintaining their key policies. You can also configure IAM policies for the roles that access AWS KMS to control permissions for these keys. You can configure AWS IoT Core to use customer managed KMS keys to encrypt your data.

For more information about customer managed keys, see [Customer managed keys](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#customer-cmk) in the *AWS Key Management Service Developer Guide*.

To opt in to customer managed keys in AWS IoT Core, follow these steps:

**Topics**
+ [Step 1: Create a customer managed key](#encryption-at-rest-cmk-create)
+ [Step 2: Create an IAM role to grant AWS IoT Core permissions to use the KMS key](#create-an-iam-role)
+ [Step 3: Opt in to customer managed keys in AWS IoT Core](#opt-in-customer-managed-keys)
+ [Step 4: Additional permissions required for AWS IoT Core control plane operations](#cmk-control-plane-permissions)
+ [Step 5: Managing keys](#understanding-key-health)
+ [Step 6: Monitoring key health](#health-status-monitoring)

### Step 1: Create a customer managed key
<a name="encryption-at-rest-cmk-create"></a>

You can create a symmetric customer managed key by using the AWS KMS console or the AWS KMS CLI commands. The `keySpec` must be `SYMMETRIC_DEFAULT` and the `keyUsage` must be `ENCRYPT_DECRYPT`.

**Note**  
AWS IoT Core only supports AWS KMS keys with `SYMMETRIC_DEFAULT` key spec and `ENCRYPT_DECRYPT` key usage for customer managed keys.

The following is an example AWS CLI command to create a KMS key which can be used with AWS IoT Core for customer managed keys.

```
aws kms create-key --key-spec SYMMETRIC_DEFAULT --key-usage ENCRYPT_DECRYPT --region us-west-2
```

The following is an example output of the command.

```
{
    "KeyMetadata": {
        "AWSAccountId": "111122223333",
        "KeyId": "1234abcd-12ab-34cd-56ef-1234567890ab",
        "Arn": "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab",
        "CreationDate": "2024-09-19T11:45:23.982000-07:00",
        "Enabled": true,
        "Description": "",
        "KeyUsage": "ENCRYPT_DECRYPT",
        "KeyState": "Enabled",
        "Origin": "AWS_KMS",
        "KeyManager": "CUSTOMER",
        "CustomerMasterKeySpec": "SYMMETRIC_DEFAULT",
        "KeySpec": "SYMMETRIC_DEFAULT",
        "EncryptionAlgorithms": [
            "SYMMETRIC_DEFAULT"
        ],
        "MultiRegion": false
    }
}
```

For more information, see [Creating a symmetric customer managed key](https://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html#create-symmetric-cmk) in the *AWS Key Management Service Developer Guide*.

#### Key policy
<a name="key-policy"></a>

When creating a customer managed key, you can specify a key policy. Key policies control access to your customer managed key. Every customer managed key must have exactly one key policy, which contains statements that determine who can use the key and how they can use it. For more information, see [Key policies](https://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html) in the *AWS Key Management Service Developer Guide*.

AWS IoT Core uses an IAM role in your account to access your customer managed key. If you're using a custom key policy, make sure the IAM role created on this key has the following permissions:
+ `kms:DescribeKey`
+ `kms:Decrypt`
+ `kms:Encrypt`
+ `kms:GenerateDataKeyWithoutPlaintext`
+ `kms:ReEncryptTo`
+ `kms:ReEncryptFrom`

### Step 2: Create an IAM role to grant AWS IoT Core permissions to use the KMS key
<a name="create-an-iam-role"></a>

For AWS IoT Core to use the KMS key you created to encrypt your data at rest, you also need to create an IAM role in your account, which AWS IoT Core can assume to access the KMS key.

The role must have the following trust policy to allow AWS IoT Core to assume the role.

```
{
    "Version": "2012-10-17",		 	 	 
    "Statement": {
        "Effect": "Allow",
        "Principal": {
            "Service": "iot.amazonaws.com"
        },
        "Action": "sts:AssumeRole",
        "Condition": {
            "StringEquals": {
                "aws:SourceAccount": "111122223333"
            },
            "ArnLike": {
                "aws:SourceArn": "arn:aws:iot:us-west-2:111122223333:*"
            }
        }
    }
}
```

Ensure the IAM policies attached to the IAM role have the following permissions on the KMS key:
+ `kms:DescribeKey`
+ `kms:Decrypt`
+ `kms:Encrypt`
+ `kms:GenerateDataKeyWithoutPlaintext`
+ `kms:ReEncryptTo`
+ `kms:ReEncryptFrom`

The following is an example IAM policy with the required permissions for customer managed keys.

```
{
    "Version": "2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "AllowIoTToAccessKMSResource",
            "Effect": "Allow",
            "Action": [
                "kms:DescribeKey",
                "kms:Decrypt",
                "kms:Encrypt",
                "kms:ReEncryptTo",
                "kms:ReEncryptFrom",
                "kms:GenerateDataKeyWithoutPlaintext"
            ],
            "Resource": [
                "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab"
            ],
            "Condition": {
                "StringEquals": {
                    "kms:EncryptionContext:aws-crypto-ec:vendor": "iot.amazonaws.com"
                }
            }
        }
    ]
}
```

For more information, see [Create a role to delegate permissions to an IAM user](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user.html) in the *AWS Identity and Access Management User Guide*.

### Step 3: Opt in to customer managed keys in AWS IoT Core
<a name="opt-in-customer-managed-keys"></a>

After you complete all the previous steps, run the `update-encryption-configuration` CLI command to opt in using customer managed keys in AWS IoT Core. When you opt in to customer managed keys, all AWS IoT Core resources in your AWS account will be encrypted using the specified AWS KMS key.

1. To opt in to customer managed keys in AWS IoT Core using AWS CLI, run the `update-encryption-configuration` CLI command.

   ```
   aws iot update-encryption-configuration --encryption-type "CUSTOMER_MANAGED_KMS_KEY" \
   --kms-access-role-arn "arn:aws:iam::111122223333:role/myrole" \
   --kms-key-arn "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab" --region us-west-2
   ```

1. To verify customer managed keys in AWS IoT Core using AWS CLI, run the `describe-encryption-configuration` CLI command:

   ```
   aws iot describe-encryption-configuration --region us-west-2
   ```

   If you have enabled customer managed keys in AWS IoT Core, the output can look like the following:

   ```
   {
       "encryptionType": "CUSTOMER_MANAGED_KMS_KEY",
       "kmsKeyArn": "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab",
       "kmsAccessRoleArn": "arn:aws:iam::111122223333:role/myrole",
       "configurationDetails": {
           "configurationStatus": "HEALTHY"
       },
       "lastModifiedDate": "2024-09-26T22:01:02.365000-07:00"
   }
   ```

   The `lastModifiedDate` field indicates the date when the encryption configuration was last updated.

   If you haven't enabled customer managed keys, the output can look like the following:

   ```
   {
       "encryptionType": "AWS_OWNED_KMS_KEY",
       "lastModifiedDate": "2024-09-26T22:01:02.365000-07:00"
   }
   ```

### Step 4: Additional permissions required for AWS IoT Core control plane operations
<a name="cmk-control-plane-permissions"></a>

After you opt in to customer managed keys, all the AWS IoT Core resources belonging to your AWS account are encrypted with the provided KMS key. All control plane operations now require the caller to have `kms:Decrypt` permissions on the KMS key in addition to the permissions required for the specific operation on the AWS IoT Core resource. If the caller does not have `kms:Decrypt` permission and they make an API call that requires encryption or decryption of data (for example, `GetPolicy`), they will receive an `UnauthorizedException`.

For example, when you call `GetPolicy`, you need both `iot:GetPolicy` and `kms:Decrypt` permissions on your customer managed KMS key for the API call to succeed.

**Note**  
When updating IAM users or roles to grant AWS KMS permissions on the key used for your encryption configuration, ensure the KMS key policy also grants the required permissions to the respective IAM users or roles.

#### AWS KMS permissions for `UpdateEncryptionConfiguration`
<a name="kms-permissions-update-encryption-configuration"></a>

The `UpdateEncryptionConfiguration` API call needs the following AWS KMS permissions on the KMS key to be able to opt in to customer managed keys or to modify the key configuration:
+ `kms:DescribeKey`
+ `kms:Decrypt`
+ `kms:Encrypt`
+ `kms:GenerateDataKeyWithoutPlaintext`
+ `kms:ReEncryptTo`
+ `kms:ReEncryptFrom`

#### AWS KMS permissions for all other control plane APIs
<a name="kms-permissions-control-plane-apis"></a>

Most control plane APIs require `kms:Decrypt` permissions when customer managed keys are enabled. However, certain APIs do not require these additional permissions:

APIs that do not require AWS KMS permissions  
The `List*` and `Delete*` APIs do not fall into this bucket. Customers can always invoke any `List*` or `Delete*` control plane API and those API calls would succeed even if the caller does not have `kms:Decrypt` permission. These API calls will succeed even if your customer managed key is unhealthy as `List*` and `Delete*` APIs do not do any decryption.  
+ **List\$1 APIs** – All listing operations (for example, `ListThings`, `ListPolicies`, `ListCertificates`)
+ **Delete\$1 APIs** – All deletion operations (for example, `DeleteThing`, `DeletePolicy`, `DeleteCertificate`)

### Step 5: Managing keys
<a name="understanding-key-health"></a>

AWS IoT Core runs periodic checks on your customer managed key configuration to ensure encrypt and decrypt operations are not impacted. These health checks run once every minute and verify AWS IoT Core's ability to access and use both the AWS KMS key and the associated IAM role for encrypt and decrypt operations.

HEALTHY  
AWS IoT Core can successfully access the AWS KMS key through the specified IAM role and perform encryption/decryption operations. All components function correctly.

UNHEALTHY  
AWS IoT Core can't access or use the AWS KMS key. This prevents new encryption operations and may impact service functionality. The `errorCode` field indicates whether the issue is with the key or the IAM role.

#### Customer actions that can impact key health
<a name="customer-actions-affecting-health"></a>

Several customer actions can cause the key health status to change from `HEALTHY` to `UNHEALTHY`:

Key-related actions  
+ **Deleting an AWS KMS key** – When you schedule a key deletion, it's in a `Pending deletion` status and can't be used
+ **Disabling an AWS KMS key** – When you disable a KMS key, it can no longer be used for encrypt / decrypt operations
+ **Scheduling key for deletion** – Key becomes unusable when deletion completes
+ **Modifying key policy** – Removing necessary permissions for AWS IoT Core access
+ **Changing key usage permissions** – Restricting required AWS KMS actions

IAM role-related actions  
+ **Deleting the IAM role** – AWS IoT Core can't assume the role to access the key
+ **Modifying role permissions** – Removing required AWS KMS permissions from the role policy
+ **Changing trust policy** – Preventing AWS IoT Core service from assuming the role
+ **Adding restrictive conditions** – Conditions that prevent AWS IoT Core from using the role

Account-level actions  
+ **Cross-account key access changes** – Modifying permissions for keys in different accounts
+ **Service Control Policies (SCPs)** – Organization-level policies that restrict AWS KMS access
+ **Account-level IAM policies** – Policies that override or conflict with key access

**Important**  
Any changes to AWS KMS keys, IAM roles, or policies used by AWS IoT Core should be tested in development environments first. Monitor the key health status closely after making any changes to ensure AWS IoT Core functionality is not impacted.

#### Updating encryption configuration
<a name="key-transition"></a>

Update your encryption configuration in AWS IoT Core to change from one customer managed key to another, or between AWS owned keys and customer managed keys.

To change the configuration to a different customer managed key:

1. Create a new customer managed key following the steps in [Step 1: Create a customer managed key](#encryption-at-rest-cmk-create).

1. Update your IAM role policy to include permissions for both the old and new keys during the update period.

1. Update your encryption configuration to use the new key:

   ```
   aws iot update-encryption-configuration --encryption-type "CUSTOMER_MANAGED_KMS_KEY" \
   --kms-access-role-arn "arn:aws:iam::111122223333:role/myrole" \
   --kms-key-arn "arn:aws:kms:us-west-2:111122223333:key/new-key-id"
   ```

To change the configuration from customer managed keys back to AWS owned keys:

```
aws iot update-encryption-configuration --encryption-type "AWS_OWNED_KMS_KEY"
```

**Note**  
When updating the encryption configuration for new customer managed keys, ensure both the old and new keys remain accessible for the operation to succeed.

##### Common failure scenarios and impacts
<a name="failure-scenarios"></a>

The following table describes common failure scenarios when keys are deleted or deactivated:


| Scenario | Immediate Impact | Long-term Consequences | 
| --- | --- | --- | 
|  Key disabled  |  All new encryption/decryption operations fail immediately  |  Service disruption until the key is re-enabled or replaced  | 
|  Key scheduled for deletion  |  Key status is changed to pending deletion and all encryption/decryption operations will fail  |  Automatic service failure when deletion completes  | 
|  Key permanently deleted  |  Immediate and permanent failure of all operations  |  Permanent data loss and inability to recover encrypted data  | 
|  Key policy modified incorrectly  |  AWS IoT Core loses access permissions to the key  |  Service failures until policy is corrected  | 
|  IAM role deleted  |  AWS IoT Core can't assume role to access key  |  Complete encryption service failure  | 
|  IAM role is modified incorrectly  |  AWS IoT Core can't assume role or use role to access key  |   Service failures until IAM role is corrected  | 

##### Prevention and best practices
<a name="prevention-best-practices"></a>

To prevent accidental key deletion or deactivation and minimize the risk of service failures:

Implement key lifecycle policies  
Establish clear procedures for key creation, rotation, and retirement. Document which keys are used by which AWS IoT Core resources and maintain an inventory of active keys.

Use IAM policies to restrict key deletion  
Create IAM policies that prevent unauthorized users from deleting or disabling critical encryption keys. Use conditions to require additional approval for key deletion operations.

Enable CloudTrail logging  
Monitor all AWS KMS key operations through CloudTrail to detect unauthorized or accidental key management activities. Set up alerts for key deletion, disabling, or policy changes.

Test key replacement procedures  
Regularly test your key replacement procedures in non-production environments to ensure you can quickly recover from key-related failures.

Maintain key backups  
While you can't export AWS KMS key material, maintain detailed records of key ARNs, policies, and associated AWS IoT Core configurations to facilitate rapid key replacement if needed.

Monitor key health  
Continuously monitor the `CMK.Health` metric and set up automated alerts for key health status changes. Implement automated responses to quickly address key-related issues.

**Important**  
Always test key update procedures in development environments before implementing them in production. Have a documented rollback plan and ensure that key replacement procedures can be executed quickly in case of emergencies.

### Step 6: Monitoring key health
<a name="health-status-monitoring"></a>

As part of the periodic checks AWS IoT Core runs, CloudWatch metrics and logs are emitted to provide visibility on the health status of your customer managed key configuration

AWS IoT Core emits the `CMK.Health` metric to CloudWatch at least once every minute. The metric provides information about the health status of the customer managed keys used by AWS IoT Core for encrypting and decrypting your data.

The `CMK.Health` metric can have the following values:
+ The value is `1`: AWS IoT Core is able to use the encryption keys successfully for encrypting and decrypting your data.
+ The value is `0`: AWS IoT Core is unable to use the encryption keys for encrypting and decrypting your data.

AWS IoT Core also emits AWS IoT V2 logs when the health status of the encryption keys changes. These logs provide additional details about the health status update. To view these logs, you must enable AWS IoT V2 logs. The `HEALTHY` logs are emitted at `INFO` level, and the `UNHEALTHY` logs are emitted at `ERROR` level. For more information about the log levels, see [Log levels](https://docs.aws.amazon.com/iot/latest/developerguide/configure-logging.html#log-level).

The following examples are CloudWatch log entries emitted by AWS IoT Core to indicate the health status update of the customer managed keys.

To effectively monitor and respond to key health status changes:

1. **Set up CloudWatch alarms** for the `CMK.Health` metric:

   ```
   aws cloudwatch put-metric-alarm --region us-west-2 \
     --alarm-name "IoTCore-CMK-Health-Alert" \
     --alarm-description "Alert when IoT Core CMK health is unhealthy" \
     --metric-name "CMK.Health" \
     --namespace "AWS/IoT" \
     --statistic "Minimum" \
     --period 300 \
     --evaluation-periods 1 \
     --threshold 1 \
     --comparison-operator "LessThanThreshold" \
     --alarm-actions "arn:aws:sns:us-west-2:111122223333:iot-alerts"
   ```

1. **Enable AWS IoT V2 logging** to capture detailed health status change events with error codes and messages.

1. **Check configuration status** for troubleshooting:

   ```
   aws iot describe-encryption-configuration --region us-west-2
   ```

1. **Investigate UNHEALTHY status** by examining the `errorCode` field:
   + `KMS_KEY_VALIDATION_ERROR` – Issue with the AWS KMS key (disabled, deleted, or policy problems)
   + `ROLE_VALIDATION_ERROR` – Issue with the IAM role (deleted, policy problems, or trust issues)

#### From UNHEALTHY to HEALTHY
<a name="unhealthy-to-healthy"></a>

When the status of the encryption keys is updated from `UNHEALTHY` to `HEALTHY`, AWS IoT Core will emit an AWS IoT V2 log message in the following format.

```
{
    "timestamp": "2017-08-10 15:37:23.476",
    "logLevel": "INFO",
    "traceId": "8421693b-f4f0-4e4a-9235-0cff8bab897d",
    "accountId": "111122223333",
    "status": "SUCCESS",
    "cmkStatus": "HEALTHY",
    "kmsKeyArn": "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab",
    "kmsAccessRoleArn": "arn:aws:iam::111122223333:role/myrole",
    "eventType": "CmkHealthCheck"
}
```

#### From HEALTHY to UNHEALTHY
<a name="healthy-to-unhealthy"></a>

When the status of the encryption keys is updated from `HEALTHY` to `UNHEALTHY`, AWS IoT Core will emit an AWS IoT V2 log message in the following format.

```
{
    "timestamp": "2017-08-10 15:37:23.476",
    "logLevel": "ERROR",
    "traceId": "8421693b-f4f0-4e4a-9235-0cff8bab897d",
    "accountId": "111122223333",
    "status": "FAILURE",
    "cmkStatus": "UNHEALTHY",
    "errorCode": "KMS_KEY_VALIDATION_ERROR / ROLE_VALIDATION_ERROR",
    "errorMessage": "Error message on why there was a failure",
    "kmsKeyArn": "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab",
    "kmsAccessRoleArn": "arn:aws:iam::111122223333:role/myrole",
    "eventType": "CmkHealthCheck"
}
```

**Warning**  
When key health becomes `UNHEALTHY`, AWS IoT Core operations fail immediately. If this occurs, review your key configurations, IAM role permissions, and policies. Monitor the `CMK.Health` metric for status changes. If operations continue to fail after reviewing your configurations, contact your account manager or the [AWS Support Center](https://console.aws.amazon.com/support/home#/) for additional assistance.

#### AWS CloudTrail events
<a name="aws-cloudtrail-events"></a>

You can also monitor AWS IoT Core's usage of the KMS key for encrypt decrypt operations. AWS IoT Core will make `DescribeKey`, `Decrypt`, `ReEncrypt`, and `GenerateDataKeyWithoutPlaintext` operations on your KMS key to encrypt / decrypt data belonging to your AWS account stored at rest.

There are CloudTrail events for `DescribeKey`, `Decrypt`, `ReEncrypt`, and `GenerateDataKeyWithoutPlaintext`. These events monitor AWS KMS operations called by AWS IoT Core to access data encrypted by your customer managed key.

##### `Decrypt` example
<a name="decrypt"></a>

```
{
    "eventVersion": "1.09",
    "userIdentity": {
        "type": "AssumedRole",
        "principalId": "AROAIGDTESTANDEXAMPLE:Sampleuser01",
        "arn": "arn:aws:sts::111122223333:assumed-role/Admin/Sampleuser01",
        "accountId": "111122223333",
        "accessKeyId": "*********************",
        "sessionContext": {
            "sessionIssuer": {
                "type": "Role",
                "principalId": "AROAIGDTESTANDEXAMPLE:Sampleuser01",
                "arn": "arn:aws:sts::111122223333:assumed-role/Admin/Sampleuser01",
                "accountId": "111122223333",
                "userName": "*****"
            },
            "attributes": {
                "creationDate": "2024-09-16T20:23:39Z",
                "mfaAuthenticated": "false"
            }
        },
        "invokedBy": "iot.amazonaws.com"
    },
    "eventTime": "2024-09-16T20:32:48Z",
    "eventSource": "kms.amazonaws.com",
    "eventName": "Decrypt",
    "awsRegion": "us-west-2",
    "sourceIPAddress": "iot.amazonaws.com",
    "userAgent": "iot.amazonaws.com",
    "requestParameters": {
        "encryptionContext": {
            "kms-arn": "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab",
            "aws-crypto-ec:vendor": "iot.amazonaws.com",
            "branch-key-id": "111122223333",
            "type": "branch:ACTIVE"
        },
        "encryptionAlgorithm": "SYMMETRIC_DEFAULT",
        "keyId": "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab"
    },
    "responseElements": null,
    "requestID": "1afb6d98-8388-455d-8b48-e62c9e0cf7f4",
    "eventID": "b59a5f16-0d98-46d8-a590-0e040a48b39b",
    "readOnly": true,
    "resources": [
        {
            "accountId": "111122223333",
            "type": "AWS::KMS::Key",
            "ARN": "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab"
        }
    ],
    "eventType": "AwsApiCall",
    "managementEvent": true,
    "recipientAccountId": "111122223333",
    "eventCategory": "Management"
}
```