

# AWS IoT Core policies


AWS IoT Core policies are JSON documents. They follow the same conventions as IAM policies. AWS IoT Core supports named policies so many identities can reference the same policy document. Named policies are versioned so they can be easily rolled back.

AWS IoT Core policies allow you to control access to the AWS IoT Core data plane. The AWS IoT Core data plane consists of operations that allow you to connect to the AWS IoT Core message broker, send and receive MQTT messages, and get or update a thing's Device Shadow.

An AWS IoT Core policy is a JSON document that contains one or more policy statements. Each statement contains:
+ `Effect`, which specifies whether the action is allowed or denied.
+ `Action`, which specifies the action the policy is allowing or denying.
+ `Resource`, which specifies the resource or resources on which the action is allowed or denied.

Changes made to a policy can take anywhere between 6 and 8 minutes to become effective because of how AWS IoT caches the policy documents. That is, it may take a few minutes to access a resource that has recently been granted access, and a resource may be accessible for several minutes after its access has been revoked.

AWS IoT Core policies can be attached to X.509 certificates, Amazon Cognito identities, and thing groups. The policies attached to a thing group apply to any thing within that group. For the policy to take effect, the `clientId` and the thing name must match. AWS IoT Core policies follow the same policy evaluation logic as IAM policies. By default, all policies are implicitly denied. An explicit allow in any identity-based or resource-based policy overrides the default behavior. An explicit deny in any policy overrides any allows. For more information, see [Policy evaluation logic](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_evaluation-logic.html#policy-eval-denyallow) in the *AWS Identity and Access Management User Guide*.

**Topics**
+ [

# AWS IoT Core policy actions
](iot-policy-actions.md)
+ [

# AWS IoT Core action resources
](iot-action-resources.md)
+ [

# AWS IoT Core policy variables
](iot-policy-variables.md)
+ [

# Cross-service confused deputy prevention
](cross-service-confused-deputy-prevention.md)
+ [

# AWS IoT Core policy examples
](example-iot-policies.md)
+ [

# Authorization with Amazon Cognito identities
](cog-iot-policies.md)

# AWS IoT Core policy actions


The following policy actions are defined by AWS IoT Core:MQTT Policy Actions

`iot:Connect`  
Represents the permission to connect to the AWS IoT Core message broker. The `iot:Connect` permission is checked every time a `CONNECT` request is sent to the broker. The message broker doesn't allow two clients with the same client ID to stay connected at the same time. After the second client connects, the broker closes the existing connection. Use the `iot:Connect` permission to ensure only authorized clients using a specific client ID can connect.

`iot:DeleteConnection`  
Represents the permission to disconnect a connected MQTT client from AWS IoT Core. The `iot:DeleteConnection` permission is checked every time a request is made to forcibly disconnect a client. When you disconnect a client, AWS IoT Core closes the client's network connection and optionally cleans the session state.

`iot:GetRetainedMessage`  
Represents the permission to get the contents of a single retained message. Retained messages are the messages that were published with the RETAIN flag set and stored by AWS IoT Core. For permission to get a list of all the account's retained messages, see [iot:ListRetainedMessages](#action_listretainedmessages).

`iot:ListRetainedMessages`  
Represents the permission to retrieve summary information about the account's retained messages, but not the contents of the messages. Retained messages are the messages that were published with the RETAIN flag set and stored by AWS IoT Core. The resource ARN specified for this action must be `*`. For permission to get the contents of a single retained message, see [iot:GetRetainedMessage](#action_getretainpublish).

`iot:Publish`  
Represents the permission to publish an MQTT topic. This permission is checked every time a PUBLISH request is sent to the broker. You can use this to allow clients to publish to specific topic patterns.  
To grant `iot:Publish` permission, you must also grant `iot:Connect` permission.

`iot:Receive`  
Represents the permission to receive a message from AWS IoT Core. The `iot:Receive` permission is confirmed every time a message is delivered to a client. Because this permission is checked on every delivery, you can use it to revoke permissions to clients that are currently subscribed to a topic.

`iot:RetainPublish`  
Represents the permission to publish an MQTT message with the RETAIN flag set.  
To grant `iot:RetainPublish` permission, you must also grant `iot:Publish` permission.

`iot:Subscribe`  
Represents the permission to subscribe to a topic filter. This permission is checked every time a SUBSCRIBE request is sent to the broker. Use it to allow clients to subscribe to topics that match specific topic patterns.  
To grant `iot:Subscribe` permission, you must also grant `iot:Connect` permission.Device Shadow Policy Actions

`iot:DeleteThingShadow`  
Represents the permission to delete a thing's Device Shadow. The `iot:DeleteThingShadow` permission is checked every time a request is made to delete a thing's Device Shadow contents.

`iot:GetThingShadow`  
Represents the permission to retrieve a thing's Device Shadow. The `iot:GetThingShadow` permission is checked every time a request is made to retrieve a thing's Device Shadow contents.

`iot:ListNamedShadowsForThing`  
Represents the permission to list a thing's named Shadows. The `iot:ListNamedShadowsForThing` permission is checked every time a request is made to list a thing's named Shadows.

`iot:UpdateThingShadow`  
Represents the permission to update a device's shadow. The `iot:UpdateThingShadow` permission is checked every time a request is made to update a thing's Device Shadow contents.

**Note**  
The job execution policy actions apply only for the HTTP TLS endpoint. If you use the MQTT endpoint, you must use MQTT policy actions defined in this topic.  
For an example of a job execution policy that demonstrates this, see [Basic job policy example](basic-jobs-example.md) that works with the MQTT protocol.Job Executions AWS IoT Core Policy Actions

`iotjobsdata:DescribeJobExecution`  
Represents the permission to retrieve a job execution for a given thing. The `iotjobsdata:DescribeJobExecution` permission is checked every time a request is made to get a job execution.

`iotjobsdata:GetPendingJobExecutions`  
Represents the permission to retrieve the list of jobs that are not in a terminal status for a thing. The `iotjobsdata:GetPendingJobExecutions` permission is checked every time a request is made to retrieve the list. 

`iotjobsdata:UpdateJobExecution`  
Represents the permission to update a job execution. The `iotjobsdata:UpdateJobExecution` permission is checked every time a request is made to update the state of a job execution.

`iotjobsdata:StartNextPendingJobExecution`  
Represents the permission to get and start the next pending job execution for a thing. (That is, to update a job execution with status QUEUED to IN\$1PROGRESS.) The `iotjobsdata:StartNextPendingJobExecution` permission is checked every time a request is made to start the next pending job execution.AWS IoT Core Credential Provider Policy Action

`iot:AssumeRoleWithCertificate`  
Represents the permission to call AWS IoT Core credential provider to assume an IAM role with certificate-based authentication. The `iot:AssumeRoleWithCertificate` permission is checked every time a request is made to AWS IoT Core credential provider to assume a role.

# AWS IoT Core action resources


To specify a resource for an AWS IoT Core policy action, use the Amazon Resource Name (ARN) of the resource. All resource ARNs follow the following format:

```
arn:partition:iot:region:AWS-account-ID:Resource-type/Resource-name
```

The following table shows the resource to specify for each action type. The ARN examples are for the account ID `123456789012`, in the partition `aws`, and specific to the region `us-east-1`. For more information about the formats for ARNs, see [Amazon Resource Names (ARNs)](https://docs.aws.amazon.com//IAM/latest/UserGuide/reference-arns.html) from the AWS Identity and Access Management User Guide.


| Action | Resource type | Resource name | ARN example | 
| --- | --- | --- | --- | 
| iot:Connect | client |  The client's client ID  | arn:aws:iot:us-east-1:123456789012:client/myClientId | 
| iot:DeleteConnection | client |  The client's client ID  | arn:aws:iot:us-east-1:123456789012:client/myClientId | 
| iot:DeleteThingShadow | thing |  The thing's name, and the shadow's name, if applicable  |  arn:aws:iot:us-east-1:123456789012:thing/thingOne arn:aws:iot:us-east-1:123456789012:thing/thingOne/shadowOne  | 
| iotjobsdata:DescribeJobExecution | thing |  The thing's name  |  arn:aws:iot:us-east-1:123456789012:thing/thingOne  | 
| iotjobsdata:GetPendingJobExecutions | thing |  The thing's name  |  arn:aws:iot:us-east-1:123456789012:thing/thingOne  | 
| iot:GetRetainedMessage | topic |  A retained message topic  |  arn:aws:iot:us-east-1:123456789012:topic/myTopicName  | 
| iot:GetThingShadow | thing |  The thing's name, and the shadow's name, if applicable  |  arn:aws:iot:us-east-1:123456789012:thing/thingOne arn:aws:iot:us-east-1:123456789012:thing/thingOne/shadowOne  | 
| iot:ListNamedShadowsForThing | All | All |  \$1 | 
| iot:ListRetainedMessages | All | All |  \$1 | 
| iot:Publish | topic |  A topic string  | arn:aws:iot:us-east-1:123456789012:topic/myTopicName | 
| iot:Receive | topic |  A topic string  | arn:aws:iot:us-east-1:123456789012:topic/myTopicName | 
| iot:RetainPublish | topic |  A topic to publish with the RETAIN flag set  |  arn:aws:iot:us-east-1:123456789012:topic/myTopicName  | 
| iotjobsdata:StartNextPendingJobExecution | thing |  The thing's name  |  arn:aws:iot:us-east-1:123456789012:thing/thingOne  | 
| iot:Subscribe | topicfilter | A topic filter string | arn:aws:iot:us-east-1:123456789012:topicfilter/myTopicFilter | 
| iotjobsdata:UpdateJobExecution | thing |  The thing's name  |  arn:aws:iot:us-east-1:123456789012:thing/thingOne  | 
| iot:UpdateThingShadow | thing |  The thing's name, and the shadow's name, if applicable  |  arn:aws:iot:us-east-1:123456789012:thing/thingOne arn:aws:iot:us-east-1:123456789012:thing/thingOne/shadowOne  | 
| iot:AssumeRoleWithCertificate | rolealias |  A role alias that points to a role ARN  |  arn:aws:iot:us-east-1:123456789012:rolealias/CredentialProviderRole\$1alias | 

# AWS IoT Core policy variables


AWS IoT Core defines policy variables that can be used in AWS IoT Core policies in the `Resource` or `Condition` block. When a policy is evaluated, the policy variables are replaced by actual values. For example, if a device is connected to the AWS IoT Core message broker with a client ID of 100-234-3456, the `iot:ClientId` policy variable is replaced in the policy document by 100-234-3456.

AWS IoT Core policies can use wildcard characters and follow a similar convention to IAM policies. Inserting an `*` (asterik) in the string can be treated as a wildcard, matching any characters. For example, you can use `*` to describe multiple MQTT topic names in the `Resource` attribute of a policy. The characters `+` and `#` are treated as literal strings in a policy. For an example policy that shows how to use wildcards, see [Using wildcard characters in MQTT and AWS IoT Core policies](pub-sub-policy.md#pub-sub-policy-cert).

You can also use predefined policy variables with fixed values to represent characters that otherwise have special meaning. These special characters include `$(*)`, `$(?)`, and `$($)`. For more information about policy variables and the special characters, see [IAM Policy elements: Variables and tags](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_variables.html) and [Creating a condition with multiple keys or values](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_multi-value-conditions.html).

**Topics**
+ [

# Basic AWS IoT Core policy variables
](basic-policy-variables.md)
+ [

# Thing policy variables
](thing-policy-variables.md)
+ [

# X.509 Certificate AWS IoT Core policy variables
](cert-policy-variables.md)

# Basic AWS IoT Core policy variables


AWS IoT Core defines the following basic policy variables:
+ `aws:SourceIp`: The IP address of the client connected to the AWS IoT Core message broker.
+ `iot:ClientId`: The client ID used to connect to the AWS IoT Core message broker.
+ `iot:DomainName`: The domain name of the client connected to AWS IoT Core.

**Topics**
+ [

## Examples of `ClientId` and `SourceIp` policy variables
](#basic-policy-variables-example)
+ [

## Examples of `iot:DomainName` policy variable
](#basic-policy-variables-example-domain)

## Examples of `ClientId` and `SourceIp` policy variables


The following AWS IoT Core policy shows a policy that uses policy variables. `aws:SourceIp` can be used in the Condition element of your policy to allow principals to make API requests only within a specific address range. For examples, see [Authorizing users and cloud services to use AWS IoT Jobs](iam-policy-users-jobs.md).

****  

```
{
	"Version":"2012-10-17",		 	 	 
	"Statement": [
		{
			"Effect": "Allow",
			"Action": [
				"iot:Connect"
			],
			"Resource": [
				"arn:aws:iot:us-east-1:123456789012:client/clientid1"
			]
		},
		{
			"Effect": "Allow",
			"Action": [
				"iot:Publish"
			],
			"Resource": [
				"arn:aws:iot:us-east-1:123456789012:topic/my/topic/${iot:ClientId}"
			],
			"Condition": {
				"IpAddress": {
					"aws:SourceIp": "123.45.167.89"
				}
			}
		}
	]
}
```

In these examples, `${iot:ClientId}` is replaced by the ID of the client connected to the AWS IoT Core message broker when the policy is evaluated. When you use policy variables like `${iot:ClientId}`, you can inadvertently open access to unintended topics. For example, if you use a policy that uses `${iot:ClientId}` to specify a topic filter:

```
{
	"Effect": "Allow",
	"Action": [
		"iot:Subscribe"
	],
	"Resource": [
		"arn:aws:iot:us-east-1:123456789012:topicfilter/my/${iot:ClientId}/topic"
	]
}
```

A client can connect using `+` as the client ID. This would allow the user to subscribe to any topic that matches the topic filter `my/+/topic`. To protect against such security gaps, use the `iot:Connect` policy action to control which client IDs can connect. For example, this policy allows only those clients whose client ID is `clientid1` to connect:

****  

```
{
	"Version":"2012-10-17",		 	 	 
	"Statement": [
		{
			"Effect": "Allow",
			"Action": [
				"iot:Connect"
			],
			"Resource": [
				"arn:aws:iot:us-east-1:123456789012:client/clientid"
			]
		}
	]
}
```

**Note**  
Using the policy variable `${iot:ClientId}` with `Connect` is not recommended. There is no check on the value of `ClientId`, so an attacher with a different client's ID can pass the validation but cause disconnection. Because any `ClientId` is allowed, setting a random client ID can bypass thing group policies.

## Examples of `iot:DomainName` policy variable


You can add the `iot:DomainName` policy variable to restrict which domains are allowed to use. Adding the `iot:DomainName` policy variable allows devices to connect to only specific configured endpoints.

The following policy allows devices to connect to the specified domain.

****  

```
{
	"Version":"2012-10-17",		 	 	 
	"Statement": {
		"Sid": "AllowConnectionsToSpecifiedDomain",
		"Effect": "Allow",
		"Action": [
			"iot:Connect"
		],
		"Resource": "arn:aws:iot:us-east-1:123456789012:client/clientid",
		"Condition": {
			"StringEquals": {
				"iot:DomainName": "d1234567890abcdefghij-ats.iot.us-east-1.amazonaws.com"
			}
		}
	}
}
```

The following policy denies devices to connect to the specified domain.

****  

```
{
	"Version":"2012-10-17",		 	 	 
	"Statement": {
		"Sid": "DenyConnectionsToSpecifiedDomain",
		"Effect": "Deny",
		"Action": [
			"iot:Connect"
		],
		"Resource": "arn:aws:iot:us-east-1:123456789012:client/clientid",
		"Condition": {
			"StringEquals": {
				"iot:DomainName": "d1234567890abcdefghij-ats.iot.us-east-1.amazonaws.com"
			}
		}
	}
}
```

For more information about policy conditional operator, see [IAM JSON policy elements: Condition operators](https://docs.aws.amazon.com//IAM/latest/UserGuide/reference_policies_elements_condition_operators.html). For more information about domain configurations, see [What is a domain configuration?](https://docs.aws.amazon.com//iot/latest/developerguide/iot-custom-endpoints-configurable.html).

# Thing policy variables


Thing policy variables allow you to write AWS IoT Core policies that grant or deny permissions based on thing properties like thing names, thing types, and thing attribute values. You can use thing policy variables to apply the same policy to control many AWS IoT Core devices. For more information about device provisioning, see [Device Provisioning](iot-provision.html).

If you use non-exclusive thing association, the same certificate can be attached to multiple things. To maintain a clear association and to avoid potential conflicts, you must match your client ID with the thing name. In this case, you obtain the thing name from the client ID in the MQTT `Connect` message sent when a thing connects to AWS IoT Core.

Keep the following in mind when using thing policy variables in AWS IoT Core policies.
+ Use the [AttachThingPrincipal](https://docs.aws.amazon.com/iot/latest/apireference/API_AttachThingPrincipal.html) API to attach certificates or principals (authenticated Amazon Cognito identities) to a thing.
+ If non-exclusive thing association is in place, when you're replacing thing names with thing policy variables, the value of `clientId` in the MQTT connect message or the TLS connection must exactly match the thing name.

The following thing policy variables are available:
+ `iot:Connection.Thing.ThingName`

  This resolves to the name of the thing in the AWS IoT Core registry for which the policy is being evaluated. AWS IoT Core uses the certificate the device presents when it authenticates to determine which thing to use to verify the connection. This policy variable is only available when a device connects over MQTT or MQTT over the WebSocket protocol.
+ `iot:Connection.Thing.ThingTypeName`

  This resolves to the thing type associated with the thing for which the policy is being evaluated. The client ID of the MQTT/WebSocket connection must be the same as the thing name. This policy variable is available only when connecting over MQTT or MQTT over the WebSocket protocol.
+ `iot:Connection.Thing.Attributes[attributeName]`

  This resolves to the value of the specified attribute associated with the thing for which the policy is being evaluated. A thing can have up to 50 attributes. Each attribute is available as a policy variable: `iot:Connection.Thing.Attributes[attributeName]` where *attributeName* is the name of the attribute. The client ID of the MQTT/WebSocket connection must be the same as the thing name. This policy variable is only available when connecting over MQTT or MQTT over the WebSocket protocol.
+ `iot:Connection.Thing.IsAttached`

  `iot:Connection.Thing.IsAttached: ["true"]` enforces that only the devices that are both registered in AWS IoT and attached to principal can access the permissions inside the policy. You can use this variable to prevent a device from connecting to AWS IoT Core if it presents a certificate that is not attached to an IoT thing in the AWS IoT Core registry.This variable has values `true` or `false` indicating that the connecting thing is attached to the certificate or Amazon Cognito identity in the registry using [AttachThingPrincipal](https://docs.aws.amazon.com/iot/latest/apireference/API_AttachThingPrincipal.html) API. Thing name is taken as client Id. 

If your client ID matches your thing name, or if you attach your certificate to a thing exclusively, using policy variables in the policy definition can simplify policy management. Instead of creating individual policies for each IoT thing, you can define a single policy using the thing policy variables. This policy can be applied to all devices dynamically. The following is an example policy to show how it works. For more information, see [Associating an AWS IoT thing to an MQTT client connection](exclusive-thing.md).

****  

```
{
	"Version":"2012-10-17",		 	 	 
	"Statement": [
		{
			"Condition": {
				"StringLike": {
					"iot:ClientId": "*${iot:Connection.Thing.Attributes[envType]}"
				}
			},
			"Effect": "Allow",
			"Action": "iot:Connect",
			"Resource": "arn:aws:iot:us-east-1:123456789012:client/*"
		}
	]
}
```

This policy example allows things to connect to AWS IoT Core if their client ID ends with the value of their `envType` attribute. Only things with a matching client ID pattern will be allowed to connect.

# X.509 Certificate AWS IoT Core policy variables


X.509 certificate policy variables assist with writing AWS IoT Core policies. These policies grant permissions based on X.509 certificate attributes. The following sections describe how to use these certificate policy variables.

**Important**  
If your X.509 certificate doesn't include a particular certificate attribute but the corresponding certificate policy variable is used in your policy document, the policy evaluation might lead to unexpected behavior.

## CertificateId


In the [RegisterCertificate](https://docs.aws.amazon.com/iot/latest/apireference/API_RegisterCertificate.html) API, the `certificateId` appears in the response body. To get information about your certificate, use the `certificateId` in [DescribeCertificate](https://docs.aws.amazon.com/iot/latest/apireference/API_DescribeCertificate.html).

## Issuer attributes


The following AWS IoT Core policy variables support the allowing or denying of permissions, based on certificate attributes set by the certificate issuer.
+ `iot:Certificate.Issuer.DistinguishedNameQualifier`
+ `iot:Certificate.Issuer.Country`
+ `iot:Certificate.Issuer.Organization`
+ `iot:Certificate.Issuer.OrganizationalUnit`
+ `iot:Certificate.Issuer.State`
+ `iot:Certificate.Issuer.CommonName`
+ `iot:Certificate.Issuer.SerialNumber`
+ `iot:Certificate.Issuer.Title`
+ `iot:Certificate.Issuer.Surname`
+ `iot:Certificate.Issuer.GivenName`
+ `iot:Certificate.Issuer.Initials`
+ `iot:Certificate.Issuer.Pseudonym`
+ `iot:Certificate.Issuer.GenerationQualifier` 

## Subject attributes


The following AWS IoT Core policy variables support the granting or denying of permissions, based on certificate subject attributes set by the certificate issuer.
+ `iot:Certificate.Subject.DistinguishedNameQualifier`
+ `iot:Certificate.Subject.Country`
+ `iot:Certificate.Subject.Organization`
+ `iot:Certificate.Subject.OrganizationalUnit`
+ `iot:Certificate.Subject.State`
+ `iot:Certificate.Subject.CommonName`
+ `iot:Certificate.Subject.SerialNumber`
+ `iot:Certificate.Subject.Title`
+ `iot:Certificate.Subject.Surname`
+ `iot:Certificate.Subject.GivenName`
+ `iot:Certificate.Subject.Initials`
+ `iot:Certificate.Subject.Pseudonym`
+ `iot:Certificate.Subject.GenerationQualifier` 

X.509 certificates provide these attributes with the option to contain one or more values. By default, the policy variables for each multi-value attribute return the first value. For example, the `Certificate.Subject.Country` attribute might contain a list of country names, but when evaluated in a policy, `iot:Certificate.Subject.Country` is replaced by the first country name.

You can request a specific attribute value other than the first value by using a one-based index. For example, `iot:Certificate.Subject.Country.1` is replaced by the second country name in the `Certificate.Subject.Country` attribute. If you specify an index value that does not exist (for example, if you ask for a third value when there are only two values assigned to the attribute), no substitution is made and authorization fails. You can use the `.List` suffix on the policy variable name to specify all values of the attribute.

## Issuer alternate name attributes


The following AWS IoT Core policy variables support the granting or denying of permissions, based on issuer alternate name attributes set by the certificate issuer.
+ `iot:Certificate.Issuer.AlternativeName.RFC822Name`
+ `iot:Certificate.Issuer.AlternativeName.DNSName`
+ `iot:Certificate.Issuer.AlternativeName.DirectoryName`
+ `iot:Certificate.Issuer.AlternativeName.UniformResourceIdentifier`
+ `iot:Certificate.Issuer.AlternativeName.IPAddress`

## Subject alternate name attributes


The following AWS IoT Core policy variables support the granting or denying of permissions, based on subject alternate name attributes set by the certificate issuer.
+ `iot:Certificate.Subject.AlternativeName.RFC822Name`
+ `iot:Certificate.Subject.AlternativeName.DNSName`
+ `iot:Certificate.Subject.AlternativeName.DirectoryName`
+ `iot:Certificate.Subject.AlternativeName.UniformResourceIdentifier`
+ `iot:Certificate.Subject.AlternativeName.IPAddress`

## Other attributes


You can use `iot:Certificate.SerialNumber` to allow or deny access to AWS IoT Core resources, based on the serial number of a certificate. The `iot:Certificate.AvailableKeys` policy variable contains the name of all certificate policy variables that contain values.

# Using X.509 certificate policy variables


This topic provides details of how to use certificate policy variables. X.509 certificate policy variables are essential when you create AWS IoT Core policies that give permissions based on X.509 certificate attributes. If your X.509 certificate doesn't include a particular certificate attribute but the corresponding certificate policy variable is used in your policy document, the policy evaluation might lead to unexpected behavior. This is because the missing policy variable doesn't get evaluated in the policy statement.

**Topics**
+ [

## X.509 certificate example
](#certificate-example)
+ [

## Using certificate issuer attributes as certificate policy variables
](#issuer-attributes-policy)
+ [

## Using certificate subject attributes as certificate policy variables
](#subject-attributes-policy)
+ [

## Using certificate Issuer alternate name attributes as certificate policy variables
](#issuer-alternate-name-attributes-policy)
+ [

## Using certificate subject alternate name attributes as certificate policy variables
](#subject-alternate-name-attributes-policy)
+ [

## Using other certificate attribute as a certificate policy variable
](#other-attributes-policy)
+ [

## X.509 Certificate policy variable limitations
](#policy-limits)
+ [

## Example policies using certificate policy variables
](#example-attributes-policy)

## X.509 certificate example


A typical X.509 certificate might appear as follows. This example certificate includes certificate attributes. During the evaluation of AWS IoT Core policies, the following certificate attributes will be populated as certificate policy variables: `Serial Number`, `Issuer`, `Subject`, `X509v3 Issuer Alternative Name`, and `X509v3 Subject Alternative Name`.

```
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            92:12:85:cb:b7:a5:e0:86
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=US, O=IoT Devices, OU=SmartHome, ST=WA, CN=IoT Devices Primary CA, 
				GN=Primary CA1/initials=XY/dnQualifier=Example corp,
				SN=SmartHome/ title=CA1/pseudonym=Primary_CA/generationQualifier=2/serialNumber=987		
        Validity
            Not Before: Mar 26 03:25:40 2024 GMT
            Not After : Apr 28 03:25:40 2025 GMT
        Subject: C=US, O=IoT Devices, OU=LightBulb, ST=NY, CN=LightBulb Device Cert, 
				GN=Bulb/initials=ZZ/dnQualifier=Bulb001, 
				SN=Multi Color/title=RGB/pseudonym=RGB Device/generationQualifier=4/serialNumber=123
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    << REDACTED >>
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            X509v3 Key Usage: 
                Digital Signature, Non Repudiation, Key Encipherment
            X509v3 Subject Alternative Name: 
                DNS:example.com, IP Address:1.2.3.4, URI:ResourceIdentifier001, email:device1@example.com, DirName:/C=US/O=IoT/OU=SmartHome/CN=LightBulbCert
            X509v3 Issuer Alternative Name: 
                DNS:issuer.com, IP Address:5.6.7.8, URI:PrimarySignerCA, email:primary@issuer.com, DirName:/C=US/O=Issuer/OU=IoT Devices/CN=Primary Issuer CA
    Signature Algorithm: sha256WithRSAEncryption
         << REDACTED >>
```

## Using certificate issuer attributes as certificate policy variables


The following table provides details of how certificate issuer attributes will be populated in an AWS IoT Core policy.


**Issuer attributes to be populated in a policy**  

| Certificate issuer attributes | Certificate policy variables | 
| --- | --- | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iot/latest/developerguide/use-policy-variables.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iot/latest/developerguide/use-policy-variables.html)  | 

## Using certificate subject attributes as certificate policy variables


The following table provides details of how certificate subject attributes will be populated in an AWS IoT Core policy.


**Subject attributes to be populated in a policy**  

| Certificate subject attributes | Certificate policy variables | 
| --- | --- | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iot/latest/developerguide/use-policy-variables.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iot/latest/developerguide/use-policy-variables.html)  | 

## Using certificate Issuer alternate name attributes as certificate policy variables


The following table provides details of how certificate issuer alternate name attributes will be populated in an AWS IoT Core policy.


**Issuer alternate name attributes to be populated in a policy**  

| X509v3 Issuer Alternative Name | Attribute in a policy | 
| --- | --- | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iot/latest/developerguide/use-policy-variables.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iot/latest/developerguide/use-policy-variables.html)  | 

## Using certificate subject alternate name attributes as certificate policy variables


The following table provides details of how certificate subject alternate name attributes will be populated in an AWS IoT Core policy.


**Subject alternate name attributes to be populated in a policy**  

| X509v3 Subject Alternative Name | Attribute in a policy | 
| --- | --- | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iot/latest/developerguide/use-policy-variables.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iot/latest/developerguide/use-policy-variables.html)  | 

## Using other certificate attribute as a certificate policy variable


The following table provides details of how other certificate attributes will be populated in an AWS IoT Core policy.


**Other attributes to be populated in a policy**  

| Other certificate attribute | Certificate policy variable | 
| --- | --- | 
|  `Serial Number: 92:12:85:cb:b7:a5:e0:86`  |  `iot:Certificate.SerialNumber = 10525622389124227206`  | 

## X.509 Certificate policy variable limitations


The following limitations apply to X.509 certificate policy variables:

Missing policy variables  
If your X.509 certificate doesn't include a particular certificate attribute but the corresponding certificate policy variable is used in your policy document, the policy evaluation might lead to unexpected behavior. This is because the missing policy variable doesn't get evaluated in the policy statement.

Certificate SerialNumber format  
AWS IoT Core treats the certificate serial number as the string representation of a decimal integer. For example, if a policy only allows connections with Client ID matching the certificate serial number, the client ID must be the serial number in decimal format.

Wildcards  
If wildcard characters are present in certificate attributes, the policy variable is not replaced by the certificate attribute value. This will leave the `${policy-variable}` text in the policy document. This might cause authorization failure. The following wildcard characters can be used: `*`, `$`, `+`, `?`, and `#`.

Array fields  
Certificate attributes that contain arrays are limited to five items. Additional items are ignored.

String length  
All string values are limited to 1024 characters. If a certificate attribute contains a string longer than 1024 characters, the policy variable is not replaced by the certificate attribute value. This will leave the `${policy-variable}` in the policy document. This might cause authorization failure.

Special Characters  
Any special character, such as `,`, `"`, `\`, `+`, `=`, `<`, `>` and `;` must be prefixed with a backslash (`\`) when used in a policy variable. For example, `Amazon Web Services O=Amazon.com Inc. L=Seattle ST=Washington C=US` becomes `Amazon Web Service O\=Amazon.com Inc. L\=Seattle ST\=Washington C\=US`.

## Example policies using certificate policy variables


The following policy document allows connections with client ID that matches the certificate serial number and publishing to the topic that matches the pattern: `${iot:Certificate.Subject.Organization}/device-stats/${iot:ClientId}/*`. 

**Important**  
If your X.509 certificate doesn't include a particular certificate attribute but the corresponding certificate policy variable is used in your policy document, the policy evaluation might lead to unexpected behavior. This is because the missing policy variable doesn't get evaluated in the policy statement. For example, if you attach the following policy document to a certificate that doesn't contain the `iot:Certificate.Subject.Organization` attribute, the `iot:Certificate.Subject.Organization` certificate policy variables won't be populated during the policy evaluation.

****  

```
{
	"Version":"2012-10-17",		 	 	 
	"Statement": [
		{
			"Effect": "Allow",
			"Action": [
				"iot:Connect"
			],
			"Resource": [
				"arn:aws:iot:us-east-1:123456789012:client/${iot:Certificate.SerialNumber}"
			]
		},
		{
			"Effect": "Allow",
			"Action": [
				"iot:Publish"
			],
			"Resource": [
				"arn:aws:iot:us-east-1:123456789012:topic/${iot:Certificate.Subject.Organization}/device-stats/${iot:ClientId}/*"
			]
		}
	]
}
```

You can also use the [Null condition operator](https://docs.aws.amazon.com//IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_Null) to ensure that the certificate policy variables used in a policy are populated during policy evaluation. The following policy document allows `iot:Connect` with certificates only when the Certificate Serial Number and Certificate Subject Common name attributes are present.

All of the certificate policy variables have String values, so all of the [String condition operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_String) are supported.

****  

```
{
	"Version":"2012-10-17",		 	 	 
	"Statement": [
		{
			"Effect": "Allow",
			"Action": [
				"iot:Connect"
			],
			"Resource": [
				"arn:aws:iot:us-east-1:123456789012:client/*"
			],
			"Condition": {
				"Null": {
					"iot:Certificate.SerialNumber": "false",
					"iot:Certificate.Subject.CommonName": "false"
				}
			}
		}
	]
}
```

# Cross-service confused deputy prevention


The *confused deputy problem* is a security issue where an entity that doesn't have permission to perform an action can coerce a more-privileged entity to perform the action. In AWS, cross-service impersonation can result in the confused deputy problem. Cross-service impersonation can occur when one service (the *calling service*) calls another service (the *called service*). The calling service can be manipulated to use its permissions to act on another customer's resources in a way it shouldn't otherwise have permission to access. To prevent this, AWS provides tools that help you protect your data for all services with service principals that have been given access to resources in your account. 

To limit the permissions that AWS IoT gives another service to the resource, we recommend using the [https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourcearn](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourcearn) and [https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourceaccount](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourceaccount) global condition context keys in resource policies. If you use both global condition context keys, the `aws:SourceAccount` value and the account in the `aws:SourceArn` value must use the same account ID when used in the same policy statement.

The most effective way to protect against the confused deputy problem is to use the `aws:SourceArn` global condition context key with the full Amazon Resource Name (ARN) of the resource. For AWS IoT, your `aws:SourceArn` must comply with the format: `arn:aws:iot:region:account-id:resource-type/resource-id` for resource specific permissions or `arn:aws:iot:region:account-id:*`. The resource-id can be the name or ID of the permitted resource, or a wildcard statement of the permitted resource IDs. Make sure that the *region* matches your AWS IoT Region and the *account-id* matches your customer account ID. 

The following example shows how to prevent the confused deputy problem by using the `aws:SourceArn` and `aws:SourceAccount` global condition context keys in the AWS IoT role trust policy. For more examples, see [Detailed examples of confused deputy prevention](#cross-service-confused-deputy-prevention-examples).

****  

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

**Note**  
If you get access deny errors, it can be because the service integration with AWS Security Token Service (STS) doesn't support the `aws:SourceArn` and `aws:SourceAccount` context keys.

## Detailed examples of confused deputy prevention


**This section provides detailed examples of how to prevent the confused deputy problem by using the `aws:SourceArn` and `aws:SourceAccount` global condition context keys in the AWS IoT role trust policy.**
+ [

### Fleet provisioning
](#cross-service-confused-deputy-prevention-fleet-provision)
+ [

### JITP
](#cross-service-confused-deputy-prevention-JITP)
+ [

### Credential provider
](#cross-service-confused-deputy-prevention-credential-provider)

### Fleet provisioning


You can configure [fleet provisioning](https://docs.aws.amazon.com/iot/latest/developerguide/iot-provision.html) using a provisioning template resource. When a provisioning template references a provisioning role, that role's trust policy can include the `aws:SourceArn` and `aws:SourceAccount` condition keys. These keys limit the resources for which the configuration can invoke the `sts:AssumeRole` request.

The role with the following trust policy can only be assumed by the IoT principal (`iot.amazonaws.com`) for the provisioning template specified in the `SourceArn`.

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement":[
      {
         "Effect":"Allow",
         "Principal":{
            "Service":"iot.amazonaws.com"
         },
         "Action":"sts:AssumeRole",
         "Condition":{
            "StringEquals":{
               "aws:SourceAccount":"123456789012"
        },
            "ArnLike":{
               "aws:SourceArn":"arn:aws:iot:us-east-1:123456789012:provisioningtemplate/example_template"
        }
         }
      }
   ]
}
```

### JITP


In [just-in-time provisioning (JITP)](https://docs.aws.amazon.com//iot/latest/developerguide/jit-provisioning.html), you can either use provisioning template as a resource separate from the CA or define the template body and the role as part of the CA certificate configuration. The value of `aws:SourceArn` in the AWS IoT role trust policy depends on how you define the provisioning template.

#### Defining provisioning template as a separate resource


If you define your provisioning template as a separate resource, the value of `aws:SourceArn` can be `"arn:aws:iot:region:account-id:provisioningtemplate/example_template"`. You can use the same policy example in [Fleet provisioning](#cross-service-confused-deputy-prevention-fleet-provision).

#### Defining provisioning template in a CA certificate


If you define your provisioning template within a CA certificate resource, the value of `aws:SourceArn` can be `"arn:aws:iot:region:account-id:cacert/cert_id"` or `"arn:aws:iot:region:account-id:cacert/*"`. You can use a wildcard when the resource identifier, such as the ID of a CA certificate, is unknown at the time of creation.

The role with the following trust policy can only be assumed by the IoT principal (`iot.amazonaws.com`) for the CA certificate specified in the `SourceArn`.

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement":[
      {
         "Effect":"Allow",
         "Principal":{
            "Service":"iot.amazonaws.com"
         },
         "Action":"sts:AssumeRole",
         "Condition":{
            "StringEquals":{
               "aws:SourceAccount":"123456789012"
        },
            "ArnLike":{
               "aws:SourceArn":"arn:aws:iot:us-east-1:123456789012:cacert/8ecde6884f3d87b1125ba31ac3fcb13d7016de7f57cc904fe1cb97c6ae98196e"
        }
         }
      }
   ]
}
```

When creating a CA certificate, you can reference a provisioning role in the registration configuration. The trust policy of the provisioning role can use `aws:SourceArn` to restrict what resources the role can be assumed for. However, during the initial [RegisterCACertificate](https://docs.aws.amazon.com/iot/latest/apireference/API_RegisterCACertificate.html) call to register the CA certificate, you would not have the ARN of the CA certificate to specify in the `aws:SourceArn` condition.

To work around this, i.e., to specify the provisioning role trust policy to the specific CA certificate that's registered with AWS IoT Core, you can do the following:
+ First, call [RegisterCACertificate](https://docs.aws.amazon.com/iot/latest/apireference/API_RegisterCACertificate.html) without providing the `RegistrationConfig` parameter.
+ After the CA certificate is registered with AWS IoT Core, call [UpdateCACertificate](https://docs.aws.amazon.com/iot/latest/apireference/API_UpdateCACertificate.html) on it.

  In the UpdateCACertificate call, provide a `RegistrationConfig` that includes the provisioning role trust policy with `aws:SourceArn` set to the ARN of the newly registered CA certificate.

### Credential provider


For [AWS IoT Core credential provider](https://docs.aws.amazon.com//iot/latest/developerguide/authorizing-direct-aws.html), use the same AWS account you use to create the role alias in `aws:SourceAccount`, and specify a statement that matches the resource ARN of the rolealias resource type in `aws:SourceArn`. When creating an IAM role for use with AWS IoT Core credential provider, you must include in the `aws:SourceArn` condition the ARNs of any role aliases that might need to assume the role, thereby authorizing the cross-service `sts:AssumeRole` request.

The role with the following trust policy can only be assumed by the principal of AWS IoT Core credential provider (`credentials.iot.amazonaws.com`) for the roleAlias specified in the `SourceArn`. If a principal attempts to retrieve credentials for a role alias other than what's specified in the `aws:SourceArn` condition, the request will be denied, even if that other role alias references the same IAM role.

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "credentials.iot.amazonaws.com"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "aws:SourceAccount": "123456789012"
        },
        "ArnLike": {
          "aws:SourceArn": "arn:aws:iot:us-east-1:123456789012:rolealias/example_rolealias"
        }
      }
    }
  ]
}
```

# AWS IoT Core policy examples


The example policies in this section illustrate the policy documents used to complete common tasks in AWS IoT Core. You can use them as examples to start from when creating the policies for your solutions.<a name="example-iot-policies-elements"></a>

The examples in this section use these policy elements:
+ [AWS IoT Core policy actions](iot-policy-actions.md)
+ [AWS IoT Core action resources](iot-action-resources.md)
+ [AWS IoT identity-based policy examples](security_iam_id-based-policy-examples.md)
+ [Basic AWS IoT Core policy variables](basic-policy-variables.md)
+ [X.509 Certificate AWS IoT Core policy variables](cert-policy-variables.md)

**Topics**
+ [

# Connect policy examples
](connect-policy.md)
+ [

# Publish/Subscribe policy examples
](pub-sub-policy.md)
+ [

# Connect and publish policy examples
](connect-and-pub.md)
+ [

# Retained message policy examples
](retained-message-policy-examples.md)
+ [

# Certificate policy examples
](certificate-policy-examples.md)
+ [

# Thing policy examples
](thing-policy-examples.md)
+ [

# Basic job policy example
](basic-jobs-example.md)

# Connect policy examples


The following policy denies permission to client IDs `client1` and `client2` to connect to AWS IoT Core, while allowing devices to connect using a client ID. The client ID matches the name of a thing that's registered in the AWS IoT Core registry and attached to the principal that's used for connection:

**Note**  
For registered devices, we recommend that you use [thing policy variables](thing-policy-variables.md) for `Connect` actions and attach the thing to the principal that's used for the connection.

****  

```
{
	"Version":"2012-10-17",		 	 	 
	"Statement": [
		{
			"Effect": "Deny",
			"Action": [
				"iot:Connect"
			],
			"Resource": [
				"arn:aws:iot:us-east-1:123456789012:client/client1",
				"arn:aws:iot:us-east-1:123456789012:client/client2"
			]
		},
		{
			"Effect": "Allow",
			"Action": [
				"iot:Connect"
			],
			"Resource": [
				"arn:aws:iot:us-east-1:123456789012:client/${iot:Connection.Thing.ThingName}"
			],
			"Condition": {
				"Bool": {
					"iot:Connection.Thing.IsAttached": "true"
				}
			}
		}
	]
}
```

The following policy grants permission to connect to AWS IoT Core with client ID `client1`. This policy example is for unregistered devices.

****  

```
{
	"Version":"2012-10-17",		 	 	 
	"Statement": [
		{
			"Effect": "Allow",
			"Action": [
				"iot:Connect"
			],
			"Resource": [
				"arn:aws:iot:us-east-1:123456789012:client/client1"
			]
		}
	]
}
```

## MQTT persistent sessions policy examples


`connectAttributes` allow you to specify what attributes you want to use in your connect message in your IAM policies such as `PersistentConnect` and `LastWill`. For more information, see [Using connectAttributes](mqtt.md#connect-attribute).

The following policy allows connect with `PersistentConnect` feature:

****  

```
{
	"Version":"2012-10-17",		 	 	 
	"Statement": [
		{
			"Effect": "Allow",
			"Action": [
				"iot:Connect"
			],
			"Resource": "arn:aws:iot:us-east-1:123456789012:client/client1",
			"Condition": {
				"ForAllValues:StringEquals": {
					"iot:ConnectAttributes": [
						"PersistentConnect"
					]
				}
			}
		}
	]
}
```

The following policy disallows `PersistentConnect`, other features are allowed:

****  

```
{
	"Version":"2012-10-17",		 	 	 
	"Statement": [
		{
			"Effect": "Allow",
			"Action": [
				"iot:Connect"
			],
			"Resource": "arn:aws:iot:us-east-1:123456789012:client/client1",
			"Condition": {
				"ForAllValues:StringNotEquals": {
					"iot:ConnectAttributes": [
						"PersistentConnect"
					]
				}
			}
		}
	]
}
```

The above policy can also be expressed using `StringEquals`, any other feature including new feature is allowed:

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Connect"
            ],
            "Resource": "arn:aws:iot:us-east-1:123456789012:client/client1"
        },
        {
            "Effect": "Deny",
            "Action": [
                "iot:Connect"
            ],
            "Resource": "*",
            "Condition": {
                "ForAnyValue:StringEquals": {
                    "iot:ConnectAttributes": [
                        "PersistentConnect"
                    ]
            }
        }
        }
    ]
}
```

The following policy allows connect by both `PersistentConnect` and `LastWill`, any other new feature is not allowed:

****  

```
{
	"Version":"2012-10-17",		 	 	 
	"Statement": [
		{
			"Effect": "Allow",
			"Action": [
				"iot:Connect"
			],
			"Resource": "arn:aws:iot:us-east-1:123456789012:client/client1",
			"Condition": {
				"ForAllValues:StringEquals": {
					"iot:ConnectAttributes": [
						"PersistentConnect",
						"LastWill"
					]
				}
			}
		}
	]
}
```

The following policy allows clean connect by clients with or without `LastWill`, no other features will be allowed:

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [{
        "Effect": "Allow",
        "Action": [
            "iot:Connect"
        ],
        "Resource": "arn:aws:iot:us-east-1:123456789012:client/client1",
        "Condition": {
            "StringEquals": {
                "iot:ConnectAttributes": "LastWill"
        }
        }
    }]
}
```

The following policy only allows connect using default features:

****  

```
{
	"Version":"2012-10-17",		 	 	 
	"Statement": [
		{
			"Effect": "Allow",
			"Action": [
				"iot:Connect"
			],
			"Resource": "arn:aws:iot:us-east-1:123456789012:client/client1",
			"Condition": {
				"ForAllValues:StringEquals": {
					"iot:ConnectAttributes": []
				}
			}
		}
	]
}
```

The following policy allows connect only with `PersistentConnect`, any new feature is allowed as long as the connection uses `PersistentConnect`:

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Connect"
            ],
            "Resource": "arn:aws:iot:us-east-1:123456789012:client/client1",
            "Condition": {
                "ForAnyValue:StringEquals": {
                    "iot:ConnectAttributes": [
                        "PersistentConnect"
                    ]
            }
        }
        }
    ]
}
```

The following policy states the connect must have both `PersistentConnect` and `LastWill` usage, no new feature is allowed:

****  

```
{
	"Version":"2012-10-17",		 	 	 
	"Statement": [
		{
			"Effect": "Allow",
			"Action": [
				"iot:Connect"
			],
			"Resource": "arn:aws:iot:us-east-1:123456789012:client/client1",
			"Condition": {
				"ForAllValues:StringEquals": {
					"iot:ConnectAttributes": [
						"PersistentConnect",
						"LastWill"
					]
				}
			}
		},
		{
			"Effect": "Deny",
			"Action": [
				"iot:Connect"
			],
			"Resource": "*",
			"Condition": {
				"ForAllValues:StringEquals": {
					"iot:ConnectAttributes": [
						"PersistentConnect"
					]
				}
			}
		},
		{
			"Effect": "Deny",
			"Action": [
				"iot:Connect"
			],
			"Resource": "*",
			"Condition": {
				"ForAllValues:StringEquals": {
					"iot:ConnectAttributes": [
						"LastWill"
					]
				}
			}
		},
		{
			"Effect": "Deny",
			"Action": [
				"iot:Connect"
			],
			"Resource": "*",
			"Condition": {
				"ForAllValues:StringEquals": {
					"iot:ConnectAttributes": []
				}
			}
		}
	]
}
```

The following policy must not have `PersistentConnect` but can have `LastWill`, any other new feature is not allowed:

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Deny",
            "Action": [
                "iot:Connect"
            ],
            "Resource": "*",
            "Condition": {
                "ForAnyValue:StringEquals": {
                    "iot:ConnectAttributes": [
                        "PersistentConnect"
                    ]
            }
        }
        },
        {
            "Effect": "Allow",
            "Action": [
                "iot:Connect"
            ],
            "Resource": "arn:aws:iot:us-east-1:123456789012:client/client1",
            "Condition": {
                "ForAllValues:StringEquals": {
                    "iot:ConnectAttributes": [
                        "LastWill"
                    ]
            }
        }
        }
    ]
}
```

The following policy allows connect only by clients that have a `LastWill` with topic `"my/lastwill/topicName"`, any feature is allowed as long as it uses the `LastWill` topic:

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Connect"
            ],
            "Resource": "arn:aws:iot:us-east-1:123456789012:client/client1",
            "Condition": {
                "ArnEquals": {
                "iot:LastWillTopic": "arn:aws:iot:us-east-1:123456789012:topic/my/lastwill/topicName"
            }
        }
        }
    ]
}
```

The following policy only allows clean connect using a specific `LastWillTopic`, any feature is allowed as long as it uses the `LastWillTopic`:

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Connect"
            ],
            "Resource": "arn:aws:iot:us-east-1:123456789012:client/client1",
            "Condition": {
                "ArnEquals": {
                "iot:LastWillTopic": "arn:aws:iot:us-east-1:123456789012:topic/my/lastwill/topicName"
            }
        }
        },
        {
            "Effect": "Deny",
            "Action": [
                "iot:Connect"
            ],
            "Resource": "*",
            "Condition": {
                "ForAnyValue:StringEquals": {
                    "iot:ConnectAttributes": [
                        "PersistentConnect"
                    ]
            }
        }
        }
    ]
}
```

# Publish/Subscribe policy examples


The policy you use depends on how you're connecting to AWS IoT Core. You can connect to AWS IoT Core by using an MQTT client, HTTP, or WebSocket. When you connect with an MQTT client, you're authenticating with an X.509 certificate. When you connect over HTTP or the WebSocket protocol, you're authenticating with Signature Version 4 and Amazon Cognito. 

**Note**  
For registered devices, we recommend that you use [thing policy variables](thing-policy-variables.md) for `Connect` actions and attach the thing to the principal that's used for the connection. 

**Topics**
+ [

## Using wildcard characters in MQTT and AWS IoT Core policies
](#pub-sub-policy-cert)
+ [

## Policies to publish, subscribe and receive messages to/from specific topics
](#pub-sub-specific-topic)
+ [

## Policies to publish, subscribe and receive messages to/from topics with a specific prefix
](#pub-sub-policy-specific-topic-prefix)
+ [

## Policies to publish, subscribe and receive messages to/from topics specific to each device
](#pub-sub-specific-topic-device)
+ [

## Policies to publish, subscribe and receive messages to/from topics with thing attribute in topic name
](#pub-sub-topic-attribute)
+ [

## Policies to deny publishing messages to subtopics of a topic name
](#pub-sub-deny-publish)
+ [

## Policies to deny receiving messages from subtopics of a topic name
](#pub-sub-deny-receive)
+ [

## Policies to subscribe to topics using MQTT wildcard characters
](#pub-sub-topic-wildcard)
+ [

## Policies for HTTP and WebSocket clients
](#pub-sub-policy-cognito)

## Using wildcard characters in MQTT and AWS IoT Core policies


MQTT and AWS IoT Core policies have different wildcard characters and you should choose them after careful consideration. In MQTT, the wildcard characters `+` and `#` are used in [MQTT topic filters](https://docs.aws.amazon.com/iot/latest/developerguide/topics.html#topicfilters) to subscribe to multiple topic names. AWS IoT Core policies use `*` and `?` as wildcard characters and follow the conventions of [IAM policies](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_grammar.html#policies-grammar-json). In a policy document, the `*` represents any combination of characters and a question mark `?` represents any single character. In policy documents, the MQTT wildcard characters, `+` and `#` are treated as those characters with no special meaning. To describe multiple topic names and topic filters in the `resource` attribute of a policy, use the `*` and `?` wildcard characters in place of the MQTT wildcard characters.

When you choose the wildcard characters to use in a policy document, consider that the `*` character is not confined to a single topic level. The `+` character is confined to a single topic level in an MQTT topic filter. To help constrain a wildcard specification to a single MQTT topic filter level, consider using multiple `?` characters. For more information about using wildcard characters in a policy resource and more examples of what they match, see [Using wildcards in resource ARNs](https://docs.aws.amazon.com//IAM/latest/UserGuide/reference_policies_elements_resource.html#reference_policies_elements_resource_wildcards).

The table below shows the different wildcard characters used in MQTT and AWS IoT Core policies for MQTT clients.


| Wildcard character | Is MQTT wildcard character | Example in MQTT | Is AWS IoT Core policy wildcard character | Example in AWS IoT Core policies for MQTT clients | 
| --- | --- | --- | --- | --- | 
| \$1 | Yes | some/\$1 | No | N/A | 
| \$1 | Yes | some/\$1/topic | No | N/A | 
| \$1 | No | N/A | Yes | `topicfilter/some/*/topic` `topicfilter/some/sensor*/topic`  | 
| ? | No | N/A | Yes |  `topic/some/?????/topic` `topicfilter/some/sensor???/topic`  | 

## Policies to publish, subscribe and receive messages to/from specific topics


The following shows examples for registered and unregistered devices to publish, subscribe and receive messages to/from the topic named "some\$1specific\$1topic". The examples also highlight that `Publish` and `Receive` use "topic" as the resource, and `Subscribe` uses "topicfilter" as the resource.

------
#### [ Registered devices ]

For devices registered in AWS IoT Core registry, the following policy allows devices to connect with clientId that matches the name of a thing in the registry. It also provides `Publish`, `Subscribe` and `Receive` permissions for the topic named "some\$1specific\$1topic".

****  

```
{
	"Version":"2012-10-17",		 	 	 
	"Statement": [
		{
			"Effect": "Allow",
			"Action": [
				"iot:Connect"
			],
			"Resource": [
				"arn:aws:iot:us-east-1:123456789012:client/${iot:Connection.Thing.ThingName}"
			],
			"Condition": {
				"Bool": {
					"iot:Connection.Thing.IsAttached": "true"
				}
			}
		},
		{
			"Effect": "Allow",
			"Action": [
				"iot:Publish"
			],
			"Resource": [
				"arn:aws:iot:us-east-1:123456789012:topic/some_specific_topic"
			]
		},
		{
			"Effect": "Allow",
			"Action": [
				"iot:Subscribe"
			],
			"Resource": [
				"arn:aws:iot:us-east-1:123456789012:topicfilter/some_specific_topic"
			]
		},
		{
			"Effect": "Allow",
			"Action": [
				"iot:Receive"
			],
			"Resource": [
				"arn:aws:iot:us-east-1:123456789012:topic/some_specific_topic"
			]
		}
	]
}
```

------
#### [ Unregistered devices ]

For devices not registered in AWS IoT Core registry, the following policy allows devices to connect using either clientId1, clientId2 or clientId3. It also provides `Publish`, `Subscribe` and `Receive` permissions for the topic named "some\$1specific\$1topic".

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Connect"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:client/clientId1",
                "arn:aws:iot:us-east-1:123456789012:client/clientId2",
                "arn:aws:iot:us-east-1:123456789012:client/clientId3"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iot:Publish"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:topic/some_specific_topic"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iot:Subscribe"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:topicfilter/some_specific_topic"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iot:Receive"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:topic/some_specific_topic"
            ]
        }
    ]
}
```

------

## Policies to publish, subscribe and receive messages to/from topics with a specific prefix


The following shows examples for registered and unregistered devices to publish, subscribe and receive messages to/from topics prefixed with "topic\$1prefix".

**Note**  
Note the use of the wildcard character `*` in this example. Although `*` is useful to provide permissions for multiple topic names in a single statement, it can lead to unintended consequences by providing more privileges to devices than required. So we recommend that you only use the wildcard character `*` after careful consideration.

------
#### [ Registered devices ]

For devices registered in AWS IoT Core registry, the following policy allows devices to connect with clientId that matches the name of a thing in the registry. It also provides `Publish`, `Subscribe` and `Receive` permissions for topics prefixed with "topic\$1prefix".

****  

```
{
	"Version":"2012-10-17",		 	 	 
	"Statement": [
		{
			"Effect": "Allow",
			"Action": [
				"iot:Connect"
			],
			"Resource": [
				"arn:aws:iot:us-east-1:123456789012:client/${iot:Connection.Thing.ThingName}"
			],
			"Condition": {
				"Bool": {
					"iot:Connection.Thing.IsAttached": "true"
				}
			}
		},
		{
			"Effect": "Allow",
			"Action": [
				"iot:Publish",
				"iot:Receive"
			],
			"Resource": [
				"arn:aws:iot:us-east-1:123456789012:topic/topic_prefix*"
			]
		},
		{
			"Effect": "Allow",
			"Action": [
				"iot:Subscribe"
			],
			"Resource": [
				"arn:aws:iot:us-east-1:123456789012:topicfilter/topic_prefix*"
			]
		}
	]
}
```

------
#### [ Unregistered devices ]

For devices not registered in AWS IoT Core registry, the following policy allows devices to connect using either clientId1, clientId2 or clientId3. It also provides `Publish`, `Subscribe` and `Receive` permissions for topics prefixed with "topic\$1prefix".

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Connect"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:client/clientId1",
                "arn:aws:iot:us-east-1:123456789012:client/clientId2",
                "arn:aws:iot:us-east-1:123456789012:client/clientId3"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iot:Publish",
                "iot:Receive"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:topic/topic_prefix*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iot:Subscribe"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:topicfilter/topic_prefix*"
            ]
        }
    ]
}
```

------

## Policies to publish, subscribe and receive messages to/from topics specific to each device


The following shows examples for registered and unregistered devices to publish, subscribe and receive messages to/from topics that are specific to the given device.

------
#### [ Registered devices ]

For devices registered in AWS IoT Core registry, the following policy allows devices to connect with clientId that matches the name of a thing in the registry. It provides permission to publish to the thing-specific topic (`sensor/device/${iot:Connection.Thing.ThingName}`) and also subscribe to and receive from the thing-specific topic (`command/device/${iot:Connection.Thing.ThingName}`). If the thing name in the registry is "thing1", the device will be able to publish to the topic "sensor/device/thing1". The device will also be able to subscribe to and receive from the topic "command/device/thing1".

****  

```
{
	"Version":"2012-10-17",		 	 	 
	"Statement": [
		{
			"Effect": "Allow",
			"Action": [
				"iot:Connect"
			],
			"Resource": [
				"arn:aws:iot:us-east-1:123456789012:client/${iot:Connection.Thing.ThingName}"
			],
			"Condition": {
				"Bool": {
					"iot:Connection.Thing.IsAttached": "true"
				}
			}
		},
		{
			"Effect": "Allow",
			"Action": [
				"iot:Publish"
			],
			"Resource": [
				"arn:aws:iot:us-east-1:123456789012:topic/sensor/device/${iot:Connection.Thing.ThingName}"
			]
		},
		{
			"Effect": "Allow",
			"Action": [
				"iot:Subscribe"
			],
			"Resource": [
				"arn:aws:iot:us-east-1:123456789012:topicfilter/command/device/${iot:Connection.Thing.ThingName}"
			]
		},
		{
			"Effect": "Allow",
			"Action": [
				"iot:Receive"
			],
			"Resource": [
				"arn:aws:iot:us-east-1:123456789012:topic/command/device/${iot:Connection.Thing.ThingName}"
			]
		}
	]
}
```

------
#### [ Unregistered devices ]

For devices not registered in AWS IoT Core registry, the following policy allows devices to connect using either clientId1, clientId2 or clientId3. It provides permission to publish to the client-specific topic (`sensor/device/${iot:ClientId}`), and also subscribe to and receive from the client-specific topic (`command/device/${iot:ClientId}`). If the device connects with clientId as clientId1, it will be able to publish to the topic "sensor/device/clientId1". The device will also be able to subscribe to and receive from the topic `device/clientId1/command`.

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Connect"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:client/clientId1",
                "arn:aws:iot:us-east-1:123456789012:client/clientId2",
                "arn:aws:iot:us-east-1:123456789012:client/clientId3"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iot:Publish"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:topic/sensor/device/${iot:Connection.Thing.ThingName}"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iot:Subscribe"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:topicfilter/command/device/${iot:Connection.Thing.ThingName}"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iot:Receive"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:topic/command/device/${iot:Connection.Thing.ThingName}"
            ]
        }
    ]
}
```

------

## Policies to publish, subscribe and receive messages to/from topics with thing attribute in topic name


The following shows an example for registered devices to publish, subscribe and receive messages to/from topics whose names include thing attributes.

**Note**  
Thing attributes only exist for devices registered in AWS IoT Core Registry. There is no corresponding example for unregistered devices.

------
#### [ Registered devices ]

For devices registered in AWS IoT Core registry, the following policy allows devices to connect with clientId that matches the name of a thing in the registry. It provides permission to publish to the topic (`sensor/${iot:Connection.Thing.Attributes[version]}`), and subscribe to and receive from the topic (`command/${iot:Connection.Thing.Attributes[location]}`) where the topic name includes thing attributes. If the thing name in the registry has `version=v1` and `location=Seattle`, the device will be able to publish to the topic "sensor/v1", and subscribe to and receive from the topic "command/Seattle".

****  

```
{
	"Version":"2012-10-17",		 	 	 
	"Statement": [
		{
			"Effect": "Allow",
			"Action": [
				"iot:Connect"
			],
			"Resource": [
				"arn:aws:iot:us-east-1:123456789012:client/${iot:Connection.Thing.ThingName}"
			],
			"Condition": {
				"Bool": {
					"iot:Connection.Thing.IsAttached": "true"
				}
			}
		},
		{
			"Effect": "Allow",
			"Action": [
				"iot:Publish"
			],
			"Resource": [
				"arn:aws:iot:us-east-1:123456789012:topic/sensor/${iot:Connection.Thing.Attributes[version]}"
			]
		},
		{
			"Effect": "Allow",
			"Action": [
				"iot:Subscribe"
			],
			"Resource": [
				"arn:aws:iot:us-east-1:123456789012:topicfilter/command/${iot:Connection.Thing.Attributes[location]}"
			]
		},
		{
			"Effect": "Allow",
			"Action": [
				"iot:Receive"
			],
			"Resource": [
				"arn:aws:iot:us-east-1:123456789012:topic/command/${iot:Connection.Thing.Attributes[location]}"
			]
		}
	]
}
```

------
#### [ Unregistered devices ]

Because thing attributes only exist for devices registered in AWS IoT Core registry, there is no corresponding example for unregistered things.

------

## Policies to deny publishing messages to subtopics of a topic name


The following shows examples for registered and unregistered devices to publish messages to all topics except certain subtopics.

------
#### [ Registered devices ]

For devices registered in AWS IoT Core registry, the following policy allows devices to connect with clientId that matches the name of a thing in the registry. It provides permission to publish to all topics prefixed with "department/" but not to the "department/admins" subtopic.

****  

```
{
	"Version":"2012-10-17",		 	 	 
	"Statement": [
		{
			"Effect": "Allow",
			"Action": [
				"iot:Connect"
			],
			"Resource": [
				"arn:aws:iot:us-east-1:123456789012:client/${iot:Connection.Thing.ThingName}"
			],
			"Condition": {
				"Bool": {
					"iot:Connection.Thing.IsAttached": "true"
				}
			}
		},
		{
			"Effect": "Allow",
			"Action": [
				"iot:Publish"
			],
			"Resource": [
				"arn:aws:iot:us-east-1:123456789012:topic/department/*"
			]
		},
		{
			"Effect": "Deny",
			"Action": [
				"iot:Publish"
			],
			"Resource": [
				"arn:aws:iot:us-east-1:123456789012:topic/department/admins"
			]
		}
	]
}
```

------
#### [ Unregistered devices ]

For devices not registered in AWS IoT Core registry, the following policy allows devices to connect using either clientId1, clientId2 or clientId3. It provides permission to publish to all topics prefixed with "department/" but not to the "department/admins" subtopic.

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Connect"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:client/clientId1",
                "arn:aws:iot:us-east-1:123456789012:client/clientId2",
                "arn:aws:iot:us-east-1:123456789012:client/clientId3"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iot:Publish"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:topic/department/*"
            ]
        },
        {
            "Effect": "Deny",
            "Action": [
                "iot:Publish"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:topic/department/admins"
            ]
        }
    ]
}
```

------

## Policies to deny receiving messages from subtopics of a topic name


The following shows examples for registered and unregistered devices to subscribe to and receive messages from topics with specific prefixes except certain subtopics.

------
#### [ Registered devices ]

For devices registered in AWS IoT Core registry, the following policy allows devices to connect with clientId that matches the name of a thing in the registry. The policy allows devices to subscribe to any topic prefixed with "topic\$1prefix". By using `NotResource` in the statement for `iot:Receive`, we allow the device to receive messages from all topics that the device has subscribed to, except the topics prefixed with "topic\$1prefix/restricted". For example, with this policy, devices can subscribe to "topic\$1prefix/topic1" and even "topic\$1prefix/restricted", however, they will only receive messages from the topic "topic\$1prefix/topic1" and no messages from the topic "topic\$1prefix/restricted".

****  

```
{
	"Version":"2012-10-17",		 	 	 
	"Statement": [
		{
			"Effect": "Allow",
			"Action": [
				"iot:Connect"
			],
			"Resource": [
				"arn:aws:iot:us-east-1:123456789012:client/${iot:Connection.Thing.ThingName}"
			],
			"Condition": {
				"Bool": {
					"iot:Connection.Thing.IsAttached": "true"
				}
			}
		},
		{
			"Effect": "Allow",
			"Action": "iot:Subscribe",
			"Resource": "arn:aws:iot:us-east-1:123456789012:topicfilter/topic_prefix/*"
		},
		{
			"Effect": "Allow",
			"Action": "iot:Receive",
			"NotResource": "arn:aws:iot:us-east-1:123456789012:topic/topic_prefix/restricted/*"
		}
	]
}
```

------
#### [ Unregistered devices ]

For devices not registered in AWS IoT Core registry, the following policy allows devices to connect using either clientId1, clientId2 or clientId3. The policy allows devices to subscribe to any topic prefixed with "topic\$1prefix". By using `NotResource` in the statement for `iot:Receive`, we allow the device to receive messages from all topics that the device has subscribed to, except topics prefixed with "topic\$1prefix/restricted". For example, with this policy, devices can subscribe to "topic\$1prefix/topic1" and even "topic\$1prefix/restricted". However, they will only receive messages from the topic "topic\$1prefix/topic1" and no messages from the topic "topic\$1prefix/restricted".

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Connect"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:client/clientId1",
                "arn:aws:iot:us-east-1:123456789012:client/clientId2",
                "arn:aws:iot:us-east-1:123456789012:client/clientId3"
            ]
        },
        {
            "Effect": "Allow",
            "Action": "iot:Subscribe",
            "Resource": "arn:aws:iot:us-east-1:123456789012:topicfilter/topic_prefix/*"
        },
        {
            "Effect": "Allow",
            "Action": "iot:Receive",
            "NotResource": "arn:aws:iot:us-east-1:123456789012:topic/topic_prefix/restricted/*"
        }
    ]
}
```

------

## Policies to subscribe to topics using MQTT wildcard characters


MQTT wildcard characters \$1 and \$1 are treated as literal strings, but they are not treated as wildcards when used in AWS IoT Core policies. In MQTT, \$1 and \$1 are treated as wildcards only when subscribing to a topic filter but as a literal string in all other contexts. We recommend that you only use these MQTT wildcards as part of AWS IoT Core policies after careful consideration.

The following shows examples for registered and unregistered things using MQTT wildcards in AWS IoT Core policies. These wildcards are treated as literal strings.

------
#### [ Registered devices ]

For devices registered in AWS IoT Core registry, the following policy allows devices to connect with clientId that matches the name of a thing in the registry. The policy allows devices to subscribe to the topics "department/\$1/employees" and "location/\$1". Because \$1 and \$1 are treated as literal strings in AWS IoT Core policies, devices can subscribe to the topic "department/\$1/employees" but not to the topic "department/engineering/employees". Similarly, devices can subscribe to the topic "location/\$1" but not to the topic "location/Seattle". However, once the device subscribes to the topic "department/\$1/employees", the policy will allow them to receive messages from the topic "department/engineering/employees". Similarly, once the device subscribes to the topic "location/\$1", they will receive messages from the topic "location/Seattle" as well.

****  

```
{
	"Version":"2012-10-17",		 	 	 
	"Statement": [
		{
			"Effect": "Allow",
			"Action": [
				"iot:Connect"
			],
			"Resource": [
				"arn:aws:iot:us-east-1:123456789012:client/${iot:Connection.Thing.ThingName}"
			],
			"Condition": {
				"Bool": {
					"iot:Connection.Thing.IsAttached": "true"
				}
			}
		},
		{
			"Effect": "Allow",
			"Action": "iot:Subscribe",
			"Resource": "arn:aws:iot:us-east-1:123456789012:topicfilter/department/+/employees"
		},
		{
			"Effect": "Allow",
			"Action": "iot:Subscribe",
			"Resource": "arn:aws:iot:us-east-1:123456789012:topicfilter/location/#"
		},
		{
			"Effect": "Allow",
			"Action": "iot:Receive",
			"Resource": "arn:aws:iot:us-east-1:123456789012:topic/*"
		}
	]
}
```

------
#### [ Unregistered devices ]

For devices not registered in AWS IoT Core registry, the following policy allows devices to connect using either clientId1, clientId2 or clientId3. The policy allows devices to subscribe to the topics of "department/\$1/employees" and "location/\$1". Because \$1 and \$1 are treated as literal strings in AWS IoT Core policies, devices can subscribe to the topic "department/\$1/employees" but not to the topic "department/engineering/employees". Similarly, devices can subscribe to the topic "location/\$1" but not "location/Seattle". However, once the device subscribes to the topic "department/\$1/employees", the policy will allow them to receive messages from the topic "department/engineering/employees". Similarly, once the device subscribes to the topic "location/\$1", they will receive messages from the topic "location/Seattle" as well.

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Connect"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:client/clientId1",
                "arn:aws:iot:us-east-1:123456789012:client/clientId2",
                "arn:aws:iot:us-east-1:123456789012:client/clientId3"
            ]
        },
        {
            "Effect": "Allow",
            "Action": "iot:Subscribe",
            "Resource": "arn:aws:iot:us-east-1:123456789012:topicfilter/department/+/employees"
        },
        {
            "Effect": "Allow",
            "Action": "iot:Subscribe",
            "Resource": "arn:aws:iot:us-east-1:123456789012:topicfilter/location/#"
        },
        {
            "Effect": "Allow",
            "Action": "iot:Receive",
            "Resource": "arn:aws:iot:us-east-1:123456789012:topic/*"
        }
    ]
}
```

------

## Policies for HTTP and WebSocket clients


When you connect over HTTP or the WebSocket protocol, you're authenticating with Signature Version 4 and Amazon Cognito. Amazon Cognito identities can be authenticated or unauthenticated. Authenticated identities belong to users who are authenticated by any supported identity provider. Unauthenticated identities typically belong to guest users who do not authenticate with an identity provider. Amazon Cognito provides a unique identifier and AWS credentials to support unauthenticated identities. For more information, see [Authorization with Amazon Cognito identities](cog-iot-policies.md).

For the following operations, AWS IoT Core uses AWS IoT Core policies attached to Amazon Cognito identities through the `AttachPolicy` API. This scopes down the permissions attached to the Amazon Cognito Identity pool with authenticated identities.
+ `iot:Connect`
+ `iot:Publish`
+ `iot:Subscribe`
+ `iot:Receive`
+ `iot:GetThingShadow`
+ `iot:UpdateThingShadow`
+ `iot:DeleteThingShadow`

That means an Amazon Cognito Identity needs permission from the IAM role policy and the AWS IoT Core policy. You attach the IAM role policy to the pool and the AWS IoT Core policy to the Amazon Cognito Identity through the AWS IoT Core `AttachPolicy` API.

Authenticated and unauthenticated users are different identity types. If you don't attach an AWS IoT policy to the Amazon Cognito Identity, an authenticated user fails authorization in AWS IoT and doesn't have access to AWS IoT resources and actions.

**Note**  
For other AWS IoT Core operations or for unauthenticated identities, AWS IoT Core does not scope down the permissions attached to the Amazon Cognito identity pool role. For both authenticated and unauthenticated identities, this is the most permissive policy that we recommend you attach to the Amazon Cognito pool role.

**HTTP**

To allow unauthenticated Amazon Cognito identities to publish messages over HTTP on a topic specific to the Amazon Cognito Identity, attach the following IAM policy to the Amazon Cognito Identity pool role:

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Publish"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:topic/${cognito-identity.amazonaws.com:sub}"
            ]
        }
    ]
}
```

To allow authenticated users, attach the preceding policy to the Amazon Cognito Identity pool role and to the Amazon Cognito Identity using the AWS IoT Core [AttachPolicy](https://docs.aws.amazon.com//iot/latest/apireference/API_AttachPolicy.html) API.

**Note**  
When authorizing Amazon Cognito identities, AWS IoT Core considers both policies and grants the least privileges specified. An action is allowed only if both policies allow the requested action. If either policy disallows an action, that action is unauthorized.

**MQTT**

To allow unauthenticated Amazon Cognito identities to publish MQTT messages over WebSocket on a topic specific to the Amazon Cognito Identity in your account, attach the following IAM policy to the Amazon Cognito Identity pool role:

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Publish"
            ],
            "Resource": ["arn:aws:iot:us-east-1:123456789012:topic/${cognito-identity.amazonaws.com:sub}"]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iot:Connect"
            ],
            "Resource": ["arn:aws:iot:us-east-1:123456789012:client/${cognito-identity.amazonaws.com:sub}"]
        }
    ]
}
```

To allow authenticated users, attach the preceding policy to the Amazon Cognito Identity pool role and to the Amazon Cognito Identity using the AWS IoT Core [AttachPolicy](https://docs.aws.amazon.com//iot/latest/apireference/API_AttachPolicy.html) API.

**Note**  
When authorizing Amazon Cognito identities, AWS IoT Core considers both and grants the least privileges specified. An action is allowed only if both policies allow the requested action. If either policy disallows an action, that action is unauthorized.

# Connect and publish policy examples


For devices registered as things in the AWS IoT Core registry, the following policy grants permission to connect to AWS IoT Core with a client ID that matches the thing name and restricts the device to publishing on a client-ID or thing name-specific MQTT topic. For a connection to be successful, the thing name must be registered in the AWS IoT Core registry and be authenticated using an identity or principal attached to the thing:

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "iot:Publish"
      ],
      "Resource": [
        "arn:aws:iot:us-east-1:123456789012:topic/${iot:Connection.Thing.ThingName}"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "iot:Connect"
      ],
      "Resource": [
        "arn:aws:iot:us-east-1:123456789012:client/${iot:Connection.Thing.ThingName}"
      ]
    }
  ]
}
```

