How do I have an ECS task assume a role from another AWS Account? - amazon-web-services

I have an an audit container that runs a scan against various AWS APIs. I want to have all of these run as ECS tasks in the prod account, but scan resources in other accounts. Is it possible to set a role from another account as the task role? I've attempted setting taskRoleArn in my task definition to the ARN of the desired role from another account, but I get the error message "Role is not Valid"
I have a simple trust relationship on the role from on the other account (111111111111 is the prod account):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ecs-tasks.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
I have a Cloudwatch Events service role in the prod account that allows iam:passRole to this role on the other account. Is there any modification needed to the ECS task execution role? I was under the impression this was only going to forward logs to Cloudwatch Logs and pull the OCI image from ECR, and shouldn't need any other permissions.
Is this possible or do I just have to assign a task role with sts:assumeRole permissions into the other account and have a shim in the Container image that assumes the role before running the audit?

Is there any modification needed to the ECS task execution role?
Add a policy to your ECS task execution role to assume roles.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "<cross-account role arn here>"
}
]
}
And assume it programmatically: https://stackoverflow.com/a/64345823/12170218

Related

AWS CodeDeploy does not have the permissions required to assume the role

I am trying to set up CI/CD with AWS + EC2 and am stuck when creating Deployment Group. The role of CodeDeploy has policies AWSCodeDeployRole and AWSCodeDeployRoleForECS but it throws an error. I tried giving it Admin rights but it is still not enough. Am I missing something? Thanks for any help!
You have a role that has the permissions required for the codedeploy to perform the deployment. What you are missing here is, You should have a trust policy defined in the role that allows codedeploy to assume the role.
Goto IAM console and select the role from the roles section
Click Trust relationships
Click Edit trust Relationships
Add the following trust policy to allow code deploy service to assume this role.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": [
"codedeploy.amazonaws.com"
]
},
"Action": "sts:AssumeRole"
}
]
}
Reference: Create a service role for CodeDeploy

Are AWS service principals implicitly account scoped in policy documents?

Consider the following trust relationship configured for an IAM role in accountA:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "cloudformation.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
Does this implicitly scope the access down to cloudformation running in accountA, or can cloudformation stack in any other account (B,C,D,etc) assume this role?
I've used sourceArn conditions previously to avoid deputy attacks, like this:
"Condition": {
"ArnLike": {
"aws:SourceArn": [
"xxxx"
]
}
}
Is this necessary, or is the initial policy sufficient to scope the trust relationship down to accountA?
This policy is allowing the CloudFormation service to assume a role that is in your account.
By default this is also scoped to your account, i.e. only CloudFormation in your account can assume the role and not CloudFormation from another account. You would have to explicitly add a Principal with another account ID to allow cross account access from CloudFormation in another account - that would look like this:
"Principal": {
"AWS": "123456789012"
"Service": "cloudformation.amazonaws.com"
},
To be clear the user would need to have the following permissions to allow them to pass the role to the service.
"iam:GetRole"
"iam:PassRole"
Without these permissions for your IAM role Arn they cannot pass it to the CloudFormation service to allow it to be assumed.
So in short the permissions to pass the IAM role arn are needed on a user/role in addition to the service being able to assume a role.
More information is available in the Granting a user permissions to pass a role to an AWS service documentation.

Modify EC2 service role so that it can be assumed by an IAM user in the same account

I have a role ssm-role for EC2. I want another IAM user to launch EC2 instance with ssm-role attached.
Policy attached with ssm-role : AmazonEC2RoleforSSM
Trust relationship for ssm-role:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com",
"AWS": "arn:aws:iam::<ACC_ID>:user/test-user"
},
"Action": "sts:AssumeRole"
}
]
}
I have added the following inline policy for the user who wants to assume ssm-role:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "test",
"Effect": "Allow",
"Action": [
"sts:AssumeRole"
],
"Resource": "arn:aws:iam::<ACC_ID>:role/ssm-role"
}
]
}
Despite these, test-user is not able to launch EC2 with ssm-role attached.
Any help will be greatly appreciated.
Note: test-user has EC2FullAccess
To launch an Amazon EC2 instance with an attached role, the IAM User making the request needs to have iam:PassRole permissions for the given role.
This is required to prevent a potential "elevation of authority" situation, such as:
A user has limited permissions
They launch an EC2 instance, specifying a Role that has elevated privileges
They login to the EC2 instance and use the privileges of the Role to perform functions that they would not normally be permitted to do
Thus, a user must have iam:PassRole permissions for the given role (at minimum) to be able to launch an instance that uses that role.
See: Granting a User Permissions to Pass a Role to an AWS Service - AWS Identity and Access Management

AWS ECS Fargate pull image from a cross account ECR repo

