IAM Role reference multiple EKS OIDC - amazon-web-services

I have 3 different EKS cluster for each stage (dev, staging, prd)
and I need to have multiple IAM Role for each application deployed in our clusters.
The idea is to be able to reference multiple EKS OIDC in the trust relationship of that IAM Role so I would end up with 1 IAM Role per application across clusters instead of 3x.
Configuring one IAM Role + trust relationship is easy like below:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::xxxxx:oidc-provider/oidc.eks.eu-west-1.amazonaws.com/id/xxxx-oidc-cluster-1"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringLike": {
"oidc.eks.eu-west-1.amazonaws.com/id/xxxx-oidc-cluster-1:sub": "system:serviceaccount:*:*"
}
}
}
]
}
What I'm trying to do is reference my other clusters (xxxx-oidc-cluster-2 and xxxx-oidc-cluster-3) in that same trust relationship. I dug into the official doc to how to construct such IAM JSON Policy, but couldn't find anything that could help. I thought maybe I was missing something.

It's probably best practice to scope your IAM Roles to one per application per cluster, but if you really want to do this, you'll need to use multiple separate statements in your Assume Role Policy (Trust Relationship).
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::xxxxx:oidc-provider/oidc.eks.eu-west-1.amazonaws.com/id/xxxx-oidc-cluster-1"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.eu-west-1.amazonaws.com/id/xxxx-oidc-cluster-1:sub": "system:serviceaccount:*:*"
}
}
},
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::xxxxx:oidc-provider/oidc.eks.eu-west-1.amazonaws.com/id/xxxx-oidc-cluster-2"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.eu-west-1.amazonaws.com/id/xxxx-oidc-cluster-2:sub": "system:serviceaccount:*:*""
}
}
}
]
}

Related

AWS trusted entity with multiple principal types and condition

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"
}
}
}
]
}

IAM & Cross-account write to S3 bucket: Allow service principal based on organisation ID

I have many AWS accounts. I enabled VPC flow logs to all of them, and I want to ship those logs to a central S3 bucket in my Log Archive Accounts.
An IAM policy that works is the following:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AWSLogDeliveryWrite",
"Effect": "Allow",
"Principal": {"Service": "delivery.logs.amazonaws.com"},
"Action": "s3:PutObject",],
"Resource": "arn:aws:s3:::central_log_archive_bucket",
"Condition": {
"StringEquals": {
"aws:SourceAccount": <account_id-1>,
"aws:SourceAccount": <account_id-2>,
"aws:SourceAccount": <account_id-3>,
...
"aws:SourceAccount": <account_id-N>
},
"ArnLike": {
"aws:SourceArn": "arn:aws:logs:*:<account_id-1>:*",
"aws:SourceArn": "arn:aws:logs:*:<account_id-2>:*",
"aws:SourceArn": "arn:aws:logs:*:<account_id-3>:*",
...
"aws:SourceArn": "arn:aws:logs:*:<account_id-N>:*",
}
}
}
]
}
I wanna simplify this. Instead of adding all account IDs like shown above, I wanna allow ANY VPC service that belongs in an AWS account under my organization to publish logs to the S3. In short, I want to do something like:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AWSLogDeliveryWrite",
"Effect": "Allow",
"Principal": {"Service": "delivery.logs.amazonaws.com"},
"Action": "s3:PutObject",],
"Resource": "arn:aws:s3:::central_log_archive_bucket",
"Condition": {
"StringEquals": {
"aws:PrincipalOrgID": "ID"
}
}
}
]
}
But I am seeing the following error message:
Unsupported Condition Key for Service Principal
Any idea how to make this work?
As mentioned here https://docs.aws.amazon.com/IAM/latest/UserGuide/access-analyzer-reference-policy-checks.html,
You can't use some condition keys with certain service principals. For example, you can't use the aws:PrincipalOrgID condition key with the service principal cloudfront.amazonaws.com. or other service like logs. You should remove condition keys that do not apply to the service principal in the Principal element.
You can automate it with a lambda in each account creation for example, to change the bucket policy...

restrict aws iam user to a specific region (eu-west-1)

I'm trying to create a policy in which the user exam can access only to the region eu-west-1.
I tried to find a solution but didn't found the right one.
the policy looks something like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "*",
"Resource": "user_arn",
"Condition": {
"StringEquals": {
"aws:RequestedRegion": "eu-west-1"
}
}
}
]
}
but it does not seem to work no matter what I do.
what is the best way to do so that the user can do whatever he wants but only in this region?
found a solution
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ec2:*",
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:RequestedRegion": "eu-west-1"
}
}
}
]
}
This should work as well, however you are granting full access to EC2 limited to one region. In the example below you "deny" any ec2 action outside the region or regions defined below, however you are not granting any privileges (they should be assigned in a separate policy or use an Allow statement. Normally this is used as an SCP in AWS organizations,a and you jusy deny action "*", to force all users to create resources only in the designated regions, and deny any API action in regions not authorized.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Action": "ec2:*",
"Resource": "*",
"Condition": {
"StringNotEquals": {
"aws:RequestedRegion": "eu-west-1"
}
}
}
]

AWS SCP for EC2 type

I want to allow users only to create t2.micro/small/medium for development and allow them to use only spot instances. Have created IAM policy to restrict type/size of instances. In addition I want to put restriction on "on-demand" instances (team MUST opt for spot instances only). What is the cleaner way of achieving it?
allow full access with the account
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "limitedSize",
"Effect": "Deny",
"Action": [
"ec2:RunInstances",
"cloudwatch:DescribeAlarms"
],
"Resource": [
"arn:aws:ec2:*:*:instance/*"
],
"Condition": {
"ForAnyValue:StringNotLike": {
"ec2:InstanceType": [
"t3.*",
"t2.*"
]
}
}
}
]
}
Try AWS Service Catalog.. that is the exact service which can help u here.
Use the ec2:InstanceMarketType condition key in your IAM policy.
Example (untested):
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Action": "*",
"Resource": "*",
"Condition": {
"StringEquals": {
"ec2:InstanceMarketType": "spot"
}
}
}
}
References:
Condition Keys for EC2
EC2 Condition Key Example
Another SO Question

AWS Service:ecs-tasks.amazonaws.com conditions keys not working

I am trying to create assume role policy for an IAM role which will be assumed by ECS TASK. I want to put a condition that only ECS Container with specific Arn should be able to assume role.
Here is my policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ecs-tasks.amazonaws.com"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringLike": {
"ecs:cluster": "ECS cluster Arn"
}
}
}
]
}
The above policy is not working and even not letting the ECS Cluster mentioned above to assume the role. So, is there any other way we can do this? Any help would be appreciated.