Lambda executions - Security Overview of AWS Lambda

Lambda executions

When Lambda runs a function on your behalf, it manages both provisioning and configuring the underlying systems necessary to run your code. This enables your developers to focus on business logic and writing code, not administering and managing underlying systems.

The Lambda service is split into the control plane and the data plane. Each plane serves a distinct purpose in the service. The control plane provides the management APIs (for example, CreateFunction, UpdateFunctionCode, PublishLayerVersion, and so on), and manages integrations with all AWS services. Communications to the Lambda control plane are protected in-transit by TLS. Customer content stored within Lambda's control plane is encrypted at rest using AWS KMS keys, which are designed to protect the content from unauthorized disclosure or tampering.

The data plane is Lambda's invoke API that cues the invocation of Lambda functions. When a Lambda function is invoked, the data plane allocates an execution environment on an AWS Lambda Worker (or simply worker, a type of Amazon EC2 instance) to that function version, or chooses an existing execution environment that has already been set up for that function version, which it then uses to complete the invocation. For more information, refer to the AWS Lambda MicroVMs and Workers section of this document.

Lambda execution environments

Each invocation is routed by Lambda's invoke service to an execution environment on a Worker that can service the request. Other than through data plane, customers and other users cannot directly initiate inbound/ingress network communications with an execution environment. This helps to ensure that communications to your execution environment are authenticated and authorized.

Execution environments are reserved for a specific function version and cannot be reused across function versions, functions, or AWS accounts. This means a single function which may have two different versions would result in at least two unique execution environments.

Each execution environment may only be used for one concurrent invocation at a time, and they may be reused across multiple invocations of the same function version for performance reasons. Depending on a number of factors (for example, rate of invocation, function configuration, and so on), one or more execution environments may exist for a given function version. With this approach, Lambda is able to provide function version level isolation for its customers.

Lambda does not currently isolate invokes within a function version’s execution environment. What this means is that one invoke may leave a state that may affect the next invoke (for example, files written to /tmp or data in-memory). If you want to ensure that one invoke cannot affect another invoke, we recommend that you create additional distinct functions. For example, you could create distinct functions for complex parsing operations which are more error prone, and re-use functions which do not perform security sensitive operations. Lambda does not currently limit the number of functions that customers can create. For more information about limits, refer to the Lambda quotas page.

Execution environments are continuously monitored and managed by Lambda, and they may be created or destroyed for any number of reasons including, but not limited to:

  • A new invoke arrives and no suitable execution environment exists.

  • An internal runtime or Worker software deployment occurs.

  • A new provisioned concurrency configuration is published.

  • The lease time on the execution environment, or the Worker, is approaching or has exceeded max lifetime.

  • Other internal workload rebalancing processes.

You can manage the number of pre-provisioned execution environments that exist for a function version by configuring provisioned concurrency on their function configuration. When configured to do so, Lambda will create, manage, and ensure the configured number of execution environments always exist. This ensures that you have greater control over start-up performance of their serverless applications at any scale.

Other than through a provisioned concurrency configuration, you cannot deterministically control the number of execution environments that are created or managed by Lambda in response to invocations.

Execution role

Each Lambda function must also be configured with an execution role, which is an IAM role that is assumed by the Lambda service when performing control plane and data plane operations related to the function. The Lambda service assumes this role to fetch temporary security credentials which are then available as environment variables during a function’s invocation. For performance reasons, the Lambda service will cache these credentials, and may re-use them across different execution environments which use the same execution role.

To ensure adherence to least privilege principle, Lambda recommends that each function has its own unique role, and that it is configured with the minimum set of permissions it requires.

The Lambda service may also assume the execution role to perform certain control plane operations such as those related to creating and configuring elastic network interfaces (ENIs) for VPC functions, sending logs to Amazon CloudWatch Application Insights, sending traces to AWS X-Ray, or other non-invoke related operations. You can always review and audit these use cases by reviewing audit logs in AWS CloudTrail.

For more information on this subject, refer to the AWS Lambda execution role documentation.

Lambda MicroVMs and Workers

