Serverless-application-model: configuring API Gateway resource policy

Created on 25 Jun 2018  路  22Comments  路  Source: aws/serverless-application-model

Description:

The new API Gateway private endpoint feature requires creating a resource policy that allows API requests coming from a VPC.

AFAICT there is no way to configure the Policy field on AWS::ApiGateway::RestApi via SAM. (Additionally, I observe my manually-added resource policies getting wiped on new SAM deployments.)

Steps to reproduce the issue:

  1. Create an API via SAM, setting EndpointConfiguration: PRIVATE

Observed result:
No resource policy on the API.

Expected result:
No resource policy on the API until SAM allows configuring a resource policy for an API in the SAM template.

areserverless-api priorit2-important typfeature v1.14.0

Most helpful comment

For the next person who comes here and sees this, the way to do this in SAM is to define it in the swagger defining your API.

Doc is here https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-resource-policies-create-attach.html#apigateway-resource-policies-create-attach-using-swagger

and it should look something like this

  SomeServerlessApiDefinition:
    Type: AWS::Serverless::Api
    Properties:
      StageName: Prod
      DefinitionBody:
        swagger: '2.0'
        x-amazon-apigateway-policy:
          Version: '2012-10-17'
          Statement:
            - Effect: Allow
              Principal: "*"
              Action: execute-api:Invoke
              Resource:
                - arn:aws:execute-api:*:*:*/Prod/someendpoint
        info:
          version: '2018-11-06'
          description: A description for the API
          title: Some Title
        schemes:
          - https
        paths:
...

All 22 comments

I'll add this as a feature request for the new APIGW feature.

Wanting this feature as well!

This would be awesome! Until then private endpoints are pretty much useless?

@simlu yes, until this is added there's no way to use private endpoints with SAM. That link (https://github.com/serverless/serverless/pull/5071) looks like a different project...

@rgarcia Yes. I thought you could just use cloudformation with SAM, but apparently not?

Yes, you can use Cloudformation with SAM. In this case, though, the Cloudformation field for an API's resource policy is contained within the result of the transformation that SAM applies to your template. Thus there's no way to modify the resource policy without changing how the SAM transformation behaves.

@rgarcia Thank you for the explanation!

Is it possible to apply the Resoure Policy after the main SAM Deployment, in another cloudformation script? What ouputs from the SAM stack would I need. My company is rolling out a cluster of API Gateways that i need secured to internal VPC access only. Let me know your recommendation as I need this feature.

@lorddelicious workarounds I've thought about, but haven't tried:

^ We use (2) extensively for lots of things. And while it is tricky to get right (if you screw up badly your deploy hangs) it is very powerful. We like that everything is still part of the stack deploy and not "manual" api requests after the stack deploy is already completed

I'm currently working on a design doc for all API Gateway auth strategies and I'll create an RFC issue for community feedback soon (will crosslink here).

@simlu Could you list a few things that you're using Custom Resources for? Is this to work around SAM limitations specifically or something else? I'm also working on a doc to enable users to passthrough/override properties of the generated CloudFormation template. This will enable you to use all features (including Resource Policies) without us adding explicit support for it (though explicit support will provide a cleaner interface for defining things; the intent of this passthrough feature is to unblock you). I'll get an RFC out for that soon also.

Hi guys, wanted to update you on my progress. I was able to use the workaround @rgarcia , the first one using the swagger definition file. Mine is YAML formatted, and I need to secure the API access to within our VPC. I was able to get this to go through cloudformation, after playing with some of the CF intrinsic functions. It works and explicitly denies access to outside of VPC, but testing via curl on an EC2 within the VPC I am getting the same denied message. I have tried setting principal to "*" and as well set it to "AWS:ourRoot" with no luck.

{"Message":"User: anonymous is not authorized to perform: execute-api:Invoke on resource: arn:aws:execute-api:us-east-1:**_somehashvalue_/Path/GET/ with an explicit deny"}

swagger: '2.0'
x-amazon-apigateway-policy:
  Version: "2012-10-17"
  Statement:
    - Effect: "Allow"
      Principal:
        AWS:
          Fn::Sub: "arn:aws:iam::${AWS::AccountId}:root"
      Action:
        - "execute-api:Invoke"
      Resource: "execute-api:/*"
    - Effect: "Deny"
      Principal: "*"
      Action:
        - "execute-api:Invoke"
      Resource: "execute-api:/*"
      Condition:
        StringNotEquals:
          aws:SourceVpc:
            Fn::ImportValue:
              Fn::Sub: "${OurVPC}"

@brettstack We use if for everything that is not available through cloud-formation. E.g. setting up cognito triggers, service registration, db init / sync / update / reset on deploy. The goal was to have things happen on stack deploy and not have separate external calls from external - deploying the stack directly from the aws website should result in the same state as deploying it through a deploy script locally - so no, this is not SAM specific.

Another update, I was able to successfully configure the Private Gateway through the Swagger YAML. As listed above, I had to add a VPCE endpoint for the execute-api in my environment https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-private-apis.html#apigateway-private-api-set-up-resource-policy, and every thing worked as expected.

Closing this in favor of #514. Please provide feedback over there if you're interested in Resource Policy implementation.

@lorddelicious could you please share the resource policy that worked for you? I am getting the same error

{"Message":"User: anonymous is not authorized to perform: execute-api:Invoke on resource: arn:aws:execute-api:us-east-1:********somehashvalue/Path/GET/"}

I have tried specifying just * for the Principal but that doesn't seem to work.

Thanks!

@karlgoldstein I was having the same issue and now made it work. The issue caught me was, after you modified the API resource based policy and save, it won't actually take effect until you deploy the API. At first deployment I messed up "vpce-id". I was trying to fix the policy but couldn't make it work. Then I found the exported swagger file still has the non-updated policy.

@karlgoldstein Sorry for the delay, this works for our purposes, remember to set uyp your VPCE endpoint for execute api gateway in your env. Should work.

x-amazon-apigateway-policy:
  Version: "2012-10-17"
  Statement:
    - Effect: "Allow"
      Principal: "*"
      Action:
        - "execute-api:Invoke"
      Resource: "execute-api:/*"
      Condition:
        StringEquals:
          aws:SourceVpc:
            Fn::ImportValue:
              Fn::Sub: "OurVPC"

@lorddelicious (or others), where in your Cloudformation serverless template can you specify an x-amazon-apigateway-policy? I've been struggling to see it show up after my template goes through the transform.

Thanks.

For the next person who comes here and sees this, the way to do this in SAM is to define it in the swagger defining your API.

Doc is here https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-resource-policies-create-attach.html#apigateway-resource-policies-create-attach-using-swagger

and it should look something like this

  SomeServerlessApiDefinition:
    Type: AWS::Serverless::Api
    Properties:
      StageName: Prod
      DefinitionBody:
        swagger: '2.0'
        x-amazon-apigateway-policy:
          Version: '2012-10-17'
          Statement:
            - Effect: Allow
              Principal: "*"
              Action: execute-api:Invoke
              Resource:
                - arn:aws:execute-api:*:*:*/Prod/someendpoint
        info:
          version: '2018-11-06'
          description: A description for the API
          title: Some Title
        schemes:
          - https
        paths:
...

if you are using Cloudformation to create PRIVATE Api use "Resource": !Join ['',["execute-api:/","*"]]
in policy AWS Will translate to proper ARN.

Was this page helpful?
0 / 5 - 0 ratings