aws / aws-cdk

The AWS Cloud Development Kit is a framework for defining cloud infrastructure in code
https://aws.amazon.com/cdk
Apache License 2.0
11.72k stars 3.94k forks source link

apigateway: Attaching a resource policy for a private API #31660

Open badmintoncryer opened 1 month ago

badmintoncryer commented 1 month ago

Describe the feature

Add a method to easily attach a resource policy for creating a Private API Gateway.

Use Case

To create a Private API Gateway, you need to attach a resource policy that allows access only from specific Interface VPC Endpoints, as shown below.

new apigateway.RestApi(this, 'PrivateRestApi', {
      endpointTypes: [apigateway.EndpointType.PRIVATE],
      handler: fn,
      policy: new iam.PolicyDocument({
        statements: [
          new iam.PolicyStatement({
            principals: [new iam.AnyPrincipal],
            actions: ['execute-api:Invoke'],
            resources: ['execute-api:/*'],
            effect: iam.Effect.DENY,
            conditions: {
              StringNotEquals: {
                "aws:SourceVpce": vpcEndpoint.vpcEndpointId
              }
            }
          }),
          new iam.PolicyStatement({
            principals: [new iam.AnyPrincipal],
            actions: ['execute-api:Invoke'],
            resources: ['execute-api:/*'],
            effect: iam.Effect.ALLOW
          })
        ]
      })
    })

Proposed Solution

My idea is to implement a addVpcEndpointAccessPolicy method like below.

declare const interfaceVpcEndpoint: ec2.InterfaceVpcEndpoint;

const api = new apigateway.RestApi(this, 'PrivateRestApi', {
      endpointTypes: [apigateway.EndpointType.PRIVATE],
})
// add resource policy
api.addVpcEndpointAccessPolicy(interfaceVpcEndpoint);

Is there any good ideas?

Other Information

No response

Acknowledgements

CDK version used

2.160.0

Environment details (OS name and version, etc.)

irrelevant

pahud commented 1 month ago

I was thinking maybe we should implement a grantInvoke() method which returns an iam.Grant and addToPrincipalOrResource() with the vpc endpoint so the experience would be like

declare const interfaceVpcEndpoint: ec2.InterfaceVpcEndpoint;

const api = new apigateway.RestApi(this, 'PrivateRestApi', {
      endpointTypes: [apigateway.EndpointType.PRIVATE],
})
api.grantInvoke(interfaceVpcEndpoint);

wdyt?

I am requesting more input from the maintainers as well. Thank you for your attention to this matter.

badmintoncryer commented 1 month ago

@pahud It sounds really nice! I will try to implement it later😁