For devices not registered as things in the AWS IoT Core registry, the following policy grants permission to connect to AWS IoT Core with client ID `client1` and restricts the device to publishing on a clientID-specific MQTT topic:

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "iot:Publish"
      ],
      "Resource": [
        "arn:aws:iot:us-east-1:123456789012:topic/${iot:ClientId}"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "iot:Connect"
      ],
      "Resource": [
        "arn:aws:iot:us-east-1:123456789012:client/client1"
      ]
    }
  ]
}
```

# Retained message policy examples


Using [retained messages](mqtt.md#mqtt-retain) requires specific policies. Retained messages are MQTT messages published with the RETAIN flag set and stored by AWS IoT Core. This section presents examples of policies that allow common uses of retained messages.

**Topics**
+ [

## Policy to connect and publish retained messages
](#retained-message-policy-examples-publish)
+ [

## Policy to connect and publish retained Will messages
](#retained-message-policy-examples-publish-lwt)
+ [

## Policy to list and get retained messages
](#retained-message-policy-examples-list-get)

## Policy to connect and publish retained messages


For a device to publish retained messages, the device must be able to connect, publish (any MQTT message), and publish MQTT retained messages. The following policy grants these permissions for the topic: `device/sample/configuration` to client **device1**. For another example that grants permission to connect, see [Connect and publish policy examples](connect-and-pub.md).

****  

```
{
	"Version":"2012-10-17",		 	 	 
	"Statement": [
		{
			"Effect": "Allow",
			"Action": [
				"iot:Connect"
			],
			"Resource": [
				"arn:aws:iot:us-east-1:123456789012:client/device1"
			]
		},
		{
			"Effect": "Allow",
			"Action": [
				"iot:Publish",
				"iot:RetainPublish"
			],
			"Resource": [
				"arn:aws:iot:us-east-1:123456789012:topic/device/sample/configuration"
			]
		}
	]
}
```

## Policy to connect and publish retained Will messages


Clients can configure a message that AWS IoT Core will publish when the client disconnects unexpectedly. MQTT calls such a message a [*Will* message](http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/errata01/os/mqtt-v3.1.1-errata01-os-complete.html#_Will_Flag). A client must have an additional condition added to its connect permission to include them. 

The following policy document grants all clients permission to connect and publish a Will message, identified by its topic, `will`, that AWS IoT Core will also retain.

****  

```
{
	"Version":"2012-10-17",		 	 	 
	"Statement": [
		{
			"Effect": "Allow",
			"Action": [
				"iot:Connect"
			],
			"Resource": [
				"arn:aws:iot:us-east-1:123456789012:client/device1"
			],
			"Condition": {
				"ForAllValues:StringEquals": {
					"iot:ConnectAttributes": [
						"LastWill"
					]
				}
			}
		},
		{
			"Effect": "Allow",
			"Action": [
				"iot:Publish",
				"iot:RetainPublish"
			],
			"Resource": [
				"arn:aws:iot:us-east-1:123456789012:topic/will"
			]
		}
	]
}
```

## Policy to list and get retained messages


Services and applications can access retained messages without the need to support an MQTT client by calling [https://docs.aws.amazon.com//iot/latest/apireference/API_iotdata_ListRetainedMessages.html](https://docs.aws.amazon.com//iot/latest/apireference/API_iotdata_ListRetainedMessages.html) and [https://docs.aws.amazon.com//iot/latest/apireference/API_iotdata_GetRetainedMessage.html](https://docs.aws.amazon.com//iot/latest/apireference/API_iotdata_GetRetainedMessage.html). The services and applications that call these actions must be authorized by using a policy such as the following example.

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:ListRetainedMessages"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:client/device1"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iot:GetRetainedMessage"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:topic/foo"
            ]
        }
    ]
}
```

