AWS trusted entity with multiple principal types and condition - amazon-iam

I have a Terraform code that generates a trusted entity like this that is attached to a role for cross-account access:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::444555666:root",
"Service": "backup.amazonaws.com"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "444-555-666-777-888"
}
}
}
]
}
If I intend to allow the AWS account with an externalId to assume the role and I also want the AWS backup service to adopt the role, is the generated resource policy correct?
I don't know if the policies engine will pick the condition and try to apply it to the account and also to the service, which is not desired.
Anybody knows if this is correct? are these kind of more complex rules documented by AWS?, I only have found info about simpler rules
I guess a way to ensure the correctness would be to separate both needs into different statements, but this is what the Terraform generates out of the provided HCL.
thanks

The statement will not be in effect until the condition is meet according to the AWS condition documentation.
You will need to have another trust statement such as the example below.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "backup.amazonaws.com"
},
"Action": "sts:AssumeRole"
},
{
"Effect": "Allow",
"Principal": {
"Service": "backup.amazonaws.com"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "444-555-666-777-888"
}
}
}
]
}

Related

How to update the IAM policy that IAM role to have the same permission set the IPs have?

How to update the IAM policy below so that the IAM role, arn:aws:iam::7574333677569:role/dev-abc-webserver, also have permissions?
{
"Version": "2012-10-17",
"Id": "Policy1517260196123",
"Statement": [
{
"Sid": "Stmt1432661968133",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::pdf.abc.com/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"24.237.272.151/32",
"42.69.252.185/32",
]
}
}
}
]
}
The issue I faced is that The IAM role doesn't have permission with it currently,
I want the IAM role to have the same permission set as the IPs have.
We don't need to change the policy
, We need to expand what it already grants access to the provided IAM role.
So ""Condition": {" needs to be expanded so we are checking for our IPs or the IAM role.
I am not able to figure out how to provide access via the IAM role yet.
I did check some aws documentation but not able to figure it out .
https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition.html
Could anyone Help me with this issue, any help should be appreciated?
Since multiple conditions within a statement are always ANDed and never ORed you need a second statement to grant the permission to other entities. That statement will have a different Principal and the Condition can be removed.
{
"Version": "2012-10-17",
"Id": "Policy1517260196123",
"Statement": [
{
"Sid": "Stmt1432661968133",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::pdf.abc.com/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"24.237.272.151/32",
"42.69.252.185/32",
]
}
}
}, {
"Sid": "StmtForRole",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::7574333677569:role/dev-abc-webserver"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::pdf.abc.com/*"
}
]
}

AWS: Permissions for exporting logs from Cloudwatch to Amazon S3

