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 !

asked 14 days ago102 views
2 Answers
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
EXPERT
answered 14 days ago
profile pictureAWS
EXPERT
reviewed 14 days ago
  • 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"
        }
      }
    }
  ]
}
```
answered 14 days ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions