1

My goal is to integrate an Alexa-hosted skill with AWS IoT. I'm getting an access denied exception runinng the following python code from this thread:

iota = boto3.client('iotanalytics')  
response = iota.get_dataset_content(datasetName='my_dataset_name',versionId='$LATEST',roleArn = "arn:aws:iam::123456789876:role/iotTest")
contentState = response['status']['state']
        
if (contentState == 'SUCCEEDED') :
    url = response['entries'][0]['dataURI']
    stream = urllib.request.urlopen(url)
    reader = csv.DictReader(codecs.iterdecode(stream, 'utf-8'))        

What's weird is that the get_dataset_content() method described here has no mention of needing permissions or credentials. Despite this, I have also gone through the steps to use personal AWS resources with my alexa-hosted skill with no luck. As far as I can tell there is no place for me to specify the ARN of the role with the correct permissions. What am I missing?

Oh, and here's the error message the code above throws:

botocore.exceptions.ClientError: An error occurred (AccessDeniedException) when calling the GetDatasetContent operation: User: arn:aws:sts::123456789876:assumed-role/AlexaHostedSkillLambdaRole/a224ab4e-8192-4469-b56c-87ac9a34a3e8 is not authorized to perform: iotanalytics:GetDatasetContent on resource: arn:aws:iotanalytics:us-east-1:123456789876:dataset/my_project_name

I have created a role called demo, which has complete admin access. I have also given it the following trust relationship:

  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "iotanalytics.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    },
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789876:role/AlexaHostedSkillLambdaRole"
      },
      "Action": "sts:AssumeRole"
    }
  ]
} 

--- The trust relationships tab displays this as well: ---
Trusted entities
The identity provider(s) iotanalytics.amazonaws.com
arn:aws:iam::858273942573:role/AlexaHostedSkillLambdaRole
Raisin
  • 345
  • 1
  • 9

2 Answers2

1

I ran into this today and after an hour of pondering what is going on, i figured out my problem, and i think it may be the same as what you were running into.

As it turns out, most of the guides out there don't mention the fact that you have to do some work to have the assumed role be the actual role that is used when you build up the boto3 resource or client.

This is a good reference for that - AWS: Boto3: AssumeRole example which includes role usage

Basically, from my understanding, if you do not do that, the boto3 commands will still execute under the same base role that the Alexa Lambda uses - you must first create the assumed role, and then use it.

Additionally, your role you're assuming must have the privileges that it needs to do what you are trying to do - but that's the easy part.

user2338408
  • 182
  • 1
  • 11
0

As I look at your code, I see: roleArn = "arn:aws:iam::123456789876:role/iotTest"

Replace it with the correct ARN of a role that has allow iotanalytics:GetDatasetContent

In addition, I assume you didn't paste all of your code, since you are trying to access the arn:aws:iotanalytics:us-east-1:123456789876:dataset/my_project_name I have doubts that your account id is 123456789876, it looks like you miss some more ARNs in your code.

Tarlog
  • 10,024
  • 2
  • 43
  • 67
  • I changed the ARNs because I don't want to post my account information on the internet. In my actual code I used the ARN of a role with all permissions, no permission boundaries, and with a trust relationship linking it to the alexa hosted skill. I will admit that I'm new to the system of AWS permissions and I may have missed something. – Raisin Dec 23 '20 at 19:41
  • In AWS unless you are using the root user, you need to use a role with proper permissions. The exception you got clearly state which permission is missing. – Tarlog Dec 23 '20 at 23:08
  • If your code runs within lambda, add the policy to the lambda's role. – Tarlog Dec 23 '20 at 23:09
  • It's not exactly lambda, it's an alexa-hosted service. The code executes with the following role. arn:aws:iam::123456789876:role/AlexaHostedSkillLambdaRole This role doesn't show up in my list of roles and I don't believe I can attach policies to it. I also have an admin role I created following these instructions, but it doesn't solve the issue. https://developer.amazon.com/en-US/docs/alexa/hosted-skills/alexa-hosted-skills-personal-aws.html – Raisin Dec 24 '20 at 21:29
  • Did you add trust relationship to the AlexaHostedSkillLambdaRole and then added STS code as the guide says? STS allows "extending" role, so in your lambda you actually try to use a different role from a different account. – Tarlog Dec 25 '20 at 01:06
  • I believe I have done that. I updated the original post with the JSON document I used in the trust relationships tab. – Raisin Dec 30 '20 at 18:01
  • Action should be GetDatasetContent – Tarlog Dec 30 '20 at 22:03
  • When I try to change either action in the JSON file I get this: ```An error occurred: AssumeRole policy may only specify STS AssumeRole actions``` – Raisin Dec 31 '20 at 01:28
  • It should be: "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "iotanalytics:GetDatasetContent", "Resource": "*" } , "Action": "sts:AssumeRole" }, { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::123456789876:role/AlexaHostedSkillLambdaRole" }, "Action": "sts:AssumeRole" } ] } – Tarlog Dec 31 '20 at 02:59
  • The JSON you suggested does not fix the issue, and I'm pretty sure my JSON is fine after reading more. I think the issue may be with the code itself; there is no point in the code that assumes the *admin_role*. The 'roleArn=' argument I added does nothing, and it's not listed in the documentation of the original function. I would think that some type of authentication needs to happen in order to call [get_dataset_content()](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/iotanalytics.html#IoTAnalytics.Client.get_dataset_content) but I'm not sure how to implement this – Raisin Jan 01 '21 at 19:47
  • I don't think your json is fine. You need to allow action "iotanalytics:GetDatasetContent" on the iotanalytics. Not assumeRole – Tarlog Jan 02 '21 at 01:26
  • See this guide how to write the assume role code: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-api.html This show exactly how to get the authentication tokens. Then you can use these tokens when you create a client to iotanalytics. – Tarlog Jan 02 '21 at 01:28
  • The JSON is fine because the permissions get handled in the policy document, not the trust relationships document. However, the guide you shared is extremely helpful, thank you for all the help and patience! – Raisin Jan 03 '21 at 04:40