# Certificate policy examples


For devices registered in AWS IoT Core registry, the following policy grants permission to connect to AWS IoT Core with a client ID that matches a thing name, and to publish to a topic whose name is equal to the `certificateId` of the certificate the device used to authenticate itself:

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Publish"
            ],
            "Resource": ["arn:aws:iot:us-east-1:123456789012:topic/${iot:CertificateId}"]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iot:Connect"
            ],
            "Resource": ["arn:aws:iot:us-east-1:123456789012:client/${iot:Connection.Thing.ThingName}"]
        }
    ]
}
```

For devices not registered in the AWS IoT Core registry, the following policy grants permission to connect to AWS IoT Core with client IDs, `client1`, `client2`, and `client3` and to publish to a topic whose name is equal to the `certificateId` of the certificate the device used to authenticate itself:

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Publish"
            ],
            "Resource": ["arn:aws:iot:us-east-1:123456789012:topic/${iot:CertificateId}"]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iot:Connect"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:client/client1",
                "arn:aws:iot:us-east-1:123456789012:client/client2",
                "arn:aws:iot:us-east-1:123456789012:client/client3"
            ]
        }
    ]
}
```

For devices registered in AWS IoT Core registry, the following policy grants permission to connect to AWS IoT Core with a client ID that matches the thing name, and to publish to a topic whose name is equal to the subject's `CommonName` field of the certificate the device used to authenticate itself:

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Publish"
            ],
            "Resource": ["arn:aws:iot:us-east-1:123456789012:topic/${iot:Certificate.Subject.CommonName}"]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iot:Connect"
            ],
            "Resource": ["arn:aws:iot:us-east-1:123456789012:client/${iot:Connection.Thing.ThingName}"]
        }
    ]
}
```

**Note**  
In this example, the certificate's subject common name is used as the topic identifier, with the assumption that the subject common name is unique for each registered certificate. If the certificates are shared across multiple devices, the subject common name is the same for all the devices that share this certificate, thereby allowing publish privileges to the same topic from multiple devices (not recommended).

For devices not registered in AWS IoT Core registry, the following policy grants permission to connect to AWS IoT Core with client IDs, `client1`, `client2`, and `client3` and to publish to a topic whose name is equal to the subject's `CommonName` field of the certificate the device used to authenticate itself:

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Publish"
            ],
            "Resource": ["arn:aws:iot:us-east-1:123456789012:topic/${iot:Certificate.Subject.CommonName}"]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iot:Connect"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:client/client1",
                "arn:aws:iot:us-east-1:123456789012:client/client2",
                "arn:aws:iot:us-east-1:123456789012:client/client3"
            ]
        }
    ]
}
```

