Glossary

    Lambda Security

    Compute & Serverless

    Lambda Security covers the practices and configurations needed to run serverless functions securely. Each Lambda function has an execution role that defines what AWS services and resources the function can access.

    Key Security Controls

    • Execution Role: apply least-privilege IAM policies; never use AdministratorAccess
    • Resource-based Policy: controls who or what can invoke the function
    • Function URL Authentication: use AWS_IAM auth type, not NONE (which allows public, unauthenticated access)
    • VPC Placement: place functions in a VPC to access private resources; requires ENI permissions
    • Code Signing: ensures only trusted code packages are deployed
    • Environment Variables: encrypt sensitive values with KMS; never store secrets in plaintext
    • Reserved Concurrency: prevents a single function from consuming all account concurrency

    Common Risks

    • Overly permissive execution roles (for example s3:* instead of s3:GetObject on a specific bucket)
    • Public function URLs without authentication
    • Secrets hardcoded in environment variables without encryption
    • Event injection through untrusted event sources

    Function URL Auth, in Detail

    Access to a function URL is determined by two things together: the AuthType parameter and the function's resource-based policy. With AWS_IAM, Lambda authenticates and authorizes the caller using the principal's identity policy and the function's resource-based policy. With NONE, Lambda performs no authentication at all, but the resource-based policy is still in effect and must grant public access before requests are accepted. That is why a function URL with auth type NONE and no matching policy statement returns 403 Forbidden.

    Two details worth internalizing. First, starting in October 2025, new function URLs require both lambda:InvokeFunctionUrl and lambda:InvokeFunction permissions, so older single-action policy examples are incomplete. Second, when you create a NONE function URL through the console or SAM, Lambda writes the public resource-based policy for you automatically; through the CLI, CloudFormation, or the API you must add it yourself. Deleting a NONE function URL does not remove that policy, so an old public grant can linger on a function long after the URL is gone.

    How It Goes Wrong in Practice

    The pattern I see repeatedly: a team enables a function URL with auth type NONE during development because signing requests with SigV4 from a browser or a curl test is annoying. The function is a small internal utility, so nobody thinks of it as an endpoint. Then the function's execution role is widened over time to read a DynamoDB table, then to write to S3, then to call Secrets Manager. What started as a throwaway is now an unauthenticated internet endpoint executing with meaningful permissions, and the URL is discoverable because it was pasted into a ticket, a README, or a client-side bundle. Anyone who has the URL can invoke the function.

    The second recurring problem is confusing environment variable encryption with secrecy. Lambda encrypts environment variables at rest by default, but the plaintext values are visible to anyone who can call lambda:GetFunctionConfiguration, and they are visible to the function code and anything that can read the process environment. A database password in an environment variable is readable by every principal with function read permissions in the account. Use Secrets Manager or SSM Parameter Store and fetch at runtime, or at minimum use a customer managed KMS key with encryption helpers so that reading the configuration does not reveal the value.

    Third, event injection. A Lambda triggered by S3, SQS, or API Gateway receives an event object built from data an outsider may control: object keys, message bodies, query strings, headers. Treating those fields as trusted input leads to the same classes of bugs as any other web application, including command injection and SSRF, except the credentials at risk are the execution role's.

    Checking Function URL Auth and Policy From the CLI

    To see whether a function has a URL and how it authenticates:

    aws lambda get-function-url-config --function-name my-function

    --function-name is required and --qualifier is optional for an alias. The output includes FunctionUrl, FunctionArn, AuthType (NONE or AWS_IAM), Cors, InvokeMode, and timestamps. Anything reporting NONE deserves a written justification.

    To read the resource-based policy that actually decides who can invoke:

    aws lambda get-policy --function-name my-function

    The output is the policy document plus a RevisionId. Look for "Principal": "*" statements, and for statements conditioned on lambda:FunctionUrlAuthType equal to NONE. To block this class of mistake organization-wide, use an SCP that denies lambda:CreateFunctionUrlConfig and lambda:UpdateFunctionUrlConfig when lambda:FunctionUrlAuthType is not AWS_IAM.

    Frequently Asked Questions

    Does putting a Lambda function in a VPC make it more secure?

    It changes what the function can reach on the network, not who can invoke it. VPC placement lets a function talk to private resources and lets you apply security groups to its egress, which is genuinely useful for controlling outbound traffic. It does nothing about the invocation path, which is governed by the resource-based policy and the trigger configuration.

    What is the difference between the execution role and the resource-based policy?

    The execution role is what the function can do once it runs. The resource-based policy is who can make it run. They are independent, and both need to be tight: a narrow invoke policy with an admin execution role is still dangerous, and so is the reverse.

    How do I make a function URL private but still callable from a browser?

    Use AWS_IAM and put the function behind something that can sign requests or authenticate users, such as CloudFront with an origin access setup, API Gateway with a Cognito or Lambda authorizer, or an application that signs SigV4 server-side. Use the lambda:InvokedViaFunctionUrl condition key so the grant applies only to function URL calls and not to direct invocations.

    Related AWS Services

    Toc Consulting: AWS Security & Cloud Architecture

    Securing your AWS estate?

    Our team helps engineering teams secure and architect AWS the right way: assessment in week one, a prioritized action plan in week two.