AWS API Gateway Cross Account - amazon-web-services

I have API gateway set up in account A and I have linked my lambda in account B with my api method in account A (added the correct permissions to account B). It always used to worked perfectly.
Now when I tried to deploy a change to the api gateway it keeps saying "The policy of Lambda function must explicitly authorize the method or custom authorizer with a SourceArn condition for cross account integration".
I have checked multiple times, all the permission are there in account B on the lambda function. I even deleted them and added them again. If I add the permission for just the lambda function without the alias it works, but when I add my alias then I get the "The policy of Lambda function must explicitly authorize the method or custom authorizer with a SourceArn condition for cross account integration" error, but I can see the permissions for my lambda with the alias in account B.
What am I doing wrong?

Related

Access CloudWatch Evidently Cross-Account?

I have a cloudwatch evidently project in one account and have a lambda in another account that wants to call EvaluateFeature on the cross-account Evidently project. Is this possible?
I've been using this client https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/evidently/EvidentlyClient.html
and even though I give it the project arn of the target account's project (in the project parameter of EvaluateFeatureRequest), it seems to re-route the EvaluateFeature request into the account the lambda resides in. Not sure if anyone has done something similar before.
I have a role in the Evidently account that can be assumed by Lambda service principal. With the stsAssumeRole permission also part of the Lambda's role policy. I just can't get EvaluateFeature to direct itself to the correct Arn/project.
Thanks.

Trigger Lambda in Account B from Lambda in Account A

I have a lambda function in Account A which will retrieve data from a source. This lambda will then need to trigger off a lambda in Account B in order to pass this data to it which then will be uploaded to DynamoDB.
I understand there will be some sort of cross-account-permissions required but am a little unsure if i need to allow these permission in Account A or Account B. I can see on AWS examples of triggering a lambda from an S3 bucket but that's not helping with what I want to do.
I could potentially have an API Gateaway in the middle for Lambda A to interact with Lambda B but that's just adding an extra resource that's not really required.
Your AWS Lambda function in account A would call the Lambda.invoke() method in the AWS SDK for whatever programming language you are writing the Lambda function with.
I understand there will be some sort of cross-account-permissions
required but am a little unsure if I need to allow these permission in
Account A or Account B
Account B Lambda is the one being called, so Account B has to give permission to Account A to make that call.
Here you got an example of cross-account permissions with lambda function: https://yogeshnile.cloud/configure-a-lambda-function-to-assume-an-iam-role-in-another-aws-account-e005e7533a71
Trigger Lambda in Account B from Lambda in Account A -> Lambda.invoke()
Btw, you don't need the lambda function in account B - you can add permissions to your DynamoDB table to assumed role, so your lambda from account A will be able to write data directly into DynamoDB on account B.

AWS - Invoke Step function using API Gateway with IAM User's identity

We have a setup like this in AWS -
Step functions include few lambda functions that write to S3 buckets
S3 bucket is passed as an argument to lambda functions by the user
API Gateway is setup to invoke Step Functions and IAM Authorization is enabled
However, currently the step function and lambdas are invoked under the IAM role defined, but we want all lambdas to be executed as the authenticated user. So if the user invoking API does not have access to S3 bucket passed, the lambda should fail. How can this be achieved ?
One of the responsibilities of Amazon API Gateway is to be a facade for your backend (here Step function and Lambda functions) and to guard it from unauthorized invocation.
I see two options. The first is easy, the second is more proper way to have all constrols.
Don't give your IAM users permissions to call this API if they don't have permissions to access data in S3 bucket. Also, remove permissions to access Step Function and Lambda Functions. Apply the principle of least privilege.
Instead of using IAM Users, use Amazon Cognito to authenticate your users to your application. Attach Cognito as an Authorizer to your API. Your Lambda function can get information about the user via context input parameter. Use DynamoDB to store additional information about the user and add business logic to your Lambda to handle any special behavior.

Creating budget actions to shutdown Lambda

I have registered a free tier AWS Lambda account and created a simple, public service for me and others to play around with. However, since I do not know yet how usage is going to be, I want to be careful for now. Otherwise someone could simply flood my service with one million requests and I get billed for it. I'd rather not have the service available.
Therefore, I want to create a budget action that shuts down all services as soon as $0.01 is exceeded. The way I've done this is that I've granted the Lambda service role (which was auto-created when I setup the lambda service) the budget permission (budgets.amazonaws.com) and then have an IAM action setup that adds the AWSDenyAll managed policy to the role itself once the budget is exceeded.
This does not seem to work. If I manually attach the AWSDenyAll policy, the Lambda service still is available. My understanding of the roles/policies system may be also fundamentally wrong.
How can I achieve a "total shutdown" action that can be triggered from a budget alert?
You're applying the AWSDenyAll policy to the execution role of the Lambda function, which is used to define permissions to access AWS resources from the Lambda itself (Configuration > Permissions > Execution role).
You essentially have blocked the Lambda function itself from accessing AWS services.
You haven't blocked any IAM principals (users or roles), AWS services (including API Gateway) or other AWS accounts which is why your Lambda can still be invoked manually or via the gateway.
Now, a question that may now arise is "how can I prevent the API Gateway from invoking my Lambda?".
The way that API Gateway is given access to trigger your Lambda is via resource-based permissions policies (Configuration > Permissions > Resource-based policy).
This is not "encapsulated" within an IAM entity (user or role) and currently, you can only update resource-based policies for Lambda resources within the scope of the AddPermission and AddLayerVersionPermission API actions.
This means that the only way to revoke API Gateway's access to invoking your function would be to delete the resource policy allowing API Gateway to invoke your function using the RemovePermission API action or via the console.
There would be no way to do this via budget actions.
The other question that can arise is "how can I prevent API Gateway and the Lambda function from being invoked then?".
This still wouldn't be possible using Budget Actions as per docs, you can only apply an IAM policy or a service control policy (SCP) none of which will help you to prevent triggering of a Lambda which is triggered via the API Gateway. You can prevent the Lambda from being triggered by AWS users within the console but you can't prevent the API Gateway unless you are using IAM to authenticate your users.
There isn't any way to "shutdown" Lambda functions or the API Gateway once you hit a specific budget limit.
You will just have to create a budget to alert you, filter on the service dimension to the Lambda and API Gateway services for example, and then take manual action (setting a monthly usage budget with a fixed usage amount and actual/forecasted notifications).

Switch profile/account/role in AWS Lambda

I am trying to connect to an AWS AppSync, located in a custom profile/account/role under the root/default account, from an AWS Lambda in the root/default account.
The below python code works fine locally, because I have configured "custom_profile" in my local .aws/config file.
session = boto3.Session(profile_name='custom_profile')
client = session.client('appsync', region_name='<region>')
But is there any way to make this code run in the AWS Lambda in the root account? How can AWS Lambda understand what is "custom_profile"? Where and how can I map "custom_profile" to the respective role ARN?
I saw a probable solution to this problem on this link, but I have not tried it.
Has anyone faced a similar issue and know of an easier solution to this problem than in the link?
The link that you've referenced is the way to go. Permissions that an AWS Lambda function has, are to be defined in a role for that function. This can include permissions to assume a role in another account.
You can then use the Security Token Service (or STS for short) and execute the AssumeRole action. This will provide you with AWS tokens that you can use to authenticate your calls to the other account.
You will also have to configure the account you're executing the lambda function in as a trusted entity in the role you want to assume in the second account.