**Note**  
In this example, the certificate's subject common name is used as the topic identifier, with the assumption that the subject common name is unique for each registered certificate. If the certificates are shared across multiple devices, the subject common name is the same for all the devices that share this certificate, thereby allowing publish privileges to the same topic from multiple devices (not recommended).

For devices registered in the AWS IoT Core registry, the following policy grants permission to connect to AWS IoT Core with a client ID that matches the thing name, and to publish to a topic whose name is prefixed with `admin/` when the certificate used to authenticate the device has its `Subject.CommonName.2` field set to `Administrator`:

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Connect"
            ],
            "Resource": ["arn:aws:iot:us-east-1:123456789012:client/${iot:Connection.Thing.ThingName}"]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iot:Publish"
            ],
            "Resource": ["arn:aws:iot:us-east-1:123456789012:topic/admin/*"],
            "Condition": {
                "StringEquals": {
                    "iot:Certificate.Subject.CommonName.2": "Administrator"
            }
        }
        }
    ]
}
```

For devices not registered in AWS IoT Core registry, the following policy grants permission to connect to AWS IoT Core with client IDs `client1`, `client2`, and `client3` and to publish to a topic whose name is prefixed with `admin/` when the certificate used to authenticate the device has its `Subject.CommonName.2` field set to `Administrator`:

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Connect"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:client/client1",
                "arn:aws:iot:us-east-1:123456789012:client/client2",
                "arn:aws:iot:us-east-1:123456789012:client/client3"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iot:Publish"
            ],
            "Resource": ["arn:aws:iot:us-east-1:123456789012:topic/admin/*"],
            "Condition": {
                "StringEquals": {
                    "iot:Certificate.Subject.CommonName.2": "Administrator"
            }
        }
        }
    ]
}
```

