With Lambda functions, you should follow least-privileged access and only allow the access needed to perform a given operation. Attaching a role with more permissions than necessary can open up your systems for abuse.
Limitations on policies
This rule only works with inline policies defined as part of the IAM role resource. It will not check managed policies or policies defined as separate resources.
Resources:MyRole:Type:AWS::IAM::RoleProperties:AssumeRolePolicyDocument:Version:"2012-10-17"Statement:-Effect:AllowPrincipal:Service:-lambda.amazonaws.comAction:-sts:AssumeRole# The rule will check this policyPolicies:-PolicyName:rootPolicyDocument:Version:"2012-10-17"Statement:-Effect:AllowAction:dynamodb:QueryResource:"*"# It will not check this policyMyPolicy:Type:AWS::IAM::PolicyProperties:PolicyDocument:Version:"2012-10-17"Statement:-Effect:AllowAction:dynamodb:*Resource:"*"Roles:-!GetAttMyRole.Arn
resource"aws_iam_role""this"{name="my-function-role"assume_role_policy=data.aws_iam_policy_document.assume.json # The rule will check this policyinline_policy{name="FunctionPolicy"policy=data.aws_iam_policy_document.valid.json}}# It will not check this policyresource"aws_iam_policy""this"{policy=data.aws_iam_policy_document.invalid.json}resource"aws_iam_policy_attachment""this"{roles=[aws_iam_role.this.name]policy_arn=aws_iam_policy.this.arn}data"aws_iam_policy_document""assume"{statement{actions=["sts:AssumeRole"]principals{type="Service"identifiers=["lambda.amazonaws.com"]}}}data"aws_iam_policy_document""valid"{statement{actions=["dynamodb:Query"]resources=["arn:aws:dynamodb:eu-west-1:111122223333:table/my-table"]}}data"aws_iam_policy_document""invalid"{statement{actions=["dynamodb:*"]resources=["*"]}}
If your Lambda function needs a broad range of permissions, you do not know ahead of time which permissions you will need, and you have evaluated the risks of using broad permissions for this function, you might ignore this rule.
import{AttributeType,Table}from'@aws-cdk/aws-dynamodb';import{Code,Function,Runtime}from'@aws-cdk/aws-lambda';exportclassMyStackextendscdk.Stack{constructor(scope:cdk.Construct,id:string,props?:cdk.StackProps){super(scope,id,props);constmyTable=newTable(scope,'MyTable',{partitionKey:{name:'id',type:AttributeType.STRING,}},);constmyFunction=newFunction(scope,'MyFunction',{code:Code.fromAsset('src/hello/'),handler:'main.handler',runtime:Runtime.PYTHON_3_8,});// Grant read access to the DynamoDB tabletable.grantReadData(myFunction);}}
1 2 3 4 5 6 7 8 91011121314151617181920212223
{"Resources":{"MyFunction":{"Type":"AWS::Serverless::Function","Properties":{"CodeUri":".","Runtime":"python3.8","Handler":"main.handler","Policies":[{"Version":"2012-10-17","Statement":[{"Effect":"Allow",// Tightly scoped permissions to just 's3:GetObject'// instead of 's3:*' or '*'"Action":"s3:GetObject","Resource":"arn:aws:s3:::my-bucket/*"}]}]}}}}
1 2 3 4 5 6 7 8 910111213141516
Resources:MyFunction:Type:AWS::Serverless::FunctionProperties:CodeUri:.Runtime:python3.8Handler:main.handlerPolicies:-Version:"2012-10-17"Statement:-Effect:Allow# Tightly scoped permissions to just 's3:GetObject'# instead of 's3:*' or '*'Action:s3:GetObjectResource:"arn:aws:s3:::my-bucket/*"
1 2 3 4 5 6 7 8 9101112131415
provider:name:awsiam:role:name:my-function-rolestatements:-Effect:Allow# Tightly scoped permissions to just 's3:GetObject'# instead of 's3:*' or '*'Action:s3:GetObjectResource:"arn:aws:s3:::my-bucket/*"functions:hello:handler:handler.hello
resource"aws_iam_role""this"{name="my-function-role"assume_role_policy=data.aws_iam_policy_document.assume.jsoninline_policy{name="FunctionPolicy"policy=data.aws_iam_policy_document.this.json}}data"aws_iam_policy_document""assume"{statement{actions=["sts:AssumeRole"]principals{type="Service"identifiers=["lambda.amazonaws.com"]}}}data"aws_iam_policy_document""this"{statement{ # Tightly scoped permissions to just 'dynamodb:Query' # instead of 'dynamodb:*' or '*'actions=["dynamodb:Query"]resources=["arn:aws:dynamodb:eu-west-1:111122223333:table/my-table"]}}resource"aws_lambda_function""this"{function_name="my-function"handler="main.handler"runtime="python3.8"filename="function.zip"role=aws_iam_role.this.arn}