Lambda will create its execution environments on a fleet of Amazon EC2 instances called AWS Lambda Workers. Workers are bare metal Amazon EC2 AWS Nitro instances which are launched and managed by Lambda in a separate isolated AWS account which is not visible to customers. Workers have one or more hardware-virtualized Micro Virtual Machines (MVM) created by Firecracker. Firecracker is an open-source Virtual Machine Monitor (VMM) that uses Linux’s Kernel-based Virtual Machine (KVM) to create and manage MVMs. It is purpose-built for creating and managing secure, multi-tenant container and function-based services that provide serverless operational models. For more information about Firecracker's security model, refer to the Firecracker project website.

As a part of the shared responsibility model, Lambda is responsible for maintaining the security configuration, controls, and patching level of the Workers. The Lambda team uses Amazon Inspector to discover known potential security issues, as well as other custom security issue notification mechanisms and pre-disclosure lists, so that you don’t need to manage the underlying security posture of their execution environment.

A diagram depicting the isolation model for AWS Lambda Workers.

Isolation model for AWS Lambda Workers

Workers have a maximum lease lifetime of 14 hours. When a Worker approaches maximum lease time, no further invocations are routed to it, MVMs are gracefully terminated, and the underlying Worker instance is terminated. Lambda continuously monitors and alarms on lifecycle activities of its fleet’s lifetime.

All data plane communications to workers are encrypted using Advanced Encryption Standard with Galois/Counter Mode (AES-GCM). Other than through data plane operations, you cannot directly interact with a worker as it hosted in a network isolated Amazon VPC managed by Lambda in the Lambda service accounts.

When a Worker needs to create a new execution environment, it is given time-limited authorization to access customer function artifacts. These artifacts are specifically optimized for Lambda’s execution environment and workers. Function code which is uploaded using the ZIP format is optimized once, and then is stored in an encrypted format using an AWS-managed key and AES-GCM.

Functions uploaded to Lambda using the container image format are also optimized. The container image is first downloaded from its original source, optimized into distinct chunks, and then stored as encrypted chunks using an authenticated convergent encryption method which uses a combination of AES-GCM and SHA-256 MAC. The convergent encryption method allows Lambda to securely deduplicate encrypted chunks. All keys required to decrypt customer content is protected using a customer managed AWS KMS key. If a customer-managed key is not provided, an AWS KMS key owned by the customer and managed by Lambda is used. When a customer-managed KMS key is used, KMS key usage by the Lambda service is available to customers in AWS CloudTrail logs for tracking and auditing.

SnapStart is a performance optimization feature in Lambda to reduce a Java function's startup latency, commonly known as cold start time. With SnapStart, Lambda takes a Firecracker MicroVM snapshot of the initialized execution environment (memory and disk) when you publish a version and persists the encrypted snapshot. Upon concurrency scale-ups, Lambda clones this snapshotted sandbox and resumes the function execution from the pre-initialized state. SnapStart is currently supported with the Java11 runtime. SnapStart isn't supported with provisioned concurrency, arm64 architectureextensionsAmazon Elastic File System (Amazon EFS), and ephemeral storage greater than 512 MB. If your application uses random values, you must evaluate your function code and verify that it is resilient to snapshot operations. For more information, refer to Handling uniqueness with Lambda SnapStart.  If your code deals with network connections, you may need to validate and re-establish them as necessary. You can use a runtime hook to re-establish connections. Network connections established by an AWS SDK are mostly automatically resumed. For other connections, review the Best practices for working with Lambda SnapStart If your function deals with ephemeral data, such as temporary credentials or cached timestamps, during the initialization phase, you can use a runtime hook to refresh temporary data.

If you want to prevent certain data from being stored in a snapshot, use a beforeCheckpoint runtime hook to delete the data before Lambda creates the snapshot. Snapshots are encrypted using a customer-unique AWS KMS key in the customer account managed by Lambda, similarly to the encryption for container images above; however, chunks are not deduplicated in this case. You can also use a customer managed AWS KMS key for control over the key. If a function is not invoked for 14 consecutive days, the snapshot is deleted. All resources associated with the deleted snapshot are removed in compliance with GDPR retention policies.