I am trying to export logs from one of my CloudWatch log groups into Amazon S3, using AWS console.
I followed the guide from AWS documentation but with little success. My organization does not allow me to manage IAM roles/policies, however I was able to find out that my role is allowed all log-related operations (logs:* on all resources within the account).
Currently, I am stuck on the following error message:
Could not create export task. PutObject call on the given bucket failed. Please check if CloudWatch Logs has been granted permission to perform this operation.
My bucket policy is set in the following way:
{
[
...
{
"Sid": "Cloudwatch Log Export 1",
"Effect": "Allow",
"Principal": {
"Service": "logs.eu-central-1.amazonaws.com"
},
"Action": "s3:GetBucketAcl",
"Resource": "arn:aws:s3:::my-bucket"
},
{
"Sid": "Cloudwatch Log Export 2",
"Effect": "Allow",
"Principal": {
"Service": "logs.eu-central-1.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::my-bucket/*"
}
]
}
Prior to editing bucket policy, my error message had been
Could not create export task. GetBucketAcl call on the given bucket failed. Please check if CloudWatch Logs has been granted permission to perform this operation.
but editing the bucket policy fixed that. I would expect allowing PutObject to do the same, but this has not been the case.
Thank you for help.
Ensure when exporting the data you configure the following aptly
S3 bucket prefix - optional This would be the object name you want to use to store the logs.
While creating the policy for PutBucket, you must ensure the object/prefix is captured adequately. See the diff for the PutBucket statement Resource:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "s3:GetBucketAcl",
"Effect": "Allow",
"Resource": "arn:aws:s3:::my-exported-logs",
"Principal": { "Service": "logs.us-east-2.amazonaws.com" }
},
{
"Action": "s3:PutObject" ,
"Effect": "Allow",
- "Resource": "arn:aws:s3:::my-exported-logs/*",
+ "Resource": "arn:aws:s3:::my-exported-logs/**_where_i_want_to_store_my_logs_***",
"Condition": { "StringEquals": { "s3:x-amz-acl": "bucket-owner-full-control" } },
"Principal": { "Service": "logs.us-east-2.amazonaws.com" }
}
]
}
Please check this guide Export log data to Amazon S3 using the AWS CLI
Policy's looks like the document that you share but slight different.
Assuming that you are doing this in same account and same region, please check that you are placing the right region ( in this example is us-east-2)
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "s3:GetBucketAcl",
"Effect": "Allow",
"Resource": "arn:aws:s3:::my-exported-logs",
"Principal": { "Service": "logs.us-east-2.amazonaws.com" }
},
{
"Action": "s3:PutObject" ,
"Effect": "Allow",
"Resource": "arn:aws:s3:::my-exported-logs/*",
"Condition": { "StringEquals": { "s3:x-amz-acl": "bucket-owner-full-control" } },
"Principal": { "Service": "logs.us-east-2.amazonaws.com" }
}
]
}
I think that bucket owner full control is not the problem here, the only chance is the region.
Anyway, take a look to the other two examples in case that you were in different accounts/ using role instead user.
This solved my issue, that was the same that you mention.
One thing to check is your encryption settings. According to https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/S3ExportTasksConsole.html
Exporting log data to Amazon S3 buckets that are encrypted by AWS KMS is not supported.
Amazon S3-managed keys (SSE-S3) bucket encryption might solve your problem. If you use SSE-KMS, Cloudwatch can't access your encryption key in order to properly encrypt the objects as they are put into the bucket.
I had the same situation and what worked for me is to add the bucket name itself as a resource in the Allow PutObject Sid, like:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowLogsExportGetBucketAcl",
"Effect": "Allow",
"Principal": {
"Service": "logs.eu-west-1.amazonaws.com"
},
"Action": "s3:GetBucketAcl",
"Resource": "arn:aws:s3:::my-bucket"
},
{
"Sid": "AllowLogsExportPutObject",
"Effect": "Allow",
"Principal": {
"Service": "logs.eu-west-1.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": [
"my-bucket",
"my-bucket/*"
]
}
]
}
I also believe that all the other answers are relevant, especially using the time in milliseconds.

How to fix s3-bucket-policy-grantee-check non-compliance?

I deployed a NIST CSF conformance pack on my AWS account, via AWS Config, to improve my security posture. One of my resources was non-compliant due to the s3-bucket-policy-grantee-check not passing. Firstly, I do not understand what it means in plain English despite reading it several times (I was hoping someone could simply the language for me even more).
I have the following bucket policy but cannot seem to figure out why I can't get rid of this violation:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AWSCloudTrailAclCheck",
"Effect": "Allow",
"Principal": {
"Service": "cloudtrail.amazonaws.com"
},
"Action": "s3:GetBucketAcl",
"Resource": "arn:aws:s3:::cis-alarms-<account-number>"
},
{
"Sid": "AWSCloudTrailWrite",
"Effect": "Allow",
"Principal": {
"Service": "cloudtrail.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::cis-alarms-<account-number>/AWSLogs/<account-number>/*",
"Condition": {
"StringEquals": {
"s3:x-amz-acl": "bucket-owner-full-control"
}
}
},
{
"Sid": "AllowSSLRequestsOnly",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::cis-alarms-<account-number>",
"arn:aws:s3:::cis-alarms-<account-number>/*"
],
"Condition": {
"Bool": {
"aws:SecureTransport": "false"
}
}
}
]
}
What am I doing wrong?
PS. This is for a bucket that was provisioned when I created a trail on CloudTrail, and it created this bucket as a trail log bucket.
I figured out what was going on. Because I deployed this rule through a conformance pack, I wasn't able to edit the role because it is attached to a service-linked role which prevents any edits/deletes to the rules within the conformance pack. When I deployed the rule on its own and put in the necessary inputs (servicePrincipals & awsPrincipals) it worked like a charm and I was able to get rid of the violation.

S3 bucket policy to deny all except a particular AWS service role and IAM role