I have 2 AWS accounts:
- account A that has an ECR repo.
- account b that has an ECS cluster running Fargate.
I have created a "cross-account" role in account A with trust relations to account B, also I have attached the "AmazonEC2ContainerRegistryPowerUser" policy to this role.
I gave access to the ECR repository in account A by adding account B's id and the "cross-account" role to the repository policy.
I attached a policy to the fargate "TaskExecutionRole" allowing fargate to assume the "cross-account" role.
When trying to deploy a Fargate task in account B with a reference to an image in account A I'm getting a 500 error.
Fargate will not automatically assume a cross-account role. Fortunately, you do not need to assume a role in another account in order to pull images from that account's ECR repository.
To enable cross-account access to an image in ECR, add access for account B in account A's repository (by setting the repository policy), and then specify a TaskExecutionRole in account B that has permissions to pull from ECR ("ecr:GetDownloadUrlForLayer", "ecr:BatchGetImage", "ecr:BatchCheckLayerAvailability").
For example, set a repository policy on the repository in account A like the following:
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "AllowCrossAccountPull",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::ACCOUNT_B_ID:root"
},
"Action": [
"ecr:GetDownloadUrlForLayer",
"ecr:BatchCheckLayerAvailability",
"ecr:BatchGetImage"
]
}
]
}
Then, set your TaskExecutionRole in account B to have a policy like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage"
],
"Resource": "*"
}
]
}
Alternately, you can use the managed policy AmazonECSTaskExecutionRolePolicy for your TaskExecutionRole instead of defining your own.

How to get AWS Glue crawler to assume a role in another AWS account to get data from that account's S3 bucket?

There's some CSV data files I need to get in S3 buckets belonging to a series of AWS accounts belonging to a third-party; the owner of the other accounts has created a role in each of the accounts which grants me access to those files; I can use the AWS web console (logged in to my own account) to switch to each role and get the files. One at a time, I switch to the role for each of the accounts and then get the files for that account, then move on to the next account and get those files, and so on.
I'd like to automate this process.
It looks like AWS Glue can do this, but I'm having trouble with the permissions.
What I need it to do is create permissions so that an AWS Glue crawler can switch to the right role (belonging to each of the other AWS accounts) and get the data files from the S3 bucket of those accounts.
Is this possible and if so how can I set it up? (e.g. what IAM roles/permissions are needed?) I'd prefer to limit changes to my own account if possible rather than having to ask the other account owner to make changes on their side.
If it's not possible with Glue, is there some other easy way to do it with a different AWS service?
Thanks!
(I've had a series of tries but I keep getting it wrong - my attempts are so far from being right that there's no point in me posting the details here).
Yes, you can automate your scenario with Glue by following these steps:
Create an IAM role in your AWS account. This role's name must start with AWSGlueServiceRole but you can append whatever you want. Add a trust relationship for Glue, such as:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "glue.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
Attach two IAM policies to your IAM role. The AWS managed policy named AWSGlueServiceRole and a custom policy that provides the access needed to all the target cross account S3 buckets, such as:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "BucketAccess",
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetBucketLocation"
],
"Resource": [
"arn:aws:s3:::examplebucket1",
"arn:aws:s3:::examplebucket2",
"arn:aws:s3:::examplebucket3"
]
},
{
"Sid": "ObjectAccess",
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": [
"arn:aws:s3:::examplebucket1/*",
"arn:aws:s3:::examplebucket2/*",
"arn:aws:s3:::examplebucket3/*"
]
}
]
}
Add S3 bucket policies to each target bucket that allows your IAM role the same S3 access that you granted it in your account, such as:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "BucketAccess",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::your_account_number:role/AWSGlueServiceRoleDefault"
},
"Action": [
"s3:ListBucket",
"s3:GetBucketLocation"
],
"Resource": "arn:aws:s3:::examplebucket1"
},
{
"Sid": "ObjectAccess",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::your_account_number:role/AWSGlueServiceRoleDefault"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::examplebucket1/*"
}
]
}
Finally, create Glue crawlers and jobs in your account (in the same regions as the target cross account S3 buckets) that will ETL the data from the cross account S3 buckets to your account.
Using the AWS CLI, you can create named profiles for each of the roles you want to switch to, then refer to them from the CLI. You can then chain these calls, referencing the named profile for each role, and include them in a script to automate the process.
From Switching to an IAM Role (AWS Command Line Interface)
A role specifies a set of permissions that you can use to access AWS
resources that you need. In that sense, it is similar to a user in AWS
Identity and Access Management (IAM). When you sign in as a user, you
get a specific set of permissions. However, you don't sign in to a
role, but once signed in as a user you can switch to a role. This
temporarily sets aside your original user permissions and instead
gives you the permissions assigned to the role. The role can be in
your own account or any other AWS account. For more information about
roles, their benefits, and how to create and configure them, see IAM
Roles, and Creating IAM Roles.
You can achieve this with AWS lambda and Cloudwatch Rules.
You can create a lambda function that has a role attached to it, lets call this role - Role A, depending on the number of accounts you can either create 1 function per account and create one rule in cloudwatch to trigger all functions or you can create 1 function for all the accounts (be cautious to the limitations of AWS Lambda).
Creating Role A
Create an IAM Role (Role A) with the following policy allowing it to assume the role given to you by the other accounts containing the data.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1509358389000",
"Effect": "Allow",
"Action": [
"sts:AssumeRole"
],
"Resource": [
"",
"",
....
"
]// all the IAM Role ARN's from the accounts containing the data or if you have 1 function for each account you can opt to have separate roles
}
]
}
Also you will need to make sure that a trust relationship with all the accounts are present in Role A's Trust Relationship policy document.
Attach Role A to the lambda functions you will be running. you can use serverless for development.
Now your lambda function has Role A attached to it and Role A has sts:AssumeRole permissions over the role's created in the other accounts.
Assuming that you have created 1 function for 1 account in you lambda's code you will have to first use STS to switch to the role of the other account and obtain temporary credentials and pass these to S3 options before fetching the required data.
if you have created 1 function for all the accounts you can have the role ARN's in an array and iterate over it, again when doing this be aware of the limits of AWS lambda.