EventBridge invokes Lambda as a target - aws-lambda

We are designing a solution which has a Lambda function as a source and another Lambda function as a target to EventBridge.
I read that for the put_rule part, the RoleArn has the ARN for the role which the rule will use needs to have the permission to invoke the target Lambda function.
But for Lambda we don't use IAM roles, but use resource bases policies instead.
The question is, where we are specifying the resource based policy in the code. In the RoleArn?
And what's the fields in the targets part for the target Lambda function?
eventclient = boto3.client('events')
response = eventclient.put_rule(
Name='notificationScheduler',
ScheduleExpression='at(2023-02-01T02:30:00)',
State='ENABLED',
Description='schedule notifications reminders '
**RoleArn**='string', ## The ARN for the role which the rule will use needs to have the permission to invoke the target lambda function
)
response = eventclient.put_targets(
Rule='notificationScheduler',
Targets=[{ ??? }]
)

You must use a Lambda resource policy to grant EventBridge invoke permissions, not a role.
Docs: Amazon SQS, Amazon SNS, Lambda, CloudWatch Logs, and EventBridge bus targets do not use roles, and permissions to EventBridge must be granted via a resource policy. API Gateway targets can use either resource policies or IAM roles.
Create the Lambda permissions (= resource policy) with the AddPermission API:
lambdaclient.add_permission(FunctionName=func_name, StatementId="MyPermissionId", Action="lambda:Invoke", Principal="events.amazonaws.com")
Add the Lambda function as a rule target by ARN:
eventclient.put_targets(Rule="notificationScheduler", Targets=[{"Id": "MyLambdaTarget", "Arn": func_arn }])

Related

Error reading new Lambda permissions: AccessDeniedException in GitHub Action

I am deploying the AWS resources using GitHub Actions and I am using terraform to create resources.
I have given the required Assume and IAM policy to the GitHub repo to deploy the resources.
One of my use cases is, that I need a cloud watch event rule which triggers the lambda every 1 hr. The Cloud watch event rule and lambda have been created successfully.
But, I got Error: Error reading new Lambda permissions: AccessDeniedException: error in the below statement during deployment.
Which IAM policy needs to add to execute the above statement.
resource "aws_lambda_permission" "allow-cloudwatch-lambda-execute" {
statement_id = "AllowExecutionFromCloudWatch"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.lambda.function_name
principal = "events.amazonaws.com"
source_arn = aws_cloudwatch_event_rule.lambda-clodwatch-event-rule.arn
}

How to pass output of lambda authorizer info to another lambda function in AWS API gateway?

I have created two Lambda functions using C#. One is to authorize and another is to perform some business logic.
I have configured first Lambda function as API gateway Authorizer and second one as Resource.
How I can pass the response of first lambda function to a API gateway request so that second one can read and continue with remaining processing?
Thanks
Satya
If your first lambda function has been authorized by API Gateway then you can just call the second lambda function directly from the first one provided the first lambda has the correct permissions to call the second lambda.
iamRoleStatements:
- Effect: Allow
Action:
- lambda:InvokeFunction
- lambda:InvokeAsync
Resource: "*"

How can I use permissions generated in AWS Custom Authorizer in my lambda code?

