Problem with AWS Lambda and cross account roles - amazon-web-services

I need to assume a cross account role to get access to an ElasticSearch domain for logging on AWS. Here's what I've done:
First, I have created a cross account role in ACCOUNT1. The role name is LoggerAccessToES and the trust relationship is something like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
},
{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::ACCOUNT1:root",
"arn:aws:iam::ACCOUNT2:root"
]
},
"Action": "sts:AssumeRole",
"Condition": {}
}
]
}
Then, on ACCOUNT2, I have created a Lambda function to assume the above role with this code:
sts_client = boto3.client('sts', region_name=Config.AWS_ES_REGION)
assumed_role_object=sts_client.assume_role(
RoleArn="arn:aws:iam::ACCOUNT1:role/LoggerAccessToES",
RoleSessionName="AssumeLoggerAccessToESSession1"
)
When I invoke the lambda (basically the lambda is attached to an SNS topic), I get the error:
botocore.exceptions.ClientError: An error occurred (AccessDenied) when calling the AssumeRole operation: Access denied
I've already tried everything was suggested by other guys in other questions and I also googled the problem but I couldn't find the resolution. What am I doing wrong here?

From what i understand, you want to assume a role in Account 1 using the lambda in account 2.
This would require two roles to be created -
The first role needs to be created in the Account 2 which is to be attached to the Lambda. This role needs to have the following permission attached -
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::ACCOUNT1:role/LoggerAccessToES"
}
}
The above policy can be added to your existing lambda execution role.
For the second part, only the trust relationship of the Role LoggerAccesstoEs needs to be addedin Account 1 shown below-
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::ACCOUNT2:root"
},
"Action": "sts:AssumeRole",
"Condition": {}
}
]
}
The first role policy allows the lambda to use the AssumeRole.
The second policy allows the Account 1 to trust the AssumeRole request from Account 2.

Related

Codebuild Insufficient Permissions: Account A calling step function in Account B

I am currently trying to add a CodeBuild Action Step (Invoking a Step Function) in my CodePipeline deployment process. Specifically, I have a Codepipeline resource in Account A and I have a stepfunction defined in Account B. I want to be able to call my Stepfunction by using the CodeBuild Action step, but I am getting a "Insufficient Permissions Error". The error is below:
Insufficient permissions
An API call to StepFunctions.describeStateMachine (RequestId: XXX) returned a AccessDeniedException error: User: arn:aws:sts::ACCOUNTA:assumed-role/SplitUnitMainStack-pipelinePipelinesplitdeployunit-YVFTJZ8E0Z5U/1640984444652 is not authorized to access this resource
Here is what the permissions looks like for Role : arn:aws:iam::782665913187:role/SplitUnitMainStack-pipelinePipelinesplitdeployunit-YVFTJZ8E0Z5U
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::ACCOUNTB:role/ExecuteUnitStepFunction"
}
]
}
And here is what the ExecuteUnitStepFunction Role looks like, which is defined in Account B
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"states:StartExecution",
"states:StartSyncExecution",
"states:DescribeStateMachine"
],
"Resource": "arn:aws:states:us-west-1:ACCOUNTB:stateMachine:SimpleStateMachineE8E2CF40-TzPjbhdrazrn",
"Effect": "Allow"
}
]
}
The Trust Relationship for this role is this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::ACCOUNTA:root"
},
"Action": "sts:AssumeRole",
"Condition": {}
}
]
}
I am not sure what I am missing in order to give CodeBuild cross-account permissions to execution my Step function. One thing I am not sure about is that in the error, there is set of numbers following the role (1640984444652). I am not sure if this is impacting the permissions or if I am missing a step in order to execute a Step Function across accounts using a CodeBuild action.

AWS sts assume role - user is trusted by target role, user has sts permissions to assume target role. "User not allowed to perform assume role"

I am trying to assume a role in a different account to give me read access. The role (ROLE_IN_TARGET_ACCOUNT) has the permissions I need, however I am getting an error that my user (SOURCE_USER) is not allowed to assume the role.
The ROLE_IN_TARGET_ACCOUNT also has the following trust relationships
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::SOURCE_ACCOUNTID:root"
},
"Action": "sts:AssumeRole",
"Condition": {}
},
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::SOURCE_ACCOUNTID:user/SOURCE_USER"
},
"Action": "sts:AssumeRole",
"Condition": {}
}
]
}
The following policy has been added to an IAM user group in SOURCE_ACCOUNTID
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::TARGET_ACCOUNT:role/ROLE_IN_TARGET_ACCOUNT"
}
and SOURCE_USER is a member of this user group. So ROLE_IN_TARGET_ACCOUNT should trust SOURCE_USER, and SOURCE_USER should have permissions to assume ROLE_IN_TARGET_ACCOUNT.
However, I get the error
An error occurred (AccessDenied) when calling the AssumeRole operation: User: arn:aws:iam::SOURCE_ACCOUNTID:user/SOURCE_USER is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::TARGET_ACCOUNT:role/ROLE_IN_TARGET_ACCOUNT
What am I missing here?
The policies you've shared seem fine (other than the second trust policy being redundant - root includes all auth'd and auth'z principals in SOURCE_ACCOUNTID, which includes SOURCE_ACCOUNTID).
Are there any SCPs, Permissions Boundaries, or Session Policies in your environment? An explicit Deny anywhere in the policy evaluation flow will prevent an otherwise good Allow configuration from working.