Can you write an s3 bucket policy that will deny access to all principals except a particular IAM role and AWS service role (e.g. billingreports.amazonaws.com).
I have tried using 'Deny' with 'NotPrincipal', but none of the below examples work as I don't think the ability to have multiple types of principals is supported by AWS?
This allows you to save the policy but locks out the bucket (warning: only root user can then update policy to unlock)
"Effect": "Deny",
"NotPrincipal": {
"AWS": [
"arn:aws:iam::<account_id>:root",
"arn:aws:iam::<account_id>:role/specialBillingRole"
],
"Service": "billingreports.amazonaws.com"
}
Therefore I am trying to use conditions but can't find the right combinations that will work. Here is an example policy.
{
"Version": "2008-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "billingreports.amazonaws.com"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::my-bucket/*"
},
{
"Sid": "",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::my-bucket/*",
"arn:aws:s3:::my-bucket"
],
"Condition": {
"StringNotLike": {
"aws:PrincipalArn": [
"arn:aws:iam::<account_id>:role/specialBillingRole",
"billingreports.amazonaws.com",
"<account_id>"
]
}
}
}
]
}
UPDATED the question as per some comment suggestions.
2nd UPDATE Also tried the below, which still gives access to all roles/users in the account (can't use wildcards in the Principal).
{
"Effect": "Deny",
"Principal": {
"AWS": "arn:aws:iam::<account_id>:root"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::my-bucket/*",
"arn:aws:s3:::my-bucket"
],
"Condition": {
"ArnNotEquals": {
"aws:PrincipalArn": [
"arn:aws:iam::<account_id>:role/specialBillingRole",
"<account_id>"
]
}
}
}
You can certainly create a bucket policy that grants access only to a service role and an IAM role, but to be clear, a service role will still begin with "arn:aws:iam:::role...".
Are you instead trying to create a bucket policy that grants access both to a particular service and a service role? I'm asking because if you have a role created with billingreports.amazonaws.com as its trusted entity, and if that role is what's intended to access the bucket, then you do not need to list the service separately in your bucket policy (if the scenario is as I imagine).
Please do note, also, that you can indeed use wildcards with the principal, combined with a condition - I do so all the time (see my example policy below). When I want to restrict bucket access to a specific role, I simply include an Allow statement with a Principal of just the role I want to allow, and then a Deny statement with a Principal of "AWS": "*", followed by a condition, like so:
{
"Version": "2008-10-17",
"Id": "PolicyScopedToSecurity",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::[accountID]:role/[roleName]",
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::[bucketName]",
"arn:aws:s3:::[bucketName]/*"
]
},
{
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::[bucketName]",
"arn:aws:s3:::[bucketName]/*"
],
"Condition": {
"StringNotLike": {
"aws:PrincipalArn": [
"arn:aws:iam::[accountID]:role/[roleName]",
"[accountID]"
]
}
}
}
]
}
If you truly need the service itself to access the bucket, the solution will be slightly different. My response assumes the service role needs access.

AWS IAM Access Management

I know that you can set up an IAM policy to restrict access to services. However, is it possible to set up a policy to allow access to a part of a service.
E.g. I am two EC2 instances. I need to create two users such that they have an access to the AWS console, but only to one EC2 instance each.
Yes you can do this with Resource-Level Permissions for EC2
The structure of the resource is stated in the documentation as follows:
arn:aws:[service]:[region]:[account]:resourceType/resourcePath
Here is how you would structure the IAM policies for each user:
User 1
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": "ec2:*",
"Resource": "arn:aws:ec2:us-east-1:123456789012:instance/InstanceIdOne"
}
]
}
User 2
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": "ec2:*",
"Resource": "arn:aws:ec2:us-east-1:123456789012:instance/InstanceIdTwo"
}
]
}
Policy without access to EC2:DescribeInstance will not work. You need to allow DescribeInstances access on all resources and manage additional access like modify, delete to specific instances depending on what the need is.
In short, allow all basic operations like Describe Tags, Instances, NetworkACLs, Images etc to all users and allow specific destructive actions like Modify and Delete to select user.
List of EC2 actions for your reference here
http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_Operations.html
So you have 2 options-
Create one policy like below and attach the same policy to both users
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": "ec2:*Describe*",
"Resource":"*",
},
{
"Effect": "Allow",
"Action": [
"ec2:*Modify*",
"ec2:*Delete*"
],
"Principal": { "AWS": "arn:aws:iam::AWS-account-ID:user/**user-name-1**" },
"Resource": "arn:aws:ec2:us-east-1:AWS-account-ID:instance/**InstanceIdOne**"
},
{
"Effect": "Allow",
"Action": [
"ec2:*Modify*",
"ec2:*Delete*"
],
"Principal": { "AWS": "arn:aws:iam::AWS-account-ID:user/**user-name-2**" },
"Resource": "arn:aws:ec2:us-east-1:AWS-account-ID:instance/**InstanceIdTwo**"
}
]}
Create 2 different policies. Example for one below
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": "ec2:*Describe*",
"Resource":"*",
},
{
"Effect": "Allow",
"Action": [
"ec2:*Modify*",
"ec2:*Delete*"
],
"Principal": { "AWS": "arn:aws:iam::AWS-account-ID:user/**user-name-1**" },
"Resource": "arn:aws:ec2:us-east-1:AWS-account-ID:instance/**InstanceIdOne**"
}
]}