Lambda function URL using Cloudfront OAC

0

Hi,

I tried to configure one of my lambda url to be accessible only though CloudFront OAC. I tried to follow this guide: Restricting access to an AWS Lambda function URL origin. Unfortunetly it doesn't seemed to work. When I try to access my lambda through is URL, I get this error: {"Message":"Forbidden"}. Here are the steps I followed : I created a Cloudfront OAC like this:

CloudFrontOacLambda:
    Type: AWS::CloudFront::OriginAccessControl
    Properties:
      OriginAccessControlConfig: 
          Description: OAC to access lambda function url
          Name: MyName
          OriginAccessControlOriginType: lambda
          SigningBehavior: always
          SigningProtocol: sigv4

I configured my cloudfront distribution to use this OAC:

...
Origins
 - DomainName: !Select [2, !Split ["/", !Ref LambdaFunctionUrl ]] # Remove https:// from URL. 
          Id: LambdaOrigin
          OriginAccessControlId: !GetAtt CloudFrontOacLambda.Id
          CustomOriginConfig:
            HTTPSPort: 443
            OriginProtocolPolicy: https-only

I updated my KMS key policy to allow CloudFront to it :

...
Effect: Allow
              Principal:
                Service: cloudfront.amazonaws.com
              Action:
                - kms:Decrypt
                - kms:Encrypt
                - kms:GenerateDataKey*
              Resource: "*"
              Condition:
                StringEquals:
                  "AWS:SourceArn": !Sub "arn:${AWS::Partition}:cloudfront::${AWS::AccountId}:distribution/${MyDistribID}"

I updated the resource-based policy of my lambda using aws cli as described in the documentation:

aws lambda add-permission \
--statement-id "AllowCloudFrontServicePrincipal" \
--action "lambda:InvokeFunctionUrl" \
--principal "cloudfront.amazonaws.com" \
--source-arn "arn:aws:cloudfront::123456789012:distribution/MyDistribID" \
--function-name FUNCTION_URL_NAME

I removed the previous policy of my lambda that provide public access.

After doing this, my fonction url is not accessible anymore (using direct Url OR or using Cloudfront).

Can someone help me and tell me what I missed ? Thanks a lot for your help !

질문됨 한 달 전162회 조회
2개 답변
0

Hello.

Are you accessing the Lambda URL directly?
Are you accessing the CloudFront URL (https://example.cloudfront.net/) instead of the Lambda URL?
Also, is the CloudFront distribution ID set in the Lambda resource-based policy correct?

profile picture
전문가
답변함 한 달 전
profile pictureAWS
전문가
검토됨 한 달 전
  • I can't access the URL, directly or using the distribution url. Always the same error : {"Message":"Forbidden"} On the lambda ressource-based policy, il I add the default public policy, the url is accessible (directly or using cloudfront url).

  • By the way, is the authentication method for the Lambda function URL set to IAM authentication? a
    If the authentication method is IAM, you can access it from CloudFront if the following resource-based policy is set for Lambda.

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "AllowCloudFrontServicePrincipal",
          "Effect": "Allow",
          "Principal": {
            "Service": "cloudfront.amazonaws.com"
          },
          "Action": "lambda:InvokeFunctionUrl",
          "Resource": "arn:aws:lambda:ap-northeast-1:account-id:function:cloudfront",
          "Condition": {
            "ArnLike": {
              "AWS:SourceArn": "arn:aws:cloudfront::account-id:distribution/xxxxxxxxxxx"
            }
          }
        }
      ]
    }
    
  • If the authentication method was "NONE", access was not possible without the following resource-based policy.

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "StatementId": "FunctionURLAllowPublicAccess",
          "Effect": "Allow",
          "Principal": "*",
          "Action": "lambda:InvokeFunctionUrl",
          "Resource": "arn:aws:lambda:ap-northeast-1:account-id:function:cloudfront",
          "Condition": {
            "StringEquals": {
              "lambda:FunctionUrlAuthType": "NONE"
            }
          }
        },
        {
          "Sid": "AllowCloudFrontServicePrincipal",
          "Effect": "Allow",
          "Principal": {
            "Service": "cloudfront.amazonaws.com"
          },
          "Action": "lambda:InvokeFunctionUrl",
          "Resource": "arn:aws:lambda:ap-northeast-1:account-id:function:cloudfront",
          "Condition": {
            "ArnLike": {
              "AWS:SourceArn": "arn:aws:cloudfront::account-id:distribution/xxxxxxxxxxx"
            }
          }
        }
      ]
    }
    
  • No it is not, as the documentation does not ask to configure it. This is the configuration described in the doc :

    aws lambda add-permission \
    --statement-id "AllowCloudFrontServicePrincipal" \
    --action "lambda:InvokeFunctionUrl" \
    --principal "cloudfront.amazonaws.com" \
    --source-arn "arn:aws:cloudfront::123456789012:distribution/DistributionID" \
    --function-name FUNCTION_URL_NAME
    

    But I tried to set it, but it doesn't seemed to work either. This is my current Lambda Policy (without IAM autnentication):

    {
      "Version": "2012-10-17",
      "Id": "default",
      "Statement": [
        {
          "Sid": "AllowCloudFrontServicePrincipal",
          "Effect": "Allow",
          "Principal": {
            "Service": "cloudfront.amazonaws.com"
          },
          "Action": "lambda:InvokeFunctionUrl",
          "Resource": "arn:aws:lambda:region:1234567890:function:myFunc",
          "Condition": {
            "ArnLike": {
              "AWS:SourceArn": "arn:aws:cloudfront::1234567890:distribution/MyDistribID"
            }
          }
        }
      ]
    }
    
  • I tried this one but it doesn't work either:

    {
      "Version": "2012-10-17",
      "Id": "default",
      "Statement": [
        {
          "Sid": "test",
          "Effect": "Allow",
          "Principal": {
            "Service": "cloudfront.amazonaws.com"
          },
          "Action": "lambda:InvokeFunctionUrl",
          "Resource": "arn:aws:lambda:region:123456789012:function:myFunc",
          "Condition": {
            "StringEquals": {
              "lambda:FunctionUrlAuthType": "AWS_IAM"
            },
            "ArnLike": {
              "AWS:SourceArn": "arn:aws:cloudfront::123456789012:distribution/MyDistrib"
            }
          }
        }
      ]
    }
    
0

Ok, I found what I missed ! The Policy was good BUT the function URL Auth type must be set to "AWS_IAM" ! This part was not described in the AWS documentation. Thanks for your help @Riku_Kobayashi

Here is my policy that works :

{
  "Version": "2012-10-17",
  "Id": "default",
  "Statement": [
    {
      "Sid": "AllowCloudFrontServicePrincipal",
      "Effect": "Allow",
      "Principal": {
        "Service": "cloudfront.amazonaws.com"
      },
      "Action": "lambda:InvokeFunctionUrl",
      "Resource": "arn:aws:lambda:region:accountid:function:myFunction",
      "Condition": {
        "ArnLike": {
          "AWS:SourceArn": "arn:aws:cloudfront::accountid:distribution/distribID"
        }
      }
    }
  ]
}
```
답변함 한 달 전
  • @willysup - I am having similar issues however it only doesn't work when I send a POST with body data to CF to send to the lambda. If you POST with body data does it succesfully send to your lambda?

로그인하지 않았습니다. 로그인해야 답변을 게시할 수 있습니다.

좋은 답변은 질문에 명확하게 답하고 건설적인 피드백을 제공하며 질문자의 전문적인 성장을 장려합니다.

질문 답변하기에 대한 가이드라인

관련 콘텐츠