I'm using flutter/dart (mqtt_client / https://pub.dev/packages/mqtt_client) to send an AWS IOT MQTT messages over websockets and I'd like to restrict an IAM user to only specific topics that a user is allowed to Publish messages only to their specific topic. I've attempted to add some restricted policies, but the application will fail with little information on the client side. Also, in Cloud Watch, I don't see any specific errors.
Here's some example topics:
arn:aws:iot:us-east-2:666121319217:topic/action_request/ASDF1234
arn:aws:iot:us-east-2:666121319217:topic/action_request/ASDF5678
So, I want to add the proper JSON policy attached to the IAM user and they only have access to ASDF1234
All of my publish topics are patterned like the above. For now, I'm focusing on restricting the Publish endpoints and then working others like Subscribe.
I've tried numerous different policies like below. Also with adding some wildcards to no success on the client side. They look right, but I'm not sure if there's indirectly other publish topics that are used internally within MQTT that's causing the failures or maybe just my syntax.
Another thought is if I add a condition that would allow only the above endpoint and no others.
https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"iot:Receive",
"iot:ListNamedShadowsForThing",
"iot:Subscribe",
"iot:Connect",
"iot:GetThingShadow",
"iot:DeleteThingShadow",
"iot:UpdateThingShadow"
],
"Resource": "*"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "iot:Publish",
"Resource": "arn:aws:iot:us-east-2:1234567890:topic/*/ASDF1234*"
}
]
}
Related
I am working on serverless where it would be used to deploy lambda functions and corresponding REST APIs using API Gateway.
The problem I am facing is that I need to give programmatic user permission to create API-Gateway with specific prefix only.
Giving permission for POST action on this resource "arn:aws:apigateway:us-east-1::/restapis" seems to give permission to create apis with any name, and "arn:aws:apigateway:us-east-1::/restapis/ps-sls-*/*" doesn't seems to working (ps-sls- is the prefix).
AWS docs are abhorently unclear to me regarding this topic.
Here's a snippet of policy doc I am using
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"s3:*",
"lambda:*",
"cloudformation:*",
"apigateway:*"
],
"Resource": [
"arn:aws:cloudformation:us-east-1:XXXXXXXXXX:stack/ps-sls-*/*",
"arn:aws:lambda:us-east-1:XXXXXXXXXXX:function:ps-sls-*",
"arn:aws:apigateway:us-east-1::/restapis",
"arn:aws:s3:::ps-sls-*"
]
}
AWS documentation has examples of different SNS access control configurations.
There are two similar configuration examples:
The first one allows to publish notifications from another account's S3 bucket to SNS topic:
{
"Effect": "Allow",
"Principal": {
"Service": "s3.amazonaws.com"
},
"Action": "sns:Publish",
"Resource": "arn:aws:sns:us-east-2:111122223333:MyTopic",
"Condition": {
"StringEquals": {
"AWS:SourceAccount": "444455556666"
}
}
}
The second one allows to publish notifications from another account's SES email to SNS topic:
{
"Effect": "Allow",
"Principal": {
"Service": "ses.amazonaws.com"
},
"Action": "SNS:Publish",
"Resource": "arn:aws:sns:us-east-2:444455556666:MyTopic",
"Condition": {
"StringEquals": {
"aws:SourceOwner": "111122223333"
}
}
}
The difference is that the first example uses aws:SourceAccount and the second one uses aws:SourceOwner.
The docs has a dedicated paragraph called "aws:SourceAccount versus aws:SourceOwner" but the distinction between these two statements is stil unclear to me.
Could you please clarify the difference between aws:SourceAccount and aws:SourceOwner policy statements?
The difference can be seen only when the owner of a resource is different from the account that the resource belongs to. It's an advanced setup. Here is an excerpt from the official doc that gives an example of this kind of setup.
... it is possible for another account to own a resource in your account. For example, the trusting account might allow the trusted account to create new resources, such as creating new objects in an Amazon S3 bucket.
Source
1. SourceOwner is used for giving access to other AWS Services from a specific account
For example, we want to define a policy that allows only SES from the account 111122223333 to publish messages to the topic 444455556666:
{
"Version": "2008-10-17",
"Id": "__default_policy_ID",
"Statement": [
{
"Sid": "__default_statement_ID",
"Effect": "Allow",
"Principal": {
"Service": "ses.amazonaws.com"
},
"Action": "SNS:Publish",
"Resource": "arn:aws:sns:us-east-2
:444455556666:MyTopic",
"Condition": {
"StringEquals": {
"aws:SourceOwner": "111122223333"
}
}
}
]
}
2. SourceAccount is used for giving IAM roles access from an account to the topic.
For example, we want to define a policy that allows only the account 444455556666 to publish messages to the topic 111122223333:
{
"Statement": [{
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "sns:Publish",
"Resource": "arn:aws:sns:us-east-2
:111122223333:MyTopic",
"Condition": {
"StringEquals": {
"AWS:SourceAccount": "444455556666"
}
}
}]
}
Now for case #1, if you have only 1 account with you, it doesn't make sense because SES will use the same account as the SNS. But if you have more accounts, it brings a benefit in which you only allow SES of a particular account to send messages to your topic.
Hope it helps. If it is not clear, pls put comments, and I will try to explain more.
Putting more information to get things more clear.
Taking an example of S3 send SNS message.
For this case, AWS will use the credentials of an internal S3 account and makes a call on behalf of your account, NOT from resource. Because of that, we need to use the aws:SourceAccount to perform validation in policy.
Taking an example of SES send SNS message.
For this case, AWS will use the credential of an internal S3 account and make a call on behalf of your resource, NOT from account. Because of that, we need to use the aws:SourceOwner in policy.
I would recommend you refer to case by case from documentation to understand which one you need to use. But I do hope you understand the differences between the 2 of them now.
The difference is as others have described. It might be worth noting this from the GitHub issue:
https://github.com/awsdocs/iam-user-guide/issues/111#issuecomment-1252880839
We don't plan to document aws:SourceOwner.
aws:SourceAccount was introduced as the preferred replacement.
So I would suggest using only aws:SourceAccount going forward.
For Amazon Webservices IAM, is there a way where I can create a role with some policies that only allow Read in the Console, yet allows Read/Write using the API/CLI/Terraform.
The purpose is to force usage of infrastructure-as-code to avoid configuration drift.
Any insights or references to Best practices are very welcome.
It's important to be clear that there is no fool-proof way to do this. No system can ever be sure how a request was made on the client side.
That being said, there should be a way to achieve what you are looking for. You will want to use the IAM condition aws:UserAgent (docs here) to prevent users from using the browser. Here is an example:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
},
{
"Effect": "Deny",
"Action": "*",
"Resource": "*"
"Condition": {
"StringLike": {
"aws:UserAgent": "console.amazonaws.com"
}
}
}
]
}
CloudTrail logs the UserAgents for requests, so you could use that to figure out which UserAgents to block. (docs here)
Somehow none of the AWS IoT Rule are working for me.
I published to topic, and sent SNS (as per example).
SELECT * FROM 'acme/temp'
All policy and trust policy are correct , yet it does not fire rule.
Sad part is log level is DEBUG configured yet cloud watch shows only INFO and no info to know why rules not fired.
Trust policy
{
"Version":"2012-10-17",
"Statement":[{
"Effect": "Allow",
"Principal": {
"Service": "iot.amazonaws.com"
},
"Action": "sts:AssumeRole"
}]
Role Policy
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Action": "sns:Publish",
"Resource": "arn:aws:sns:us-east-1:643170122694:snstopic"
}
}
Pl suggest how to troubleshoot.
I am using MQTT client inside AWS console to publish message to topic. If I subscribe then I get messages. I put my rule configuration here forums.aws.amazon.com/thread.jspa?messageID=741034&tstart=0 Can you think of any ways I can troubleshoot .. No matter what rule I write and what action I defined .. it does not fire Iot rule engine. I am using us east 1 region.
I have server S3 buckets belonging to different clients. I am using AWS SDK for PHP in my application to upload photos to the S3 bucket. I am using the AWS SDK for Laravel 4 to be exact but I don't think the issue is with this specific implementation.
The problem is unless I give the AWS user my server is using the FullS3Access it will not upload photos to the bucket. It will say Access Denied! I have tried first with only giving full access to the bucket in question, then I realized I should add the ability to list all buckets because that is probably what the SDK tries to do to confirm the credentials but still no luck.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetBucketLocation",
"s3:ListAllMyBuckets"
],
"Resource": "arn:aws:s3:::*"
},
{
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::*"
]
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::clientbucket"
]
}
]
}
It is a big security concern for me that this application has access to all S3 buckets to work.
Jeremy is right, it's permissions-related and not specific to the SDK, so far as I can see here. You should certainly be able to scope your IAM policy down to just what you need here -- we limit access to buckets by varying degrees often, and it's just an issue of getting the policy right.
You may want to try using the AWS Policy Simulator from within your account. (That link will take you to an overview, the simulator itself is here.) The policy generator is also helpful a lot of the time.
As for the specific policy above, I think you can drop the second statement and merge with the last one (the one that is scoped to your specific bucket) may benefit from some * statements since that may be what's causing the issue:
"Action": [
"s3:Delete*",
"s3:Get*",
"s3:List*",
"s3:Put*"
]
That basically gives super powers to this account, but only for the one bucket.
I would also recommend creating an IAM server role if you're using a dedicated instance for this application/client. That will make things even easier in the future.