For devices registered in AWS IoT Core registry, the following policy allows a device to use its thing name to publish on a specific topic that consists of `admin/` followed by the `ThingName` when the certificate used to authenticate the device has any one of its `Subject.CommonName` fields set to `Administrator`:

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Connect"
            ],
            "Resource": ["arn:aws:iot:us-east-1:123456789012:client/${iot:Connection.Thing.ThingName}"]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iot:Publish"
            ],
            "Resource": ["arn:aws:iot:us-east-1:123456789012:topic/admin/${iot:Connection.Thing.ThingName}"],
            "Condition": {
                "ForAnyValue:StringEquals": {
                    "iot:Certificate.Subject.CommonName.List": "Administrator"
            }
        }
        }
    ]
}
```

For devices not registered in AWS IoT Core registry, the following policy grants permission to connect to AWS IoT Core with client IDs `client1`, `client2`, and `client3` and to publish to the topic `admin` when the certificate used to authenticate the device has any one of its `Subject.CommonName` fields set to `Administrator`:

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Connect"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:client/client1",
                "arn:aws:iot:us-east-1:123456789012:client/client2",
                "arn:aws:iot:us-east-1:123456789012:client/client3"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iot:Publish"
            ],
            "Resource": ["arn:aws:iot:us-east-1:123456789012:topic/admin"],
            "Condition": {
                "ForAnyValue:StringEquals": {
                    "iot:Certificate.Subject.CommonName.List": "Administrator"
            }
        }
        }
    ]
}
```