I'd like to generate a custom policy that provides fine grained access to DynamoDB tables inside an AWS custom authorizer. Is this possible?
In serverless, my configuration looks like this:
functions:
APIAuthorizer:
handler: src/services/auth/handlers.apiAuthorizer
cors: true
GraphQLAPI:
handler: src/services/graphql/handlers.apiHandler
events:
- http:
path: "/api"
method: post
cors: true
authorizer:
name: APIAuthorizer
type: request
resultTtlInSeconds: 0
I've verified that my custom authorizer is being called, and that various permissions it generates (sts:AssumeRole, lambda:InvokeFunction, execute-api:Invoke, and others) are required for successfully invoking the API handler. So my custom authorizer is working and the result it provides is necessary.
However, when the authorizer includes dynamodb permissions, e.g., a statement like
{ Effect: "Allow", Action: "dynamodb:", "Resource": "" }
my API handler (the GraphQLAPI function) fails with a message like
User: arn:aws:sts::<myaccountid>:assumed-role/<mydefaultrole>/myservice-mystage-GraphQLAPI is not authorized to perform: dynamodb:Query on resource: arn:aws:dynamodb:us-east-1:<myaccountId>:table/<mytable>/index/<someIndex>
(I noticed the complaint is about an index permission, so also tried adding specific permissions for that index and/or for all indexes, but this has no effect.)
The bottom line, after many different attempts, is that dynamodb permissions issued by the custom authorizer are completely ignored. My lambda node.js code is using the AWS node SDK, which should be picking up permissions from the instance environment. I assumed this would include permissions generated by the custom authorizer.
Finally, I noticed that the AWS javascript SDK documentation on how credentials are loaded says only "The execution role provides the Lambda function with the credentials it needs to run and to invoke other web services". I.e., it doesn't mention the dynamically generated credentials issued by the custom authorizer.
This seems to explain the behavior I'm seeing. My API handler only has permissions from the statically defined execution role (the error message indicates that too), and isn't granted permissions generated by the custom authorizer.
Is there anyway to use the permissions my custom authorizer generates inside my API handler?
I think you misunderstood the IAM policy output from Lambda authorizers. The purpose of the IAM policy output from the authorizer is to reflect what the outcome should be for API gateway with respect to continuing to process the request.
The policy returned is not necessarily applied to the invoked function, but applied to the invocation of the function. It merely tells API Gateway which APIs the requesting user is authorized to access.
If you wish to give the API functions being invoked specific access to resources such as DynamoDB tables, or any other AWS resources, those have to be configured in the role assigned to the Lambda function. Otherwise, you may be able to specify a role that the Lambda function to be invoked would assume that grants it additional permissions. This role can be passed via the context parameters from the authorizer.

how does aws lambda invoke work

I am fairly new to lambda and trying to wrap my head around it. I created a basic hello world function and invoked it through
aws lambda invoke
My question is
Dont I have to create an API gateway and expose the lambda function through the API gateway for it work.
How does aws lambda invoke if I have not created a gateway and exposed the function?
You do not have to necessarily create API gateway for invoking lambda function. Every lambda function is already available to be accessed via Amazon's Web Service using API:
POST /2015-03-31/functions/FunctionName/invocations?Qualifier=Qualifier HTTP/1.1
See http://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html for more details.
However, the above API expects that the request payload is signed using aws signature version 4 . The CLI call aws lambda invoke automatically takes care of that piece once you have configured valid access and secret keys.
The API Gateway in front of lambda allows you to add:
Custom resource names
Custom authentication schemes (even no authentication if desired)
Custom way of sending payload
and more...
In summary, API Gateway gives you more control over the API resource and can even abstract the user from internals of AWS API.

AWS API Gateway: How to pass IAM identity to Lambda function?

I've successfully configured IAM-authenticated access to my Lambda function with AWS API Gateway front-end, but unable to find how to pass IAM user identity to my Lambda function.
I need exactly IAM user identity and can not run Lambda function under calling IAM-user credentials.
All I need - is to get calling IAM-user identity in my Lambda function.
Is there option for that?
Support for accessing identity and other information from the Amazon API Gateway request context hadn't been available when you posted the question, but recently been added, see Announcement: Context Variables:
You can now access context variables from within mapping templates to retrieve contextual information about the API call. You can access data such as stage, resource path, and HTTP method, as well as information about the identity of the caller. This information can then be passed along to your backend integration using the $context variable. [emphasis mine]
The referenced documentation on Accessing the $context Variable features a $context Variable Reference and there are various $context.identity.* parameters that should address your use case.
Cognito Identity
As outlined in Soenke's answer to the OPs similar question in the Amazon API Gateway forum, there is an as of yet undocumented integration parameter that results in the Cognito identifier being included in this $context.identity.* context variables:
in order to have the Cognito (not IAM!) IdentityId and IdentityPoolId
available in Lambda, you have to enable "Invoke with caller
credentials" on the API Gateway "Integration Request" page of the API
GW Resource. This results in a new context struct "identity"
(containing "cognitoIdentityId" and "cognitoIdentityPoolId" being
passed to the Lambda function).
You can use Cognito with a "public" pool id, then attach role to the Cognito pool id, the role being accessing your Lambda, I think it is called InvokeLambdaRole or something
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: 'REGION:YOUR_POOL_ID',
});
Use AWS STS to get temporary credentials with limited privileges. After that you can use API Gateway with AWS_IAM authentication, then end point will invoke the Lambda methods for you. Or you can invoke lambda directly with the credentials you got, but then again you have to attache the right roles for the identity pool you created.
NB: Put strictly minimum roles on your pole, that is a publicly available id, every body can use it to get a temporary or a fixed (to track users accross devices) user_/app_ id.

Resources