update Route53 record set - cross account

Am facing an access issue when trying to update record set using lambda function.
Lambda - Account A
Route53 - Account B
I have an IAM role attached to lambda in Account A with an assume role permission to an IAM role in Account B. The IAM role in account B has access to update the record set in Account B.
When am triggering lambda, am receiving user is not authorized to access this resource.
Can someone help me, if i'm missing anything here or do I need any additional setup.
You are using a Lambda function in Account-A to call Route 53 in Account-B.
This will require:
An IAM Role (Role-A) in Account-A that is assigned to the Lambda function. It should grant permission to call AssumeRole(), with the Resource set to the ARN of Role-B in Account-B:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::<Account-B>:role/role-b"
}
]
}
And with this Trust Relationship:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
An IAM Role (Role-B) in Account-B that has permission to call Route 53. It should also have a trust policy allowing it to be assumed by Role-A in Account-A:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "route53:*",
"Resource": "*"
}
]
}
(This is an overly powerful policy. It would be better to limit it to the specific Route 53 actions that are required.)
And this Trust Relationship (pointing to the Role created in the previous step):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<Account-A>:role/role-a"
},
"Action": "sts:AssumeRole"
}
]
}
You need to use STS to get a token to call Route53 on Account B. Here are the docs on STS in boto3: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sts.html#STS.Client.assume_role
You'll get back a credential that you will use to make the call to Route53.

Dynamodb Cross-account put_item

I have two AWS accounts (account A, and account B). Account A has an EC2 instance, and that instance wants to do a put item to a dynamodb located in account B.
Since it is cross-account access, I created an IAM role on account B to allow account A to do put_item, an IAM role on account A to assume that role and attached the IAM role on the EC2 instance
When I run my program, I get an error message saying that I am trying to use the assume role to put an item to a table that in the same account. (in my code i just sepcified the Account B table name)
It seems that the instance doesn’t realize that the table is on account B even I have the assumerole setup. What am I missing here?
I have also verified that I can put item using AWS CLI (after performing the STS call).
Is there any Java API that I can to specify which dynamodb arn that I want to put the item to?
Error message:
User: arn:aws:sts::ACCOUNT_A:assumed-role/Assume-role/INSTANCE_ID is not authorized to perform: dynamodb:PutItem on resource: arn:aws:dynamodb:us-east-1:ACCOUNT_A:table/TABLE_NAME (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: AccessDeniedException)
Policy on account A:
{
"Version": "2012-10-17",
"Statement": [ {
"Effect": "Allow",
"Action": [ "sts:AssumeRole", "sts:GetFederationToken" ],
"Resource": "arn:aws:iam::AccountA:role/PutItem" },
{ "Effect": "Allow",
"Action": [ "sts:DecodeAuthorizationMessage", "sts:GetAccessKeyInfo", "sts:GetCallerIdentity" ],
"Resource": "*" } ]
}
Policy on Account B:
{
"Version": "2012-10-17",
"Statement": [ {
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [ "dynamodb:PutItem", "dynamodb:UpdateItem", "dynamodb:UpdateTable" ],
"Resource": "arn:aws:dynamodb:region:accB:table/table name" },
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "dynamodb:*",
"Resource": "*" } ]
}

AWS Trust Policy Has prohibited field Principal

I'm trying to create an IAM role and assign it to an EC2 instance according to Attach an AWS IAM Role to an Existing Amazon EC2 Instance by Using the AWS CLI.
The policy looks like below:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
But it gives this error:
This policy contains the following error: Has prohibited field Principal
There is a similar question here but it couldn't fix this issue.
Any help would be appreciated.
Faced the same issue when trying to update the "Trust Relationship" Or same known as "Trust Policy".
"Principal" comes to play only in "Trust Policy". May be by mistake you are updating normal policy falling under the permissions tab. Try updating the policy under "Trust Relationships" tab as below:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"ec2.amazonaws.com",
"lambda.amazonaws.com"
]
},
"Action": "sts:AssumeRole"
}
]
}
The easiest way to create a Service Role is:
Go to the IAM Console
Click Roles
Create new Role
Select an Amazon EC2 service role
Then attach your policies
It will create the trust policy for you.
Please note that the Trust Policy is stored in a separate location to the actual Policy (the bit that assigns permissions). Based upon the error message, it seems like you're putting the trust policy in the normal spot, because Roles don't need a principle (but trust policies do).
write a policy inside bucket --> permissions --> bucket policy --> save
Note: don't write policy in iam console and bucket and cloud-watch regions must be same. other region wont work.
use below policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "logs.YOUR-CLOUD-WATCH-REGION.amazonaws.com"
},
"Action": "s3:GetBucketAcl",
"Resource": "arn:aws:s3:::YOUR-BUCKET-NAME"
},
{
"Effect": "Allow",
"Principal": {
"Service": "logs.YOUR-CLOUD-WATCH-REGION.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::YOUR-BUCKET-NAME/*",
"Condition": {
"StringEquals": {
"s3:x-amz-acl": "bucket-owner-full-control"
}
}
}
]
}