# Thing policy examples


The following policy allows a device to connect if the certificate used to authenticate with AWS IoT Core is attached to the thing for which the policy is being evaluated:

****  

```
{  
    "Version":"2012-10-17",		 	 	 
    "Statement":[
        {  
            "Effect":"Allow",
            "Action":["iot:Connect"],
            "Resource":[ "*" ],
            "Condition": {
                "Bool": {
                    "iot:Connection.Thing.IsAttached": ["true"]
            }
        }
        }
    ]
}
```

The following policy allows a device to publish if the certificate is attached to a thing with a particular thing type and if the thing has an attribute of `attributeName` with value `attributeValue`. For more information about thing policy variables, see [Thing policy variables](thing-policy-variables.md).

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "iot:Publish"
      ],
      "Resource": "arn:aws:iot:us-east-1:123456789012:topic/device/stats",
      "Condition": {
        "StringEquals": {
          "iot:Connection.Thing.Attributes[attributeName]": "attributeValue",
          "iot:Connection.Thing.ThingTypeName": "Thing_Type_Name"
        },
        "Bool": {
          "iot:Connection.Thing.IsAttached": "true"
        }
      }
    }
  ]
}
```

The following policy allows a device to publish to a topic that starts with an attribute of the thing. If the device certificate is not associated with the thing, this variable won't be resolved and will result in an access denied error. For more information about thing policy variables, see [Thing policy variables](thing-policy-variables.md).

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "iot:Publish"
      ],
      "Resource": "arn:aws:iot:us-east-1:123456789012:topic/${iot:Connection.Thing.Attributes[attributeName]}/*"
    }
  ]
}
```

