Permission Boundary IAM role denying attaching administrator policy - json

Can anyone point me how to accomplish the instruction below. I am trying to find it playing with roles and policy but I can't find any way to accomplish a granular approach to deny attaching administrator policy and maintaining other IAM rights.
Set an IAM permission boundary on the development IAM role that explicitly denies attaching the administrator policy

You need to combine multiple conditions to achieve this:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "IAMPermissions",
"Effect": "Allow",
"Action": [
"iam:*"
],
"Resource": "*"
},
{
"Sid": "DenyAttachAdministratorPolicy",
"Effect": "Deny",
"Action": [
"iam:AttachRolePolicy"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"iam:PermissionsBoundary": "arn:aws:iam::012345678912:policy/MyPermissionBoundary"
},
"ArnEquals": {
"iam:PolicyARN": "arn:aws:iam::aws:policy/AdministratorAccess"
}
}
}
]
}
(You would need to update the PB ARN mentioned in the policy)
Note that this might not handle other edge cases where a malicious user could potentially attach AdministratorAccess to something else and escalate their privileges (e.g. via a Lambda function or container maybe?).

Related

IAM Policy with action: autoscaling:AttachLoadBalancerTargetGroups, Filters access based on the ARN of a target group is not working

We have an autoscaling group with 2 target groups. We want to allow a team to Detach/Attach one of these target groups and prevent them from detaching/attaching the other one. So we build this IAM Policy Statement:
{
"Sid": "AsgPolicy",
"Effect": "Allow",
"Action": [
"autoscaling:AttachLoadBalancerTargetGroups",
"autoscaling:DetachLoadBalancerTargetGroups"
],
"Resource": "arn:aws:autoscaling:*:${account}:autoScalingGroup:*:autoScalingGroupName/app-${env}-frontend",
"Condition": {
"StringLike": {
"autoscaling:TargetGroupARNs": "arn:aws:elasticloadbalancing:*:${account}:targetgroup/app-${env}-target/*"
}
}
}
Even though everything seems correct, whenever I use the role with this policy to detach/attach the target group in the condition I get this error:
Detaching target groups failed
User: arn:aws:sts::11111111111:assumed-role/role-name/username is not authorized to perform: autoscaling:DetachLoadBalancerTargetGroups on resource: arn:aws:autoscaling:eu-west-1:11111111111:autoScalingGroup:ad6d28fa-b472-44e9-9ec4-e39bab5cd364:autoScalingGroupName/app-dev-frontend because no identity-based policy allows the autoscaling:DetachLoadBalancerTargetGroups action
I don't understand where is the issue.
The condition is important because only one target should be updated and not the other one.
Thanks
For permission statement to work properly, ”Resource” resource types specified should be supported by actions listed under “Actions”. Not every resource type can be specified with every action. If you specify a resource that is not valid for the action, any request to use that action fails, and the statement's Effect does not apply.
In your case, actions "autoscaling:AttachLoadBalancerTargetGroups" and "autoscaling:DetachLoadBalancerTargetGroups" does not support resource-level permissions (shown as blank in the actions table under “Resource types” column of Actions Table) and you must specify all resources ("*") in your policy.
You can try with this policy:
{
"Sid": "AsgPolicy",
"Effect": "Allow",
"Action": [
"autoscaling:AttachLoadBalancerTargetGroups",
"autoscaling:DetachLoadBalancerTargetGroups"
],
"Resource": "*",
"Condition": {
"StringLike": {
"autoscaling:TargetGroupARNs": "arn:aws:elasticloadbalancing:*:${account}:targetgroup/app-${env}-target/*"
}
}
}
Here is the solution for this issue, it worked perfectly:
{
"Sid": "AsgDetach",
"Effect": "Allow",
"Action": [
"autoscaling:AttachLoadBalancerTargetGroups",
"autoscaling:DetachLoadBalancerTargetGroups"
],
"Resource": "*",
"Condition": {
"ForAnyValue:StringLike": {
"autoscaling:TargetGroupARNs": "arn:aws:elasticloadbalancing:*:*xxx"
}
}
}

Amazon S3 bucket policy allow access to ONLY specific http

