Skip to content

Can't restric Publish policy for thing with nRF

0

Hi all, Let me explain my context, I have a custom board build with an nRF9151. I want to use mqtt, so I use nRF AWS library explain here.

In AWS iot console I have create a thing with name CLIENT_ID. I have a certifacte with a policy attached. In my project I want to be able to

  • Publish to topics like CLIENT_ID/*, example CLIENT_ID/data
  • Receive from topics like CLIENT_ID/*, example CLIENT_ID/update

In my prj.conf here is my AWS iot conf:

CONFIG_AWS_IOT=y
CONFIG_AWS_IOT_CLIENT_ID_STATIC="CLIENT_ID"
CONFIG_AWS_IOT_BROKER_HOST_NAME="MY_END_POINT"
CONFIG_AWS_IOT_AUTO_DEVICE_SHADOW_REQUEST=n

And here is my policy (I added shadow because if CONFIG_AWS_IOT_AUTO_DEVICE_SHADOW_REQUEST=y nRF subscride to shadow automatically, but for the moment I disabled it):

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "iot:Connect",
      "Resource": "arn:aws:iot:eu-west-3:ACCOUNT_ID:client/CLIENT_ID"
    },
    {
      "Effect": "Allow",
      "Action": "iot:Publish",
      "Resource": [
        "arn:aws:iot:eu-west-3:ACCOUNT_ID:topic/CLIENT_ID/*",
        "arn:aws:iot:eu-west-3:ACCOUNT_ID:topic/$aws/things/CLIENT_ID/shadow/*"
      ]
    },
    {
      "Effect": "Allow",
      "Action": "iot:Subscribe",
      "Resource": [
        "arn:aws:iot:eu-west-3:ACCOUNT_ID:topicfilter/CLIENT_ID/*",
        "arn:aws:iot:eu-west-3:ACCOUNT_ID:topicfilter/$aws/things/CLIENT_ID/shadow/*"
      ]
    },
    {
      "Effect": "Allow",
      "Action": "iot:Receive",
      "Resource": [
        "arn:aws:iot:eu-west-3:ACCOUNT_ID:topic/CLIENT_ID/*",
        "arn:aws:iot:eu-west-3:ACCOUNT_ID:topic/$aws/things/CLIENT_ID/shadow/*"
      ]
    }
  ]
}

With this policy I got an AUTHORIZATION_FAILURE in log :

{
    "timestamp": "2025-05-13 06:59:55.354",
    "logLevel": "ERROR",
    "traceId": "removed,
    "accountId": "ACCOUNT_ID",
    "status": "Failure",
    "eventType": "Connect",
    "protocol": "MQTT",
    "clientId": "CLIENT_ID",
    "principalId": "removed",
    "sourceIp": "removed",
    "sourcePort": 56875,
    "reason": "AUTHORIZATION_FAILURE",
    "details": "Authorization Failure"
}

The strange thing is, if I replace

    {
      "Effect": "Allow",
      "Action": "iot:Publish",
      "Resource": [
        "arn:aws:iot:eu-west-3:ACCOUNT_ID:topic/CLIENT_ID/*",
        "arn:aws:iot:eu-west-3:ACCOUNT_ID:topic/$aws/things/CLIENT_ID/shadow/*"
      ]
    },

by

    {
      "Effect": "Allow",
      "Action": "iot:Publish",
      "Resource":  "arn:aws:iot:eu-west-3:ACCOUNT_ID:topic/*"
    },

Everything works, I can connect, publish, receive and subscride. Example of logs when everything works:

{
    "timestamp": "2025-05-13 07:16:32.495",
    "logLevel": "INFO",
    "traceId": "removed",
    "accountId": "ACCOUNT_ID",
    "status": "Success",
    "eventType": "Connect",
    "protocol": "MQTT",
    "clientId": "CLIENT_ID",
    "principalId": "removed",
    "sourceIp": "removed",
    "sourcePort": 53267
}

{
    "timestamp": "2025-05-13 07:16:32.635",
    "logLevel": "INFO",
    "traceId": "removed",
    "accountId": "ACCOUNT_ID",
    "status": "Success",
    "eventType": "Subscribe",
    "protocol": "MQTT",
    "topicName": "CLIENT_ID/example,CLIENT_ID/example_2",
    "clientId": "CLIENT_ID",
    "principalId": "removed",
    "sourceIp": "removed",
    "sourcePort": 53267
}

{
    "timestamp": "2025-05-13 07:16:32.768",
    "logLevel": "INFO",
    "traceId": "removed",
    "accountId": "ACCOUNT_ID",
    "status": "Success",
    "eventType": "Publish-In",
    "protocol": "MQTT",
    "topicName": "CLIENT_ID/send",
    "clientId": "CLIENT_ID",
    "principalId": "removed",
    "sourceIp": "removed",
    "sourcePort": 53267
}

Thanks for your help

  • ok find it, the problem was coming from nRF aws iot and CONFIG from MQTT_HELPER_LAST_WILL set to y

asked a year ago166 views

1 Answer
0

The issue you're experiencing is likely related to how the AWS IoT Core policy variables are being interpreted in your policy. The problem stems from the mismatch between your device's client ID and the thing name used in the policy.

In your configuration, you've set:

CONFIG_AWS_IOT_CLIENT_ID_STATIC="CLIENT_D"

However, your policy is using "CLIENT_ID" in the resource ARNs. This mismatch is causing the AUTHORIZATION_FAILURE.

To resolve this, you need to ensure that the client ID used by your device matches exactly with the thing name in your AWS IoT Core. In this case, you should change your configuration to:

CONFIG_AWS_IOT_CLIENT_ID_STATIC="CLIENT_ID"

Alternatively, you could change your thing name in AWS IoT Core to match "CLIENT_D".

The reason why the policy works when you allow publishing to all topics ("arn:aws:iot:eu-west-3:ACCOUNT_ID:topic/*") is that it's not relying on the client ID or thing name matching.

For a more secure and restrictive policy, you should use the ${iot:Connection.Thing.ThingName} policy variable instead of hardcoding the client ID/thing name. This variable will automatically be replaced with the actual thing name used during the connection. Your publish resource in the policy would then look like:

"Resource": [ "arn:aws:iot:eu-west-3:ACCOUNT_ID:topic/${iot:Connection.Thing.ThingName}/", "arn:aws:iot:eu-west-3:ACCOUNT_ID:topic/$aws/things/${iot:Connection.Thing.ThingName}/shadow/" ]

Remember, when using this variable, the client ID used to connect must exactly match the thing name in AWS IoT Core. This approach allows for a more flexible and secure policy that doesn't need to be updated if you change the thing name or want to use the same policy for multiple devices.
Sources
Policy Thing Problem | AWS re:Post
IoT policy to restrict MQTT publish/subscribe by Thing Name | AWS re:Post
AWS IoT policies overly permissive - AWS IoT Device Defender

answered a year 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.