# Basic job policy example


This sample shows the policy statments required for a job target that's a single device to receive a job request and communicate job execution status with AWS IoT.

Replace *us-west-2:57EXAMPLE833* with your AWS Region, a colon character (:), and your 12-digit AWS account number, and then replace *uniqueThingName* with the name of the thing resource that represents the device in AWS IoT.

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Connect"
            ],
            "Resource": [
                "arn:aws:iot:us-west-2:123456789012:client/uniqueThingName"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iot:Publish"
            ],
            "Resource": [
                "arn:aws:iot:us-west-2:123456789012:topic/test/dc/pubtopic",
                "arn:aws:iot:us-west-2:123456789012:topic/$aws/events/job/*",
                "arn:aws:iot:us-west-2:123456789012:topic/$aws/events/jobExecution/*",
                "arn:aws:iot:us-west-2:123456789012:topic/$aws/things/uniqueThingName/jobs/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iot:Subscribe"
            ],
            "Resource": [
                "arn:aws:iot:us-west-2:123456789012:topicfilter/test/dc/subtopic",
                "arn:aws:iot:us-west-2:123456789012:topicfilter/$aws/events/jobExecution/*",
                "arn:aws:iot:us-west-2:123456789012:topicfilter/$aws/things/uniqueThingName/jobs/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iot:Receive"
            ],
            "Resource": [
                "arn:aws:iot:us-west-2:123456789012:topic/test/dc/subtopic",
                "arn:aws:iot:us-west-2:123456789012:topic/$aws/things/uniqueThingName/jobs/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iotjobsdata:DescribeJobExecution",
                "iotjobsdata:GetPendingJobExecutions",
                "iotjobsdata:StartNextPendingJobExecution",
                "iotjobsdata:UpdateJobExecution"
            ],
            "Resource": [
                "arn:aws:iot:us-west-2:123456789012:topic/$aws/things/uniqueThingName"
            ]
        }
    ]
}
```

# Authorization with Amazon Cognito identities


There are two types of Amazon Cognito identities: unauthenticated and authenticated. If your app supports unauthenticated Amazon Cognito identities, no authentication is performed, so you don't know who the user is. 

**Unauthenticated Identities:** For unauthenticated Amazon Cognito identities, you grant permissions by attaching an IAM role to an unauthenticated identity pool. We recommend that you only grant access to those resources you want available to unknown users.

**Important**  
For unauthenticated Amazon Cognito users connecting to AWS IoT Core, we recommend that you give access to very limited resources in IAM policies.

**Authenticated Identities:** For authenticated Amazon Cognito identities, you need to specify permissions in two places: 
+ Attach an IAM policy to the authenticated Amazon Cognito Identity pool and
+ Attach an AWS IoT Core policy to the Amazon Cognito Identity (authenticated user).

## Policy examples for unauthenticated and authenticated Amazon Cognito users connecting to AWS IoT Core


The following example shows permissions in both the IAM policy and the IoT policy of an Amazon Cognito identity. The authenticated user wants to publish to a device specific topic (e.g. device/DEVICE\$1ID/status).

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Connect"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:client/Client_ID"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iot:Publish"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:topic/device/Device_ID/status"
            ]
        }
    ]
}
```

