How to set up API keys using aws-cdk python

2.3k Views Asked by At

I need to add an API Key to API Gateway for a proxy resource.
Right now my code adds the requirement for both the proxy and the options resource. How can I specify the requirement only for the proxy?

I managed to do it through the console but it isn't easily manageable.

class Stack(core.Stack):
    def __init__(self, scope: core.Construct, id: str, props: Dict, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        self.version = Path('VERSION').read_text().strip()
        self.namespace = props['namespace']

        role = iam.Role()

        role.add_to_policy()

        bucket = s3.Bucket()
        bucket.grant_read_write(role)

        code = lambda_.Code.from_ecr_image()

        function = lambda_.Function()

        api = apigw.RestApi(
            self, "BackendApi",
            rest_api_name='api',
            deploy_options=apigw.StageOptions(
                tracing_enabled=True,
                data_trace_enabled=True,
                stage_name="some_stage"
            ),
            binary_media_types=['multipart/form-data']
        )

        # Create Api key and add it to the api. Names must be unique independent of stage
        api_key = api.add_api_key("ApiKey", api_key_name="ApiKey", value="1234567890abcdefghij")

        # Create Usage Plan and add it to the API
        plan = api.add_usage_plan("usagePlan", api_key=api_key)
        plan.add_api_stage(stage=api.deployment_stage)

        api_integration = apigw.LambdaIntegration(function)

        proxy_resource = api.root.add_proxy(
            any_method=True,
            default_integration=api_integration,
            default_method_options=apigw.MethodOptions(
                api_key_required=True
            )
        )

        self.add_cors_options(proxy_resource)

    def add_cors_options(self, resource):
        """
        Utility method to add CORS to a Apigateway resource
        Args:
            resource (aws_cdk.aws_apigateway.IResource)
        """
        resource.add_method('OPTIONS', apigw.MockIntegration(
            integration_responses=[{
                'statusCode': '200',
                'responseParameters': {
                    'method.response.header.Access-Control-Allow-Headers': "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'",
                    'method.response.header.Access-Control-Allow-Origin': "'*'",
                    'method.response.header.Access-Control-Allow-Credentials': "'false'",
                    'method.response.header.Access-Control-Allow-Methods': "'GET,POST,OPTIONS'"
                }
            }],
            passthrough_behavior=apigw.PassthroughBehavior.WHEN_NO_MATCH,
            request_templates={"application/json": "{\"statusCode\":200}"}
        ),
            method_responses=[{
                'statusCode': '200',
                'responseParameters': {
                    'method.response.header.Access-Control-Allow-Headers': True,
                    'method.response.header.Access-Control-Allow-Methods': True,
                    'method.response.header.Access-Control-Allow-Credentials': True,
                    'method.response.header.Access-Control-Allow-Origin': True,
                }
            }],
        )

The only way that I managed to add the requirement for the proxy was by adding the requirement in the proxy creation. Is this the better way?

1

There are 1 best solutions below

0
On

Looking at your code snippet, my guess is that you are adding the API Key requirement in the default MethodOptions while creating the proxy resource.

proxy_resource = api.root.add_proxy(
            any_method=True,
            default_integration=api_integration,
            default_method_options=apigw.MethodOptions(
                api_key_required=True
            )
        )

So CDK adds the requirement to that method too, taking off the default_method_options value would fix it.

proxy_resource = api.root.add_proxy(
            any_method=True,
            default_integration=api_integration
        )