Issue concating policy variables with a string in an iot policy's resource block

1

I am trying to create an iot policy for our devices, and I'm having an issue authorizing two clients to connect. Each one of our devices will establish two different connections, a "main" connection to publish data to a topic, and a separate connection for dealing with the device's shadows. Here is the relevant block from my policy:

{
    "Effect": "Allow",
    "Action": [
        "iot:Connect"
    ],
    "Resource": [
        "arn:aws:iot:us-east-2:<account_id>:client/${iot:Connection.Thing.ThingName}",
        "arn:aws:iot:us-east-2:<account_id>:client/${iot:Connection.Thing.ThingName}_shadow_client"
    ]
}

The "main" connection uses the device's ThingName for the MQTT connection clientId, and I am having no issues with this client connecting. The trouble is with my second "shadow" client, where I am using ThingName + "_shadow_client" for the MQTT connection clientId. For some reason, the above policy does not work for this client, as I am getting the following log in CloudWatch when it tries to connect:

{
    "timestamp": "2022-02-07 19:08:58.979",
    "logLevel": "ERROR",
    "traceId": "<trace>",
    "accountId": "<account_id>",
    "status": "Failure",
    "eventType": "Connect",
    "protocol": "MQTT",
    "clientId": "test_shadow_client",
    "principalId": "<principle_id>",
    "sourceIp": "<source_ip>",
    "sourcePort": <source_port>,
    "reason": "AUTHORIZATION_FAILURE",
    "details": "Authorization Failure"
}

My device's ThingName is test, and my code is correctly setting the MQTT clientId to test_shadow_client (I am using the C++ V2 SDK btw). I have also tested manually setting the "shadow" client resource in the policy to "arn:aws:iot:us-east-2:<account_id>:client/test_shadow_client" and this works.

Is there maybe an issue when trying to concat the policy variable ${iot:Connection.Thing.ThingName} with a string like I am doing when specifying a resource? If so, how might I achieve my goal of having two separate clients that use the ThingName in the clientIds? My ultimate goal is to use the device's serial number as the ThingName, so these two clientIds will have their values programmatically set per device with the convention I'm following in my policy.

EDIT: It appears that iot:Connection.Thing.ThingName gets set to the clientId of the MQTT connection, which does not make sense to me as there is an iot:ClientId policy variable also available. However, this does explain why my policy is not working as expected. Can anyone confirm this?

  • I have the same problem. Did you find a solution?

  • Hello, I'm facing the same issue. Has anyone been able to solve it? I know there's the option of creating another Thing with the second Thing name. but i wanted to avoid having two things for every device

Otto45
asked 2 years ago353 views
1 Answer
1
Accepted Answer

https://docs.aws.amazon.com/iot/latest/developerguide/thing-policy-variables.html

The thing name is obtained from the client ID in the MQTT Connect message sent when a thing connects to AWS IoT Core.

And:

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.

profile pictureAWS
EXPERT
Greg_B
answered 2 years ago
  • Could you clarify on this? For instance if client_id of a connection is "my_thingname__shadow" then "iot:Connection.Thing.ThingName" will evaluate to "my_thingname__shadow" or "my_thingname" ?

    Aren't the following two statements from the docs contradictory ?

    • "The thing name is obtained from the client ID in the MQTT Connect message sent when a thing connects to AWS IoT Core"
    • "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."

    One is saying thing_name = client_id and the other says thing_name = name of the thing in registry.

    Wouldn't that be a security issue if thing name was obtained from client_id? I can then connect with whatever client_id I want and claim access to other things by using their thing_name as my client_id.

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions