0

I have a device that uses MQTT via 8883 to send data to AWS IoT Core. During intial testing I applied a very permissive policy and it can connect. When I try to make the policy more restrictive I run into a weird scenario where the connection fails to authenticate when I use anything other than "iot:*" for action and "*" for the resource. The policy that succeeds is

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ConnectIfCertAttachedToAThing",
      "Condition": {
        "Bool": {
          "iot:Connection.Thing.IsAttached": "true"
        },
        "StringEquals": {
          "iot:ClientId": "${iot:Connection.Thing.ThingName}"
        }
      },
      "Effect": "Allow",
      "Action": "iot:*",
      "Resource": "*"
    },
    {
      "Sid": "PublishUnderAttachedThingRoot",
      "Effect": "Allow",
      "Action": "iot:Publish",
      "Resource": "arn:aws:iot:${aws:Region}:${aws:AccountId}:topic/${iot:Connection.Thing.ThingName}/*"
    },
    {
      "Sid": "SubReceiveUnderAttachedThingRoot",
      "Effect": "Allow",
      "Action": "iot:Subscribe",
      "Resource": "arn:aws:iot:${aws:Region}:${aws:AccountId}:topicfilter/${iot:Connection.Thing.ThingName}/*"
    },
    {
      "Sid": "ReceiveMessages",
      "Effect": "Allow",
      "Action": "iot:Receive",
      "Resource": "arn:aws:iot:${aws:Region}:${aws:AccountId}:topic/${iot:Connection.Thing.ThingName}/*"
    }
  ]
}

but the policy I want to use and that fails is

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ConnectIfCertAttachedToAThing",
      "Condition": {
        "Bool": {
          "iot:Connection.Thing.IsAttached": "true"
        },
        "StringEquals": {
          "iot:ClientId": "${iot:Connection.Thing.ThingName}"
        }
      },
      "Effect": "Allow",
      "Action": "iot:*",
      "Resource": [
        "arn:aws:iot:${aws:Region}:${aws:AccountId}:client/${iot:Connection.Thing.ThingName}"
      ]
    },
    {
      "Sid": "PublishUnderAttachedThingRoot",
      "Effect": "Allow",
      "Action": "iot:Publish",
      "Resource": "arn:aws:iot:${aws:Region}:${aws:AccountId}:topic/${iot:Connection.Thing.ThingName}/*"
    },
    {
      "Sid": "SubReceiveUnderAttachedThingRoot",
      "Effect": "Allow",
      "Action": "iot:Subscribe",
      "Resource": "arn:aws:iot:${aws:Region}:${aws:AccountId}:topicfilter/${iot:Connection.Thing.ThingName}/*"
    },
    {
      "Sid": "ReceiveMessages",
      "Effect": "Allow",
      "Action": "iot:Receive",
      "Resource": "arn:aws:iot:${aws:Region}:${aws:AccountId}:topic/${iot:Connection.Thing.ThingName}/*"
    }
  ]
}

I have verified via CloudWatch debug logs that the clientId and thingName match.

New contributor
Paul V is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.

1 Answer 1

-2

Use ${iot:ClientId} for the Resource

The most robust way to handle this—while staying restrictive—is to use the Client ID variable for the Resource ARN and use the Condition block to enforce that the Client ID must match the Thing Name.

Here is the corrected and optimized policy:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ConnectWithClientIdValidation",
      "Effect": "Allow",
      "Action": "iot:Connect",
      "Resource": [
        "arn:aws:iot:${aws:Region}:${aws:AccountId}:client/${iot:ClientId}"
      ],
      "Condition": {
        "Bool": {
          "iot:Connection.Thing.IsAttached": "true"
        },
        "StringEquals": {
          "iot:ClientId": "${iot:Connection.Thing.ThingName}"
        }
      }
    },
    {
      "Sid": "PublishUnderAttachedThingRoot",
      "Effect": "Allow",
      "Action": "iot:Publish",
      "Resource": "arn:aws:iot:${aws:Region}:${aws:AccountId}:topic/${iot:Connection.Thing.ThingName}/*"
    },
    {
      "Sid": "SubReceiveUnderAttachedThingRoot",
      "Effect": "Allow",
      "Action": [
        "iot:Subscribe",
        "iot:Receive"
      ],
      "Resource": [
        "arn:aws:iot:${aws:Region}:${aws:AccountId}:topicfilter/${iot:Connection.Thing.ThingName}/*",
        "arn:aws:iot:${aws:Region}:${aws:AccountId}:topic/${iot:Connection.Thing.ThingName}/*"
      ]
    }
  ]
}
New contributor
unknown is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
Sign up to request clarification or add additional context in comments.

1 Comment

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.