NotResource results in a shorter policy by listing only a few resources that should not match, rather than including a long list of resources that will match.
what will be the result of wildcard in NotResource?
{
"Effect": "Allow",
"NotAction": [
"iam:*"
],
"NotResource": [
"*"
]
}
A policy statement element with NotResource applies to any resource that does not match the listed resource(s). * matches any resource, so NotResource * ends up meaning "not any resource". The policy will have no effect since it will match no resources.
I'm not sure AWS will let you create such a policy, but if it's allowed that's the effect it will have.
Related
{
"Sid": "Allow bucket write",
"Effect": "Allow",
"Principal": {
"Service": [
"cloudtrail.amazonaws.com"
]
},
"Action": "s3:PutObject",
"Resource": "${aws_s3_bucket.log-dev-test-bucket-test.arn}/AWSLogs/${var.organization_id}/${aws:PrincipalAccount}/*",
"Condition": {"StringEquals": {"s3:x-amz-acl": "bucket-owner-full-control"}}
},
I am getting this message on my Resource section with regard to ${aws:PrincipalAccount}:
"Extra characters after interpolation expression: Template interpolation doesn't expect a colon at this location. Did you intend this to be a literal sequence to be processed as part of another language? If so, you can escape it by starting with "$${" instead of just "${".HCL"
The error message is suggesting to use $${aws:PrincipalAccount} to escape it.I don't know what that will do to it because i need to have this IAM policy variable in the policy statement resource section to achieve my goal.can any explain what escape will do if i use $$ instead of $ before {aws:PrincipalAccount}.Thank you
There is no such IAM variable as aws:PrincipalAccount. The avaiable IAM variables are listed in Request information that you can use for policy variables .
I am trying to understand the need for the condition "home/${aws:userid}/*" . This condition actually feels like it is satisified in the "arn:aws:s3:::bucket-name/home/${aws:userid}/*" .
When we have allowed for all s3 operations in the third statement for that user. then why do we need to allow s3:listbuckets specifically for that user?
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListAllMyBuckets",
"s3:GetBucketLocation"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::bucket-name",
"Condition": {
"StringLike": {
"s3:prefix": [
"",
"home/",
"home/${aws:userid}/*"
]
}
}
},
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::bucket-name/home/${aws:userid}",
"arn:aws:s3:::bucket-name/home/${aws:userid}/*"
]
}
]
}
ref https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_examples_s3_federated-home-directory-console.html
s3:ListBucket is a bucket-level permission, while arn:aws:s3:::bucket-name/home/${aws:userid}/* is a wildcard object ARN, not a bucket ARN.
An attempt to grant s3:ListBucket will not match any Resource that isn't a bucket ARN, so the s3:* grant -- which only includes object ARNs -- does not actually allow object listings.
So this example policy does not contain any redundancy.
If this implementation still seems a bit counter-intuitive or perhaps convoluted, it does become somewhat clearer if you consider how the S3 API works on the wire. The ListObjects API action (as well as the newer ListObjectsV2) is submitted against the bucket -- there's no path in the request... or, more precisely, the path in the HTTP request is always¹ /... and the query string contains prefix= and the object key prefix where the requested listing is to be anchored.
While there's no compulsory correlation between the way the underlying API works and the way IAM policies work, it does make sense that the s3:prefix condition key is what's used to control use of the prefix parameter to ListObjects, instead of an object-level ARN, and that the bucket -- not an object key or wildcard pattern -- is the resource being accessed.
¹ always / except when it's /${bucket} as required by the old deprecated path-style URLs that are finally being phased out after a false start or two, at least for new buckets. The resource as expressed in the path component of the request URI is always the bucket itself, not the bucket plus a key prefix.
The resources are different. In the third statement, user can only access bucket-name/home/${aws:userid}. This means that when the user goes into the S3 console, and clicks bucket bucket-name it will get access denied. So user won't be able to list the bucket content, and will not see that there is home folder there. They will also not see that in bucket-name/home there is a folder with their username.
Thus, to overcome this issue, there is the second statement, which allows to list all content of ``bucket-nameand thenbucket-name/home`. This way users can navigate easily in S3 console to get to their actual home folder.
Without the second statement, users would have to type url of their home folders in browser to go to directly to it, which is not very user friendly.
From the AWS IAM ARN documentation at https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html, I can see wildcard use as shown below which is quite confusing.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ManageRichardAccessKeys",
"Effect": "Allow",
"Action": [
"iam:*AccessKey*",
"iam:GetUser"
],
"Resource": "arn:aws:iam::*:user/division_abc/subdivision_xyz/Richard"
},
{
"Sid": "ListForConsole",
"Effect": "Allow",
"Action": "iam:ListUsers",
"Resource": "*"
}
]
}
In the first statement "Resource": "arn:aws:iam::*:user/division_abc/subdivision_xyz/Richard", why are we not specifying the account number and just substituting with wildcard "*" - I understand that in the context of S3 this is left blank, but over here it is wildcard - what does the wild card here really mean? The wildcard appears to give it a meaning like "any account" but isnt this incorrect?
Also, for the second statement "Resource": "*", does this mean ListUsers for any resource? which does not make any sense - should this not be something like arn:aws:iam::123456789012: indicating list users for this AWS account (123456789012)?
Assuming that the queries actually work (I didn't test them):
Yes, leaving out the account number is a 'little' dangerous because it would also be permitting the user that has this policy to manage access keys for a same-named user in a different account, but the receiving account would not honor the request so it is safe.
The ListUsers command does not actually take many parameters (just a prefix), so it's really an "all or nothing" API call. Please note that it only applies to requesting a list of users, nothing else. (That is, there is no concept of calling "ListUsers for a resource".)
See: Actions, Resources, and Condition Keys for Identity And Access Management - AWS Identity and Access Management
I am trying to find out one problem with IAM policy of one of my user.
I have policy which says deny access if the service is not in our list. I am trying to grant access to my user for all action of apigateway. I have provided below policy. But it is denying access for all action other than GET, OPTIONS, HEAD. I have the wild character * in the beginning, will be individual actions override the wild character settings. I am trying to understand the evaluation order for IAM. Does the individual action override the *?
{
"Statement": [
{
"Resource": "*",
"Effect": "Deny",
"NotAction": [
"apigateway:*"
"apigateway:GET",
"apigateway:OPTIONS",
"apigateway:HEAD"
]
}
]
}
In AWS IAM, all requests are denied by default. So, you only need to grant permissions to the desired actions while all other actions will be denied by default.
When a request is made, the AWS service decides whether a given
request should be allowed or denied. The evaluation logic follows
these rules:
By default, all requests are denied. (In general, requests made using the account credentials for resources in the account are always allowed.)
An explicit allow overrides this default.
An explicit deny overrides any allows.
The order in which the policies are evaluated has no effect on the outcome of the evaluation. All policies are evaluated, and the result is always that the request is either allowed or denied.
See Determining Whether a Request is Allowed or Denied.
So, usually it should be enough to write your Allow policy as:
{
"Statement": [
{
"Resource": "*",
"Effect": "Allow",
"Action": [
"apigateway:GET",
"apigateway:OPTIONS",
"apigateway:HEAD"
]
}
]
}
However, if you suspect that other policies might be granting the user undesired actions, you could write your Deny policy as:
{
"Statement": [
{
"Resource": "*",
"Effect": "Deny",
"NotAction": [
"apigateway:GET",
"apigateway:OPTIONS",
"apigateway:HEAD"
]
}
]
}
This line was helpful from the AWS docs:
An explicit deny in any policy overrides any allows
When trying to configure which instances can be listed using policies, I remark the following issue:
When the condition is not implemented, all instances are visible.
When any condition is implemented, nothing is visible.
The example policy with condition is included:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1461235889000",
"Effect": "Allow",
"Action": [
"ec2:DescribeInstances"
],
"Resource": [
"*"
],
"Condition": {
"StringEquals": {
"ec2:InstanceType": "r3.xlarge"
}
}
}
]
}
What is wrong here?
The ec2:DescribeInstances action does not support resource-level permissions or applying conditions.
From the linked documentation above:
...to use these actions in an IAM policy, you must grant users permission to use all resources for the action by using a * wildcard for the Resource element in your statement. You cannot use Amazon EC2 condition keys for these actions.
So your usage of the * wildcard without a condition is valid, but applying any condition (as of this writing) will unfortunately not work as expected.
Further Reading:
Supported Resource-Level Permissions for Amazon EC2 API Actions