Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OAC should be enabled when using lambda streaming #4684

Open
ravenscar opened this issue May 1, 2024 · 12 comments
Open

OAC should be enabled when using lambda streaming #4684

ravenscar opened this issue May 1, 2024 · 12 comments
Assignees

Comments

@ravenscar
Copy link
Contributor

When using a Nextjs site if you enable streaming then the lambdas get publicly accessible URLs for use as origins for the CloudFront distribution.

If you have WAF enabled in your CF you may want to prevent the lambda URLs from being invoked directly via the public url, e.g. not via CF. AWS now supports OAC for lambdas and I think it would be secure to have this enabled by default in this case.

https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-lambda.html

@JohnnyCrazy
Copy link

Hey,

Is this currently being worked on? If not, I would like to try implementing this. Couple of questions I had: Should this be controlled by a parameter? Should it default to enabling oac?

@cgcompassion
Copy link

cgcompassion commented Jul 26, 2024

Aaaaalright, I think I finally got this mostly working. Here's my code.

UPDATE: Include ImageFunction thanks to @srobroek .

    const oac = new aws.cloudfront.OriginAccessControl('MyOAC', {
      name: 'My OAC',
      description: 'NextJS OAC for lambdas',
      originAccessControlOriginType: 'lambda',
      signingBehavior: 'always',
      signingProtocol: 'sigv4',
    });

    const appName = 'MySite';
    const app = new sst.aws.Nextjs(appName, {
      transform: {
        server: {
          url: {
            authorization: 'iam',
          },
        },
        imageOptimization: {
          url: {
            authorization: 'iam',
          },
        },
        cdn(args) {
          args.origins = [...args.origins].map((origin) => {
            if (origin.originId !== 's3') {
              return { ...origin, originAccessControlId: oac.id };
            }
            return origin;
          });
        },
      },
    });

    new aws.lambda.Permission('OACPermissionServer', {
      action: 'lambda:InvokeFunctionUrl',
      principal: 'cloudfront.amazonaws.com',
      function: app.nodes.server?.nodes.function,
      functionUrlAuthType: 'AWS_IAM',
      sourceArn: app.nodes.cdn?.nodes.distribution.arn,
    });

    // Hacky workaround because the nodes output contains server lambda but not imageOptimizer.
    const imageOptimizationFunctionName = `${$app.name}-${$app.stage}-${appName}ImageOptimizerFunction`;
    new aws.lambda.Permission('OACPermissionImage', {
      action: 'lambda:InvokeFunctionUrl',
      principal: 'cloudfront.amazonaws.com',
      function: imageOptimizationFunctionName,
      functionUrlAuthType: 'AWS_IAM',
      sourceArn: app.nodes.cdn?.nodes.distribution.arn,
    });

NOTES:

@woodsjd-cr
Copy link

Any update on this? This would be a great feature!

@jayair
Copy link
Contributor

jayair commented Aug 21, 2024

I know we did this recently #4373

@cgcompassion
Copy link

I might be missing it, but I don't see anything in that PR about the NextJS lambdas (server and imageOptimization).

@jayair
Copy link
Contributor

jayair commented Aug 22, 2024

Yeah it was for the distribution I think.

@srobroek
Copy link

srobroek commented Aug 26, 2024

@cgcompassion

Extremely hacky workaround for the imageOptimization nodes not being available, but since the naming convention is predictable and pulumi expects a function name, you can do the following until this has been addressed.

const frontendName = "frontend"
const imageOptimizationFunctionName = `${$app.name}-${$app.stage}-${frontendName}ImageOptimizerFunction`
export const frontend = new sst.aws.Nextjs(frontendName, {
...
}

new aws.lambda.Permission('OACPermission2', {
    action: 'lambda:InvokeFunctionUrl',
    principal: 'cloudfront.amazonaws.com',
    function: imageOptimizationFunctionName,
    functionUrlAuthType: 'AWS_IAM',
    sourceArn: frontend.nodes.cdn?.nodes.distribution.arn,
});

Confirmed working for separate stage names and frontend names, did not validate for separate apps but i don't see why this wouldn't work.

@yuta-hidaka
Copy link

@srobroek @cgcompassion

Hello!
Do you know if the code works for the current SST version?

I've tried those codes in my environment and I've got an error like IllegalOriginAccessConfiguration: Illegal configuration: The origin type and OAC origin type differ.

@cgcompassion
Copy link

Probably not, the code base is changing so rapidly (good thing). I'm hoping to get back to this one in the next couple of weeks and I'll try to adjust this to match the latest OAC work that has been merged.

@cgcompassion
Copy link

@srobroek @cgcompassion

Hello! Do you know if the code works for the current SST version?

I've tried those codes in my environment and I've got an error like IllegalOriginAccessConfiguration: Illegal configuration: The origin type and OAC origin type differ.

@yuta-hidaka I just tried again, and the code snippet I posted still applies, and works for me with latest version of SST. Based on the error message, I suggest looking at the part in the transform where I apply the OAC to all origins except S3 (The S3 origin already has it's own OAC, we want to apply ours to the two lambdas only). Take a look at your origin list on AWS for this distribution and you should see three origins. One S3 bucket and two lambdas. There's a column called "Origin access" which is what we want to not be empty... Let me know if you still can't get it working.

@cgcompassion
Copy link

cgcompassion commented Oct 4, 2024

@jayair It's very cool that the S3 bucket now has OAC, but would love it if we could apply OAC to the lambdas as well by default. See: https://aws.amazon.com/blogs/networking-and-content-delivery/secure-your-lambda-function-urls-using-amazon-cloudfront-origin-access-control/

@jayair
Copy link
Contributor

jayair commented Oct 4, 2024

cc @fwang

@thdxr thdxr transferred this issue from sst/ion Oct 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants