- Knowledge Base
- Amazon Web Services
- AWS Lambda
- Lambda Functions Should not Share Roles that Contain Admin Privileges
Ensure that your Amazon Lambda functions do not share execution roles that contain admin privileges in order to promote the Principle of Least Privilege (POLP) and provide your functions the minimal amount of access required to perform their tasks. Sharing admin roles between Lambda functions poses a security risk because it grants excessive permissions, increasing the potential for misuse or accidental actions that can affect your AWS cloud environment.
This rule can help you work with the AWS Well-Architected Framework.
The permissions assumed by an Amazon Lambda function are determined by the execution role associated with the function. Sharing an admin role with other Lambda functions can lead to serious security vulnerabilities, as a malicious actor who gains access to one function could exploit its privileges to compromise other AWS resources, including sensitive data or essential services. To mitigate this risk, it is crucial to assign least privilege roles that grant Lambda functions only the permissions necessary to perform their tasks. By using the right IAM role, you can control these privileges and avoid providing full or generic access, ensuring more secure and focused permission management.
Audit
To identify Amazon Lambda functions that share execution roles which contain admin privileges, perform the following operations:
Using AWS Console
01 Sign in to the AWS Management Console.
02 Navigate to Lambda console available at https://console.aws.amazon.com/lambda/.
03 In the left navigation panel, choose Functions to access the Amazon Lambda functions available within the current AWS region.
04 Click on the name (link) of the Lambda function that you want to examine.
05 Select the Configuration tab and choose Permissions from the left menu.
06 Take note of the Role name attribute value, listed in the Execution role section. The execution role is an IAM role that defines the access permissions for the selected function.
07 Go back to the Functions listing page and repeat steps no. 4 – 6 for all the Lambda functions available within the selected AWS region. If two or more Amazon Lambda functions share the same execution role, the permissions configuration available for your Lambda functions violates the Principle of Least Privilege (POLP).
08 Navigate to Identity and Access Management (IAM) console available at https://console.aws.amazon.com/iam/.
09 In the left navigation panel, under Access management, choose Roles.
10 Type the name of the IAM role shared between your Amazon Lambda functions in the Search box and press Enter.
11 Click on the name (link) of the resulted IAM role and select the Permissions tab to access the identity–based policies attached to the role.
12 In the Permissions policies section, click on the Expand button (plus icon) located next to the policy name, to display the policy document in JSON format.
13 For each IAM policy document, identify the "Action" element value in each policy statement. If the "Action" value is set to "*" and the "Effect" value is set to "Allow", the role policy provides access to all the supported AWS services and resources (i.e. administrative permissions). Therefore, your Amazon Lambda functions share an execution role that contains admin privileges.
14 Change the AWS cloud region from the console navigation bar and repeat the Audit process for other regions.
Using AWS CLI
01 Run list-functions command (OSX/Linux/UNIX) to list the name of each Amazon Lambda function available in the selected AWS cloud region:
aws lambda list-functions --region us-east-1 --output table --query 'Functions[*].FunctionName'
02 The command output should return a table with the requested function name(s):
-------------------------- | ListFunctions | +------------------------+ | cc-process-app-queue | | cc-export-user-data | | cc-get-ec2-log-data | +------------------------+
03 Run get-function command (OSX/Linux/UNIX) with the name of the Lambda function that you want to examine as the identifier parameter, to describe the Amazon Resource Name (ARN) of the IAM role that Amazon Lambda assumes when it executes the selected function (i.e. the function's execution role):
aws lambda get-function --region us-east-1 --function-name cc-process-app-queue --query 'Configuration.Role'
04 The command output should return the ARN of the IAM role (execution role) associated with the selected Lambda function. The Amazon Resource Name (ARN) also includes the role name, i.e. "arn:aws:iam::\
"arn:aws:iam::123456789012:role/cc-app-function-execution-role"
05 Repeat steps no. 3 and 4 for all the functions deployed in the selected AWS region and compare the role ARNs. If two or more Lambda functions share the same execution role, the permissions configuration available for your Amazon Lambda functions violates the Principle of Least Privilege (POLP).
06 Run list-attached-role-policies command (OSX/Linux/UNIX) with the name of the IAM role shared between your Lambda functions as the identifier parameter, to list the Amazon Resource Name (ARN) of each managed policy attached to the selected role:
aws iam list-attached-role-policies --role-name cc-app-function-execution-role --query 'AttachedPolicies[*].PolicyArn'
07 The command output should return the ARN of each managed policy attached to the selected role:
[ "arn:aws:iam::123456789012:policy/cc-lambda-managed-policy" ]
08 Run get-policy-version command (OSX/Linux/UNIX) with the ARN of the managed policy returned at the previous step as the identifier parameter, to describe the policy document (JSON format) defined for the selected policy version:
aws iam get-policy-version --policy-arn arn:aws:iam::123456789012:policy/cc-lambda-managed-policy --version-id v1 --query 'PolicyVersion.Document'
09 The command output should return the requested IAM policy document:
{ "Version": "2012-10-17", "Statement": [ { "Action": "*", "Resource": "*", "Effect": "Allow" } ] }
Identify the "Action" element value in each policy statement. If the "Action" value is set to "*" and the Effect value is set to "Allow", as shown in the example above, the role policy provides access to all the supported AWS services and resources (i.e. administrative permissions). Therefore, your Amazon Lambda functions share an execution role that contains admin privileges.
10 Run list-role-policies command (OSX/Linux/UNIX) with the name of the IAM role shared between your Lambda functions as the identifier parameter, to describe the name of each inline policy attached to the selected role:
aws iam list-role-policies --role-name cc-app-function-execution-role --query 'PolicyNames'
11 The command output should return the name of each inline policy associated with the selected role:
[ "cc-lambda-inline-policy" ]
12 Run get-role-policy command (OSX/Linux/UNIX) with the name of the inline policy returned at the previous step as the identifier parameter, to describe the policy document defined for the selected inline policy:
aws iam get-role-policy --role-name cc-app-function-execution-role --policy-name cc-lambda-inline-policy --query 'PolicyDocument'
13 The command output should return the requested inline policy document:
{ "Version": "2012-10-17", "Statement": [ { "Action": [ "*" ], "Resource": [ "*" ], "Effect": "Allow", "Sid": "FullAccess" } ] }
Identify the "Action" element value in each policy statement. If the "Action" value is set to "*" and the Effect value is set to "Allow", as shown in the output example above, the role policy provides access to all the supported AWS services and resources. Therefore, your Amazon Lambda functions share an execution role that contains admin privileges.
14 Change the AWS cloud region by updating the --region command parameter value and repeat steps no. 1 – 13 to perform the Audit process for other AWS regions.
Remediation / Resolution
To implement the Principle of Least Privilege (POLP) and create a separate execution role for each individual Amazon Lambda function, using the right set of permissions instead of full admin permissions, perform the following operations:
Using AWS CloudFormation
01 CloudFormation template (JSON):
{ "AWSTemplateFormatVersion": "2010-09-09", "Resources": { "FunctionExecutionRole": { "Type": "AWS::IAM::Role", "Properties": { "RoleName": "LambdaExecutionRole", "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": [ "lambda.amazonaws.com" ] }, "Action": [ "sts:AssumeRole" ] } ] }, "Path": "/", "ManagedPolicyArns": [ "arn:aws:iam::aws:policy/AdministratorAccess" "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" "arn:aws:iam::aws:policy/service-role/AWSXRayDaemonWriteAccess" ] } }, "LambdaFunction": { "Type": "AWS::Lambda::Function", "Properties": { "FunctionName": "cc-app-worker-function", "Handler": "lambda_function.lambda_handler", "Role": { "Fn::GetAtt": [ "FunctionExecutionRole", "Arn" ] }, "Code": { "S3Bucket": "cc-lambda-functions", "S3Key": "worker.zip" }, "Runtime": "python3.9", "MemorySize": 1024, "Timeout": 45, "VpcConfig": { "SecurityGroupIds": [ "sg-0abcd1234abcd1234" ], "SubnetIds": [ "subnet-abcd1234", "subnet-1234abcd" ] } } } } }
02 CloudFormation template (YAML):
AWSTemplateFormatVersion: '2010-09-09' Resources: FunctionExecutionRole: Type: AWS::IAM::Role Properties: RoleName: LambdaExecutionRole AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Path: / ManagedPolicyArns: - arn:aws:iam::aws:policy/AdministratorAccess - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole - arn:aws:iam::aws:policy/service-role/AWSXRayDaemonWriteAccess LambdaFunction: Type: AWS::Lambda::Function Properties: FunctionName: cc-app-worker-function Handler: lambda_function.lambda_handler Code: S3Bucket: cc-lambda-functions S3Key: worker.zip Runtime: python3.9 MemorySize: 1024 Timeout: 45 VpcConfig: SecurityGroupIds: - sg-0abcd1234abcd1234 SubnetIds: - subnet-abcd1234 - subnet-1234abcd Role: !GetAtt 'FunctionExecutionRole.Arn'
Using Terraform (AWS Provider)
01 Terraform configuration file (.tf):
terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 4.0" } } required_version = ">= 0.14.9" } provider "aws" { profile = "default" region = "us-east-1" } resource "aws_iam_role" "lambda-execution-role" { name = "LambdaExecutionRole" path = "/" assume_role_policy = <<EOF { "Version": "2012-10-17", "Statement": [ { "Action": "sts:AssumeRole", "Principal": { "Service": "lambda.amazonaws.com" }, "Effect": "Allow" } ] } EOF managed_policy_arns = ["arn:aws:iam::aws:policy/AdministratorAccess"] managed_policy_arns = ["arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"] managed_policy_arns = ["arn:aws:iam::aws:policy/service-role/AWSXRayDaemonWriteAccess"] } resource "aws_lambda_function" "lambda-function" { function_name = "cc-app-worker-function" s3_bucket = "cc-lambda-functions" s3_key = "worker.zip" handler = "lambda_function.lambda_handler" runtime = "python3.9" memory_size = 1024 timeout = 45 vpc_config { subnet_ids = [ "subnet-01234abcd1234abcd", "subnet-0abcd1234abcd1234" ] security_group_ids = [ "sg-0abcd1234abcd1234" ] } role = aws_iam_role.lambda-execution-role.arn }
Using AWS Console
01 Sign in to the AWS Management Console.
02 Navigate to Lambda console available at https://console.aws.amazon.com/lambda/.
03 In the left navigation panel, choose Functions to access the Amazon Lambda functions available within the current AWS region.
04 Click on the name (link) of the Lambda function that you want to configure.
05 Select the Configuration tab and choose Permissions from the left menu.
06 In the Execution role section, choose Edit to change the execution role that defines the permissions for the selected function.
07 In the Basic settings section, perform the following actions to replace the function execution role that grants excessive admin privileges and is shared with other Lambda functions, with a new role that follows the Principle of Least Privilege (POLP) and provides only the necessary permissions for the function's operation:
- For Execution role, choose Create a new role from AWS policy templates, provide a unique name for the new role in the Role name box, and select one or more policy templates from the Policy templates - optional dropdown list. This will create a new, dedicated execution role for your Amazon Lambda function. If you already have a compliant execution role for the selected function, choose Use an existing role for Execution role, and select the IAM role from the Existing role dropdown list.
- Choose Save to apply the configuration changes.
08 Repeat steps no. 4 – 7 to change the permissions for each Amazon Lambda function with admin privileges that shares the execution role with other functions, available within the current AWS region.
09 Change the AWS cloud region from the console navigation bar and repeat the Remediation process for other regions.
Using AWS CLI
01 Create the trust relationship policy required for the execution role. This trust policy allows Amazon Lambda to use the role's permissions by giving the service principal "lambda.amazonaws.com" permission to call the AWS Security Token Service "AssumeRole" action. To create the required trust policy for the new IAM role, save the following policy document to a JSON file named cc-execution-role-trust-policy.json:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "lambda.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
02 Run create-role command (OSX/Linux/UNIX) to create a new Amazon IAM role using the trust relationship policy defined at the previous step:
aws iam create-role --role-name cc-new-app-function-role --assume-role-policy-document file://cc-execution-role-trust-policy.json.json
03 The command output should return the information available for the new IAM role:
{ "Role": { "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { "Service": "lambda.amazonaws.com" } } ] }, "RoleId": "AAAABBBBCCCCDDDDEEEEF", "CreateDate": "2024-10-22T10:00:00Z ", "RoleName": "cc-new-app-function-role", "Path": "/", "Arn": "arn:aws:iam::123456789012:role/cc-new-app-function-role" } }
04 The following AWS-managed policies provide permissions that are required to use Amazon Lambda features (see the official documentation for the updated list of managed policies):
- "AWSLambdaBasicExecutionRole" – permission to upload logs to Amazon CloudWatch Logs.
- "AWSLambdaDynamoDBExecutionRole" – permission to read records from an Amazon DynamoDB stream.
- "AWSLambdaKinesisExecutionRole" – permission to read events from an Amazon Kinesis data stream or consumer.
- "AmazonS3ObjectLambdaExecutionRolePolicy" – permission to interact with Amazon S3 object Lambda and to write to CloudWatch Logs.
- "AWSLambdaMSKExecutionRole" – permission to read records from an Amazon Managed Streaming for Apache Kafka (Amazon MSK) cluster.
- "AWSLambdaSQSQueueExecutionRole" – permission to read a message from an Amazon Simple Queue Service (Amazon SQS) queue.
- "AWSLambdaVPCAccessExecutionRole" – permission to manage elastic network interfaces to connect your function to a virtual private cloud (VPC).
- "AWSXRayDaemonWriteAccess" – permission to upload trace data to X-Ray.
- "CloudWatchLambdaInsightsExecutionRolePolicy" – permission to write runtime metrics to CloudWatch Lambda Insights.
05 Run attach-role-policy command (OSX/Linux/UNIX) to attach an AWS-managed policy to the newly created IAM role (execution role). Based on your function's access requirements, choose the appropriate policy from the list of managed policies described at the previous step. The new role must follow the Principle of Least Privilege (POLP) and provides only the necessary permissions for the function's operation. As an example, the policy attached to the new IAM role is "AWSLambdaSQSQueueExecutionRole", a managed policy which provides permissions to read messages from an Amazon SQS queue (the command does not produce an output):
aws iam attach-role-policy --role-name cc-new-app-function-role --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaSQSQueueExecutionRole
06 Run update-function-configuration command (OSX/Linux/UNIX) with the name of the Amazon Lambda function that you want to configure as the identifier parameter, to replace the function execution role that grants excessive admin privileges and is shared with other Lambda functions, with the new, compliant role created and configured at the previous steps:
aws lambda update-function-configuration --region us-east-1 --function-name cc-process-app-queue --role arn:aws:iam::123456789012:role/cc-new-app-function-role
07 The command output should return the information available for the configured function:
{ "LastUpdateStatus": "Successful", "FunctionName": "cc-process-app-queue", "LastModified": "2024-10-22T11:00:00.000+0000", "RevisionId": "abcdabcd-1234-abcd-1234-abcd1234abcd", "MemorySize": 128, "State": "Active", "Version": "$LATEST", "Role": "arn:aws:iam::123456789012:role/cc-new-app-function-role", "Timeout": 45, "Runtime": "nodejs12.x", "TracingConfig": { "Mode": "PassThrough" }, "CodeSha256": "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcd", "Description": "", "CodeSize": 403, "FunctionArn": "arn:aws:lambda:us-east-1:123456789012:function:cc-process-app-queue", "Handler": "index.handler" }
08 Repeat steps no. 1 – 7 to change the permissions for each Amazon Lambda function with admin privileges that shares the execution role with other functions, available in the selected AWS region.
09 Change the AWS cloud region by updating the --region command parameter value and repeat the Remediation process for other AWS regions.
References
- AWS Documentation
- AWS Lambda FAQs
- Create your first Lambda function
- Managing permissions in AWS Lambda
- Defining Lambda function permissions with an execution role
- Working with AWS managed policies in the execution role
- Working with resource-based IAM policies in Lambda
- AWS Command Line Interface (CLI) Documentation
- list-functions
- get-function
- list-attached-role-policies
- get-policy-version
- list-role-policies
- get-role-policy
- create-role
- attach-role-policy
- update-function-configuration
Related Lambda rules
- Enable and Configure Reserved Concurrency (Security, reliability, operational-excellence, cost-optimisation, sustainability)
- Enable Enhanced Monitoring for Lambda Functions (Security)
- Lambda Using Latest Runtime Environment (Security, reliability, sustainability)
- Function in Private Subnet (Security)
Unlock the Remediation Steps
Free 30-day Trial
Automatically audit your configurations with Conformity
and gain access to our cloud security platform.
You are auditing:
Lambda Functions Should not Share Roles that Contain Admin Privileges
Risk Level: High