I'm trying to restrict access to objects (media files) in an Amazon S3 bucket to a specific referral domain, privatewebsite.com, with a bucket policy, but keep getting access denied, no matter the domain referred.
I have the following settings for Block Public Access
Block public access to buckets and objects granted through new access control lists (ACLs) - On
Block public access to buckets and objects granted through any access control lists (ACLs) - On
Block public access to buckets and objects granted through new public bucket policies - Off
Block public and cross-account access to buckets and objects through any public bucket policies - Off
I've added the following code, URL with and without, http:// and https://, yet still get access denied. (privatewebsite.com, https://privatewebsite.com, http://privatewebsite.com)
{
"Version": "2012-10-17",
"Id": "Policy8675309",
"Statement": [
{
"Sid": "Stmt8675309",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-media-bucket/*",
"Condition": {
"StringLike": {
"aws:Referer": "https://privatewebsite.com"
}
}
},
{
"Sid": "Explicit deny to ensure requests are allowed only from specific referer.",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": "arn:aws:s3:::my-media-bucket/*",
"Condition": {
"StringNotLike": {
"aws:Referer": [
"https://privatewebsite.com/*",
"http://privatewebsite.com/*"
]
}
}
}
]
}
Can anyone see any obvious errors in my bucket policy?
I expect this policy to ALLOW any request, when coming from a page on privatewebsite.com, while DENY-ing all other requests, but at the moment ALL requests are denied.
From Bucket Policy Examples - Restricting Access to a Specific HTTP Referrer:
{
"Version": "2012-10-17",
"Id": "http referer policy example",
"Statement": [
{
"Sid": "Allow get requests originating from www.example.com and example.com.",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::examplebucket/*",
"Condition": {
"StringLike": {
"aws:Referer": [
"http://www.example.com/*",
"http://example.com/*"
]
}
}
}
]
}
This method only grants Allow access for the given Referer. There is no need to use a Deny policy with it because access is denied by default. Thus, only the Allow permissions are granted.
Try this for you string-like section (allow section):
"StringLike": {
"aws:Referer": [
"https://privatewebsite.com/*",
"http://privatewebsite.com/*"
]
}

AWS IAM Policy To Restrict S3 Access (Prefix) Based On IAM User's Tag

A variety of IAM users are sharing access to an S3 bucket. The S3 bucket has content separated by user so each user has a unique area they have access to.
For instance:
S3 Bucket: example-bucket.
IAM User: UserOne. This user is tagged with sampleTag=u11111.
IAM User: UserTwo. This user is tagged with sampleTag=u22222.
Many more tagged IAM users.
I'd like to write an IAM policy such that:
UserOne has access to read+write content to s3://example-bucket/u11111/* and read content from s3://example-bucket/config/u11111/
UserTwo has access to read+write content to s3://example-bucket/u22222/* and read content from s3://example-bucket/config/u22222/
Etc...
Note that the S3 key includes the value of the sampleTag in the path.
I'd like this single policy to be able to be applied to the entire group of IAM users without need to include an individual policy for each user.
I expected this to be possible thanks to ${aws:PrincipalTag/sampleTag} which I thought would inject the tag value in that location in the resource strings. But after playing with the policy simulator, it doesn't seem to accomplish this.
Current policy looks like:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListAllMyBuckets"
],
"Resource": "arn:aws:s3:::*"
},
{
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetBucketLocation"
],
"Resource": [
"arn:aws:s3:::example-bucket",
"arn:aws:s3:::example-bucket-test"
]
},
{
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::example-bucket",
"arn:aws:s3:::example-bucket-test"
],
"Condition": {
"StringEquals": {
"s3:prefix": [
"",
"${aws:PrincipalTag/sampleTag}/"
],
"s3:delimiter": ["/"]
}
}
},
{
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::example-bucket",
"arn:aws:s3:::example-bucket-test"
],
"Condition": {
"StringLike": {
"s3:prefix": ["${aws:PrincipalTag/sampleTag}/*"]
}
}
},
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:GetObjectAcl",
"s3:GetObjectVersion",
"s3:GetObjectVersionAcl"
],
"Resource": [
"arn:aws:s3:::example-bucket/config/${aws:PrincipalTag/sampleTag}/*",
"arn:aws:s3:::example-bucket-test/config/${aws:PrincipalTag/sampleTag}/*"
]
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:GetObjectAcl",
"s3:GetObjectVersion",
"s3:GetObjectVersionAcl",
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::example-bucket/${aws:PrincipalTag/sampleTag}/*",
"arn:aws:s3:::example-bucket-test/${aws:PrincipalTag/sampleTag}/*"
]
}
]
}
I think the last two policies to not work. I can't find documentation to say if you can embed variables into the Resource strings or not, but s3:prefix doesn't seem to be available for GetObject or PutObject operations -- so I'm not sure how else to restrict the scope of those permissions.
Any ideas as to what is wrong or how to accomplish this would be appreciated!
I think it is possible to use ${aws:PrincipalTag} in the Ressource property of a policy. Just look into the docs of IAM. The example uses the PrincipalTag as last part of the Ressource value.
(Just use Strg + F and type PrincipalTag on the docs website an you find the example)
You are right, the last two policies will not work.
According to documentation aws:PrincipalTag/tag-key works with string operators, hence aws:PrincipalTag/tag-key usage will only works inside Condition policy elements.
Also, s3:prefix condition key only work for ListBucket & ListBucketVersions actions: https://docs.aws.amazon.com/IAM/latest/UserGuide/list_amazons3.html#amazons3-policy-keys
You can have PrincipalTag as part of the resource.
This works.
{
"Sid": "FullPermissionOnlyForPrefix",
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::mybucket/${aws:PrincipalTag/team}*",
"arn:aws:s3:::mybucket/${aws:PrincipalTag/team}/*"
]
}

Create a single IAM user to access only specific S3 bucket

I have many S3 buckets in my AWS account. But now I created an IAM user and a new S3 bucket, I would like to give this user the ability to access the new S3 bucket using a client like CyberDuck.
I tried to create so many policies. But after that this user getting permission to list all my other buckets also. How can I give access to listing and writing access to a single S3 bucket?
First you create a Policy to allow access to a single S3 bucket (IAM -> Policies -> Create Policy). You can use AWS Policy Generator (http://awspolicygen.s3.amazonaws.com/policygen.html), it should look something like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1528735049406",
"Action": [
"s3:DeleteObject",
"s3:GetObject",
"s3:HeadBucket",
"s3:ListBucket",
"s3:ListObjects",
"s3:PutObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::YOURBUCKETNAME"
}
]
}
Save the policy and note the name you gave to it, then go to IAM -> Users and select the desired user. In the permissions tab, click 'Add permissions', then select 'Attach existing policies directly' near the top. Find your policy by its name, tick its checkbox and complete the process.
Per this ( https://aws.amazon.com/blogs/security/writing-iam-policies-grant-access-to-user-specific-folders-in-an-amazon-s3-bucket/ )
they’ll need to be able to at least list all the buckets. But other than that, this also provides an example policy, which I just used last night for my own account, so I can confirm that it works.
Update
Okay, I've tested and confirmed using CyberDuck that the following policy (customized to your environment of course) will prevent users from viewing all root buckets, and only allow them access to the bucket you specify:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowAllInBucket",
"Action": [
"s3:*"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::bucket-for-single-user"
}
]
}
Just make sure that when you specify the path in CyberDuck, that you enter it as: bucket-for-single-user.s3.amazonaws.com.
Also, only START unrestricted like that, just to make sure it's working for you (since access appears to be an issue). After that, apply restrictions, you know...least privilege and all.
According to Cyberduck Help / Howto / Amazon S3, it supports directly entering the Bucket name, as <bucketname>.s3.amazonaws.com. If this is possible with the client you are using, you don't need s3:ListAllMyBuckets permissions.
Actions should be grouped by the Resources that they can parse
(Conditions are also potentially different per Action).
This IAM policy will allow full control of all the content (aka in the bucket)
without controlling of the S3 bucket subresources (aka of the bucket):
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "BucketOperations",
"Effect": "Allow",
"Action": "s3:ListBucket*",
"Resource": "arn:aws:s3:::<bucketname>"
},
{
"Sid": "ObjectOperations",
"Effect": "Allow",
"Action": [
"s3:AbortMultipartUpload",
"s3:ListMultipartUploads",
"s3:DeleteObject*",
"s3:GetObject*",
"s3:PutObject*"
],
"Resource": "arn:aws:s3:::<bucketname>/*"
},
{
"Sid": "DenyAllOthers",
"Effect": "Deny",
"Action": "s3:*",
"NotResource": [
"arn:aws:s3:::<bucketname>",
"arn:aws:s3:::<bucketname>/*"
]
}
]
}
If you aren't specifically trying to lock the IAM user out of every
possible public S3 bucket, you can leave the "DenyAllOthers" Sid off,
without granting additional permissions to the users.
FYI, the AWS ReadOnlyAccess policy automatically gives s3:* to
anything it's attached to. I recommend ViewOnlyAccess (which will
unfortunately grant s3:ListAllMyBuckets without the DenyAllOthers).
Create my own policy and working for me. The IAM user can just list all bucket. But cant do anything on another bucket. The user can only get access to the specific bucket with reading, write, delete files privileges.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "<EXAMPLE_SID>",
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::<MYBUCKET>"
},
{
"Sid": "<EXAMPLE_SID>",
"Effect": "Allow",
"Action": "s3:ListAllMyBuckets",
"Resource": "*"
}, {
"Sid": "<EXAMPLE_SID>",
"Effect": "Deny",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::<MYotherBUCKET>"
}, {
"Sid": "<EXAMPLE_SID>",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::<MYBUCKET>/*"
}
]
}
Then add this policy also to this user. This policy will restrict all type of operation to listed other s3 bucket.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "<EXAMPLE_SID>",
"Effect": "Deny",
"Action": [
"s3:PutAnalyticsConfiguration",
"s3:GetObjectVersionTagging",
"s3:CreateBucket",
"s3:ReplicateObject",
"s3:GetObjectAcl",
"s3:DeleteBucketWebsite",
"s3:PutLifecycleConfiguration",
"s3:GetObjectVersionAcl",
"s3:PutBucketAcl",
"s3:PutObjectTagging",
"s3:DeleteObject",
"s3:GetIpConfiguration",
"s3:DeleteObjectTagging",
"s3:GetBucketWebsite",
"s3:PutReplicationConfiguration",
"s3:DeleteObjectVersionTagging",
"s3:GetBucketNotification",
"s3:PutBucketCORS",
"s3:DeleteBucketPolicy",
"s3:GetReplicationConfiguration",
"s3:ListMultipartUploadParts",
"s3:PutObject",
"s3:GetObject",
"s3:PutBucketNotification",
"s3:PutBucketLogging",
"s3:PutObjectVersionAcl",
"s3:GetAnalyticsConfiguration",
"s3:GetObjectVersionForReplication",
"s3:GetLifecycleConfiguration",
"s3:ListBucketByTags",
"s3:GetInventoryConfiguration",
"s3:GetBucketTagging",
"s3:PutAccelerateConfiguration",
"s3:DeleteObjectVersion",
"s3:GetBucketLogging",
"s3:ListBucketVersions",
"s3:ReplicateTags",
"s3:RestoreObject",
"s3:GetAccelerateConfiguration",
"s3:GetBucketPolicy",
"s3:PutEncryptionConfiguration",
"s3:GetEncryptionConfiguration",
"s3:GetObjectVersionTorrent",
"s3:AbortMultipartUpload",
"s3:PutBucketTagging",
"s3:GetBucketRequestPayment",
"s3:GetObjectTagging",
"s3:GetMetricsConfiguration",
"s3:DeleteBucket",
"s3:PutBucketVersioning",
"s3:PutObjectAcl",
"s3:ListBucketMultipartUploads",
"s3:PutMetricsConfiguration",
"s3:PutObjectVersionTagging",
"s3:GetBucketVersioning",
"s3:GetBucketAcl",
"s3:PutInventoryConfiguration",
"s3:PutIpConfiguration",
"s3:GetObjectTorrent",
"s3:ObjectOwnerOverrideToBucketOwner",
"s3:PutBucketWebsite",
"s3:PutBucketRequestPayment",
"s3:GetBucketCORS",
"s3:PutBucketPolicy",
"s3:GetBucketLocation",
"s3:ReplicateDelete",
"s3:GetObjectVersion"
],
"Resource": [
"arn:aws:s3:::<MYotherBUCKET>/*",
"arn:aws:s3:::<MYotherBUCKET>"
]
}
]
}
I was recently able to get this to work using Amazon's documentation. The key for me was to point the IAM User to the specific bucket NOT the S3 console. Per the documentation, "Warning: After you change these permissions, the user gets an Access Denied error when they access the main Amazon S3 console. The main console link is similar to the following:
https://s3.console.aws.amazon.com/s3/home
Instead, the user must access the bucket using a direct console link to the bucket, similar to the following:
https://s3.console.aws.amazon.com/s3/buckets/awsexamplebucket/"
My policy is below:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1589486662000",
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::AWSEXAMPLEBUCKET",
"arn:aws:s3:::AWSEXAMPLEBUCKET/*"
]
}
]
}

How do I do an OR condition in an S3 bucket policy?

I'm working on an S3 bucket policy. The idea is to explicitly deny access to all IAM users within the account, except for those explicitly granted.
I found a blog post that explains how to restrict access to a specific user. It works well. However, I want to extend the syntax to include a second IAM user that will be allowed access. This is, in effect, an OR condition.
But, I've very new to JSON, and I'm not sure how to go about that.
Here is the policy that works for restricting access to a single user:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::my-bucket",
"arn:aws:s3:::my-bucket/*"
],
"Condition": {
"StringNotLike": {
"aws:userId": [
"AIDA<obfuscated id>:*",
"AIDA<obfuscated id>",
"111111111111"
]
}
}
}
]
}
Can anyone help me edit the above JSON to allow for an OR condition where I could specify an additional userid that would be allowed access?
AdvThanksance!
Ok, I figured this out.
First, I tried adding a second StringgNotLike clause to the Condition, but that didn't work.
After doing as bit more reading, I realized the Condition clause accepts multiple key/value pairs. In fact, the original policy I showed in my question already did that. I just needed to add more values to the array that was already there.
The policy that works, looks like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::my-private-bucket",
"arn:aws:s3:::my-private-bucket/*"
],
"Condition": {
"StringNotLike": {
"aws:userId": [
"AIDA<obfuscated-id-1>:*",
"AIDA<obfuscated-id-1>",
"AIDA<obfuscated-id-2>:*",
"AIDA<obfuscated-id-2>",
"111111111111"
]
}
}
}
]
}
When I realized that the key had already specified an array of values, I just added the second user id to the array, and it worked great.