How to create a certificate policy which lets multiple clients connect to one thing in AWS IoT?

0

Setup

I have system in which there are multiple services running and all of them need to connect to one single thing. The clientID of my main service is the thingName itself. However, the ClientID for my other services look like thingName-jobs, thingName-test etc. What I would like to achieve is to create a policy which lets these services connect, and subscribe and publish to topics restricted by thingName.

Problem

Connect

My problem is, in the policy, inside iot:connect, only services with clientID as thingName can connect even though I have let all services clientID present.

{
    "Effect": "Allow",
    "Action": "iot:Connect",
    "Resource": [
        "arn:aws:iot:eu-west-2:000000000000/${iot.Thing.ThingName}",
        "arn:aws:iot:eu-west-2:000000000000/${iot.Thing.ThingName}-jobs",
        "arn:aws:iot:eu-west-2:000000000000/${iot.Thing.ThingName}-test",
        ]
}

Here, thingName-jobs and thingName-test connections are getting refused.

Subscribe

{
      "Effect": "Allow",
      "Action": "iot:Subscribe",
      "Resource": [
        "arn:aws:iot:eu-west-2:000000000000:topicfilter/*/${iot:Connection.Thing.ThingName}/*",
        "arn:aws:iot:eu-west-2:000000000000:topicfilter/$aws/things/${iot:Connection.Thing.ThingName}/jobs/*"
      ]
    },

Here, clients with clientID != thingName cannot subscribe to these topics.

Publish

Same goes for publish.

{
      "Effect": "Allow",
      "Action": "iot:Publish",
      "Resource": [
        "arn:aws:iot:eu-west-2:000000000000:topic/*/${iot:Connection.Thing.ThingName}/*",
        "arn:aws:iot:eu-west-2:000000000000:topic/$aws/things/${iot:Connection.Thing.ThingName}/jobs/*"
      ]
    },

I know using certificate variables is an option, but some of these devices are already on site and I don't have the option to create/change their certificates. I need a policy which restricts clients to connect, publish and subscribe to topics restricted by thingName. Is this possible without using certificate variables or wildcards.

1 Answer
1

Hi. I think you have already seen answers sharing this information: 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.

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.

So, when you have ${iot.Thing.ThingName}-jobs in the resource of your policy, and client thingName-jobs connects, you end up with thingName-jobs-jobs as the resource. And similar for other combinations.

all of them need to connect to one single thing

Clients don't connect to a thing. In AWS IoT Core, things are just a way to organize your fleet. You don't need any things defined. Your services could all connect to AWS IoT Core, so long as the X.509 certificates are registered.

Based on what you described in your question, I recommend you create a thing for each service. Where, of course, the thing name is the same as the client ID used by each service. Then you can use the thing name policy variable to easily write scalable least-privilege policies.

profile pictureAWS
EXPERT
Greg_B
answered 4 months ago

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