aws / chalice

Python Serverless Microframework for AWS
Apache License 2.0
10.64k stars 1.01k forks source link

API Gateway does not have permissions to invoke Custom Authorizer by default #1379

Open gauravcj opened 4 years ago

gauravcj commented 4 years ago

I have created a custom authorizer in my application (actually declared in a BluePrint). CustomAuthorizer( 'DocManCustomAuth', header='Authorization', authorizer_uri=(auth_arn)) However, when I package and deploy the function (using cloudformation), all authorizations fail with: Execution failed due to configuration error: Invalid permissions on Lambda function Fri Mar 20 06:28:55 UTC 2020 : Execution failed due to configuration error: Authorizer error Fri Mar 20 06:28:55 UTC 2020 : AuthorizerConfigurationException I have to delete all references and add another authorizer (pointing to the same function) manually to work. When adding the authorizer, I am given the choice on API Gateway console to give the requisite permissions to API Gateway to invoke the lambda function. That's when it starts working.

jamesls commented 4 years ago

Yeah, it's an interesting question. Here's the thinking behind the current behavior of not adding the permissions for custom authorizers.

If you specify a custom authorizer, you're pointing chalice to a pre-existing lambda function. This lambda function presumably has it's own lifecycle management (e.g something else is managing deploying/updating/deleting this function).

In that case, chalice decides that it's not going to touch the lambda function at all. If you wanted chalice to manage the authorizer, you could use a built-in authorizer. Also, in order to give API Gateway permission to invoke the lambda function, you have to call the AddPermission operation on the custom authorizer lambda function, and we don't even know if we have permissions to modify that function because we didn't create/manage it ourselves.

I'm inclined to keep the behavior as is, but if there's interest we could add an opt-in parameter that tells chalice to try to update the permissions for the lambda function, e.g. CustomAuthorizer(..., manage_api_gateway_permissions=True) or something like that.

Let me know what you think.

gauravcj commented 4 years ago

Great thoughts. The issue with customAuthorizer is that the deployment is as heavy as the main application though it gets deployed as a separate app. If the main app includes libraries like boto3 and others, then the custom authorizer gets them by default and makes the second lambda function heavy as well. To escape that, I wrote a separate custom authorizer. In cdk speak, the authorizer looks like this

lambdaFn = lambda_.Function(
            self, "<some_name>",
            handler="app.lambda_handler",
            code=lambda_.Code.asset("<location of code>),
            timeout=core.Duration.seconds(30),
            role=auth_role,
            runtime=lambda_.Runtime.PYTHON_3_7,
        )

Where auth_role is..

 auth_role = iam.Role(self, 'DocManAuth_LambdaRole',
                             assumed_by=iam.ServicePrincipal(
                                 'lambda.amazonaws.com')
                             )

    auth_role.add_to_policy(iam.PolicyStatement(
            actions=["logs:CreateLogGroup",
                     "logs:CreateLogStream",
                     "logs:PutLogEvents"],
            resources=["arn:aws:logs:*:*:*"]
        ))

But the function fails with the above mentioned error. What am I missing? Is there any documentation that you can point me to? If it does not exist, can we add the requisite documentation?

Thanks and really appreciate the work you are doing!

jamesls commented 4 years ago

Just following up on this. After thinking through it more, I think it makes sense for us to offer to add the appropriate permissions. To make this backwards compatible I'm thinking:

I'm going to mark this as a feature request.