The following example shows the permissions in an IAM policy of an Amazon Cognito unauthenticated role. The unauthenticated user wants to publish to non-device specific topics that do not require authentication.

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Connect"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:client/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iot:Publish"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:topic/non_device_specific_topic"
            ]
        }
    ]
}
```

## GitHub examples


The following example web applications on GitHub show how to incorporate policy attachment to authenticated users into the user signup and authentication process.
+ [MQTT publish/subscribe React web application using AWS Amplify and the AWS IoT Device SDK for JavaScript](https://github.com/aws-samples/aws-amplify-react-iot-pub-sub-using-cp)
+ [MQTT publish/subscribe React web application using AWS Amplify, the AWS IoT Device SDK for JavaScript, and a Lambda function](https://github.com/aws-samples/aws-amplify-react-iot-pub-sub-using-lambda)

Amplify is a set of tools and services that helps you build web and mobile applications that integrate with AWS services. For more information about Amplify, see [Amplify Framework Documentation,](https://docs.amplify.aws/).

Both examples perform the following steps.

1. When a user signs up for an account, the application creates an Amazon Cognito user pool and identity.

1. When a user authenticates, the application creates and attaches a policy to the identity. This gives the user publish and subscribe permissions.

1. The user can use the application to publish and subscribe to MQTT topics.

The first example uses the `AttachPolicy` API operation directly inside the authentication operation. The following example demonstrates how to implement this API call inside a React web application that uses Amplify and the AWS IoT Device SDK for JavaScript.

```
function attachPolicy(id, policyName) {
    var Iot = new AWS.Iot({region: AWSConfiguration.region, apiVersion: AWSConfiguration.apiVersion, endpoint: AWSConfiguration.endpoint});
    var params = {policyName: policyName, target: id};

    console.log("Attach IoT Policy: " + policyName + " with cognito identity id: " + id);
    Iot.attachPolicy(params, function(err, data) {
         if (err) {
               if (err.code !== 'ResourceAlreadyExistsException') {
                  console.log(err);
               }
          }
         else  {
            console.log("Successfully attached policy with the identity", data);
         }
     });
}
```

This code appears in the [AuthDisplay.js](https://github.com/aws-samples/aws-amplify-react-iot-pub-sub-using-cp/blob/d1c307b36357be934db9dda020140fa337709cd9/src/AuthDisplay.js#L45) file.

The second example implements the `AttachPolicy` API operation in a Lambda function. The following example shows how the Lambda uses this API call.

```
iot.attachPolicy(params, function(err, data) {
     if (err) {
           if (err.code !== 'ResourceAlreadyExistsException') {
              console.log(err);
              res.json({error: err, url: req.url, body: req.body});
           }
      }
     else  {
        console.log(data);
        res.json({success: 'Create and attach policy call succeed!', url: req.url, body: req.body});
     }
 });
```

This code appears inside the `iot.GetPolicy` function in the [app.js](https://github.com/aws-samples/aws-amplify-react-iot-pub-sub-using-lambda/blob/e493039581d2aff0faa3949086deead20a2c5385/amplify/backend/function/amplifyiotlambda/src/app.js#L50) file.

**Note**  
When you call the function with AWS credentials that you obtain through Amazon Cognito Identity pools, the context object in your Lambda function contains a value for `context.cognito_identity_id`. For more information, see the following.   
[AWS Lambda context object in Node.js](https://docs.aws.amazon.com/lambda/latest/dg/nodejs-context.html)
[AWS Lambda context object in Python](https://docs.aws.amazon.com/lambda/latest/dg/python-context.html)
[AWS Lambda context object in Ruby](https://docs.aws.amazon.com/lambda/latest/dg/ruby-context.html)
[AWS Lambda context object in Java](https://docs.aws.amazon.com/lambda/latest/dg/java-context.html)
[AWS Lambda context object in Go](https://docs.aws.amazon.com/lambda/latest/dg/golang-context.html)
[AWS Lambda context object in C\$1](https://docs.aws.amazon.com/lambda/latest/dg/csharp-context.html)
[AWS Lambda context object in PowerShell](https://docs.aws.amazon.com/lambda/latest/dg/powershell-context.html)