Lambda functions share an execution role

Separate Lambda execution roles where functions have different permission requirements.

Description

When functions with different permission requirements use the same execution role, permissions needed by one function can also reach the others. The execution role supplies permissions that function code uses to access AWS services.

Sharing a role between functions with the same work and trust boundary does not automatically mean excessive access. Review attached policies and actual access, not just role names.

Potential impact

  • Exploitation of one function’s code or input can expose data or operations that the function does not need.
  • Changing a shared role can affect the other functions that use it.

Remediation

  • Identify required APIs and resources for each function. Separate execution roles where permissions or trust boundaries differ.
  • Grant each role only necessary permissions and configure its trust policy for the Lambda service. Review total permissions when reusing common policies.
  • Verify function execution, logging and required service calls after the change.

Examples

These examples compare the roles attached to two functions. Replace the ARNs with existing roles that trust Lambda. The fixed-response code is illustrative; a real application also needs permissions for its own operations.

Before

yaml
Resources:
  Primer01:
    Type: AWS::Lambda::Function
    Properties:
      Runtime: nodejs22.x
      Role: arn:aws:iam::123456789012:role/lambda-role
      Handler: index.handler
      Code:
        ZipFile: |
          exports.handler = async () => ({ statusCode: 200, body: "ok" });

  Primer02:
    Type: AWS::Lambda::Function
    Properties:
      Runtime: nodejs22.x
      Role: arn:aws:iam::123456789012:role/lambda-role
      Handler: index.handler
      Code:
        ZipFile: |
          exports.handler = async () => ({ statusCode: 200, body: "ok" });

Both functions use the same role and therefore share its granted permissions.

After

yaml
Resources:
  Primer01:
    Type: AWS::Lambda::Function
    Properties:
      Runtime: nodejs22.x
      Role: arn:aws:iam::123456789012:role/lambda-role-primer01
      Handler: index.handler
      Code:
        ZipFile: |
          exports.handler = async () => ({ statusCode: 200, body: "ok" });

  Primer02:
    Type: AWS::Lambda::Function
    Properties:
      Runtime: nodejs22.x
      Role: arn:aws:iam::123456789012:role/lambda-role-primer02
      Handler: index.handler
      Code:
        ZipFile: |
          exports.handler = async () => ({ statusCode: 200, body: "ok" });

The functions use separate roles. Their policies must also follow least privilege for the separation to limit access.

References