AWS Execution failed due to configuration error: Authorizer error - amazon-web-services

I created 2 Authorizers to an API Gateway Endpoint. One manually using console and the other one using boto3.
The one created manually works great, however the one created using script gives error mentioned in the subject line. If you check the contents of these 2 authorizers, they are the same.
What can be the missing part? I dont think this is Invalid permission on lambda as it is working on one authorizer when configured manually.
The code for the same is as below:
response = client.create_authorizer(
restApiId=apiid,
name=authName,
type='TOKEN',
authType='custom',
authorizerUri=authorizerUri,
##arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:<AcctId>:function:CustomAuthorizer/invocations
identitySource='method.request.header.Authorization',
identityValidationExpression= '.*',
authorizerResultTtlInSeconds=300
)
Getting error:
Mon Jul 18 11:53:04 UTC 2016 : Execution failed due to configuration error: Invalid permissions on Lambda function
Mon Jul 18 11:53:04 UTC 2016 : Execution failed due to configuration error: Authorizer error
Mon Jul 18 11:53:04 UTC 2016 : AuthorizerConfigurationException

Just went down this rabbit hole, and came across a solution (worked with boto3 and python, hope it is similar across different sdk's).
The issue is that when you create it manually through the console, there is a popup that asks to enable api gateway (this specific authorizer to be exact) as a trigger to the lambda function you are using as an authorizer. When doing it via sdk, there obviously is no popup, so the authorizer is not authorized to invoke that lambda.
You can enable permissions two ways:
In lambda, create a new trigger for your authorizer in the Designer panel. Specifying an api and stage should do the trick
Create a role that will handle this permission. Give it permission to invoke lambda (you can use the AWSLambdaRole template role) and make sure to add api-gateway as a trusted entity to use this role in the Trust Relationships tab. your policy should look something like this:
{"Version": "2012-10-17","Statement": [{"Effect": "Allow","Principal": {"Service": "apigateway.amazonaws.com"},"Action": "sts:AssumeRole"}]}
Now, when creating a custom authorizer using the sdk, you have to provide an authorizerCredentials parameter, which is described as "(string) Specifies the required credentials as an IAM role for API Gateway to invoke the authorizer. To specify an IAM role for API Gateway to assume, use the role's Amazon Resource Name (ARN). To use resource-based permissions on the Lambda function, specify null.".
Copy your newly-created role's arn and use this as the value for the authorizerCredentials param.
Viola! you now have a custom authorizer that is allowed to use the role that allows it to invoke the lambda function!
(sorry for bad formatting, I don't comment often :D)

First, use the test button in API Gateway to confirm if you can call your Lambda function from within it. This will ensure that the API Gateway-to-Lambda connection is working.
To assess your resource policies, you need to call the GetPolicy API; the execution role controls what your code an do in Lambda, not who can call it. That would be a good next check.
You can also turn on logging in API Gateway, which is a good way to gain additional insight into what it's doing on your behalf. These logs then show up in Amazon CloudWatch Logs, where you can check out the flow of your request.
If you're using CORS, it's possible to miss a setting (or two :), so I would double check that as well. CURLing directly to your endpoint (you can easily test from Lambda using its HTTP endpoint blueprint) is a good first step before you "wire up" your API to a website or other app directly.

It would be helpful if you check your CloudWatch Logs Insights.
Go to your lambda function, open "Monitor" section. Read through the last logs received.
In my case, I made a typo on lambda methods handler address. That is why the error thrown.

You need to add a resource-based statement to your Lambda's permissions, in order to allow it to be called by your gateway. As #MichaelJoy points out, this is taken care of in the console when you click "Create" on the popup. Doing this programmatically requires taking a second step after your authorizer has been created.
To do this via CLI, you can do the following (presumably boto3 has all of the corresponding commands):
aws lambda add-permission --function-name 'arn:aws:lambda:us-west-2:<AcctId>:function:CustomAuthorizer' \
--action lambda:InvokeFunction --statement-id 'api_gateway' \
--principal apigateway.amazonaws.com --output text \
--source-arn "AUTHORIZER_ARN"
where AUTHORIZER_ARN is the ARN of the authorizer you just created. Note that the statement id of 'api_gateway' is arbitrary.
You can see all resource-based policies on your Lambda via the following. This may be helpful esp if you want to inspect the permissions added by you via the console as a working example of what you need to effect programmatically to get the same result:
aws lambda get-policy --function-name XXXX
If you're updating an existing resource-based permission, you'll need to remove it first via the remove-policy command

Related

AWS Lambda doesn't have DynamoDB permissions when invoked by URL/API Gateway

We have a pair of existing AWS Lambda functions that read/write from a DynamoDB table. I created a new function and table; the function is very basic, just does a putItem on the DynamoDB table. I can successfully invoke it with the test functionality in Lambda.
However, if I invoke the Lambda function using the FunctionURL or via API Gateway, I get the following error.
Yet in Configuration > Permissions in the Lambda interface I clearly see the permission:
Suggestions where to check next? Comparison to our existing, working functions hasn't revealed anything; everything I have checked in configured the same.
Thanks!
When you invoke the lambda function in the lambda console, lambda is using an Execution role.
When you invoke the lambda function via API gateway or via the function URL, it is likely that you are using IAM authorization. As a result, lambda is using the role of the principal who invoked the function (in this case, PatientWellnessDeregistration-role-3ospc0u3).
The execution role is configured correctly, but the IAM role of the principal is lacking the required permissions.
Further reading:
https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html
https://docs.aws.amazon.com/lambda/latest/dg/urls-auth.html
What you could optionally check is that API Gateway is authorized to call your new Lambda. If so, then the Resource-based policy of the Lambda (still in the Permissions tab) should have something similar to:
Resource-based policy example:

Accessing LambdaURL with AWS_IAM auth from EC2 using IAM role

I have a Lambda that does some things and needs to be trigered from Jenkins build. Jenkins uses EC2 agents with a specific "jenkins" role attached to them to execute the build. To access lambda we use LambdaURL, when we set auth type to NONE, everything works fine, but we want to have this endpoint secure, so we switched to AWS_IAM auth type. We set up lambda permissions to give "jenkins" role lambda:InvokeFunctionUrl rights for this lambda, I also attached full lambda permissions policy for this role during testing. But still we get "Forbidden" from that LambdaURL. I found this blogpost that states that in case of AWS_IAM auth type we also need AWS Sigv4 signature. But I don't understand how we can sign it in jenkins using that "jenkins" role. Am I missing something? What may be the best way to limit access to that FunctionURL- instead of auth type?
Thanks!
After some time I realised that in this case it is mush better to invoke lambda with API or awc-cli, not via FunctionURL. I used boto3 and it worked! More on how: https://hands-on.cloud/working-with-aws-lambda-in-python-using-boto3/#How-to-invoke-Lambda-function-using-Boto3

Use Test button in API Gateway console with specific lambda version

I have an API Gateway resource that points to a specific version of lambda:
Foo-LambdaFunction7804AD21-1LLYB0GTDYURR:1
I use AWS API Gateway web UI navigate to the resource, then "test" section. I click "Test" and get back:
Execution failed due to configuration error: Invalid permissions on Lambda function
If I point to a lambda ARN without a version, i.e.
Foo-LambdaFunction7804AD21-1LLYB0GTDYURR
then it works as expected.
Does "Test" page of the AWS UI console has a different resource id and requires different resource-based policy statement?
I had to give API Gateway's execution role a permission to call Foo-LambdaFunction7804AD21-1LLYB0GTDYURR:1 lambda version.

Deploying an AWS Lambda from a different account

I have a Lambda .jar that I build from a Jenkins box in an AWS account ("Account_Bld"). Once built, I copy the .jar over to an S3 bucket in a different AWS account ("Account_Dst"), and I attempt to update the Lambda in Account_Dst based on the newly copied .jar in S3.
I'm using this command as part of my deploy script, which is a slight modification of another version that works when everything is located in the same account:
aws lambda update-function-code --function-name arn:aws:lambda:us-east-1:{Account_Dst_Id}:function:{lambda_function_name} --zip-file fileb://{jar_file_relative_path} --region us-east-1
Not surprisingly, I get this error:
An error occurred (AccessDeniedException) when calling the UpdateFunctionCode operation: User: arn:aws:sts::{Account_Bld_Id}:assumed-role/{jenkins_ec2_role}/{jenkins_ec2_instance_id} is not authorized to perform: lambda:UpdateFunctionCode on resource: arn:aws:lambda:us-east-1:{Account_Dst_Id}:function:{lambda_function_name}
I have given jenkins_ec2_role rights to update the Lambda in the other account, but it makes sense that I would need to reciprocate those rights somewhere in Account_Dst -- assuming there is a simple solution to this problem.
Now, possible resolutions. I could assume a role in Account_Dst that has the correct rights and update the Lambda, but that's more setup hassle than it is worth to me right now. I've seen some Google suggestions that I could use CodePipeline, but obviously I'm using Jenkins, so that doesn't seem like a good solution, either.
So, the question is, is there an easy solution here that I am missing?
This is now possible. A Lambda resource based policy can be configured to allow a principal from another account to perform actions e.g. lambda:UpdateFunctionCode or lambda:Invoke.
In case of UpdateFunctionCode, the documentation states:
FunctionName
The name of the Lambda function.
Name formats
Function name – my-function.
Function ARN – arn:aws:lambda:us-west-2:123456789012:function:my-function.
Partial ARN – 123456789012:function:my-function.
...
Source: https://docs.aws.amazon.com/lambda/latest/dg/API_UpdateFunctionCode.html
The Lambda Function permission in account 222222222222 must be configured to allow the principal from account 111111111111 to update the function code:
aws lambda add-permission --function-name my-function --statement-id xaccount --action lambda:UpdateFunctionCode --principal 111111111111 --output out.txt
Source:
https://docs.aws.amazon.com/lambda/latest/dg/access-control-resource-based.html#permissions-resource-xaccountinvoke
Then the function code in account 222222222222 can be updated from account 111111111111:
aws lambda update-function-code --function-name arn:aws:lambda:us-west-2:222222222222:function:my-function --zip-file fileb://soure.zip
Granting permissions in Account_Bld to access Account_Dst is not sufficient to gain access to another account. This is good, because you wouldn't want people granting themselves access to other people's accounts.
The destination account needs to accept the incoming request. The method varies by service. For example, Amazon S3 can create a Bucket Policy to permit access from other accounts, as can Amazon SQS.
However, there is no such concept in Lambda to configure incoming requests from other accounts. There is simply nowhere that can be configured to allow update-function-code from another account.
Therefore, you will need to do as you suggested:
Create an IAM User or IAM Role in Account_Dst
Use the credentials from the Account_Dst IAM User (simplest) or use the existing Account_Bld credentials to assume the Role in Account_Dst (a few more lines of code)
Call update-function-code using those credentials

Api Gateway can't invoke Lambda function

Following this tutorial on AWS, I hit a roadblock when trying to test the api through the web console (as many others did):
Thu Nov 10 22:54:48 UTC 2016 : Execution failed due to configuration error: Invalid permissions on Lambda function
I've read every relevant post on SO and AWS forums I could find, but can't figure out how to grant permission to the API Gateway to invoke the Lambda function.
Web Console Method:
Thanks to this mate I found a quick fix:
Go into the web console and select
The resource method > Integration Request > Pencil next to Lambda Function > Check mark next to lambda function (don't change the name)
A popup window should warn that you are granting permissions to the API to execute the lambda function.
API Method:
Also, thanks to Richard Downer for this code explanation:
A resource policy is different from an IAM Policy, setting the IAM policy will not work.
You need to use the Add-LMPermission api call after creation of Write-AGIntegration.
Here is an example:
Add-LMPermission -FunctionName myfunction -Action lambda:InvokeFunction -Principal apigateway.amazonaws.com -SourceArn arn:aws:execute-api:us-west-2:IAMAccountNumber:*/*/POST/apiendpoint -StatementId description