AWS SAM Resource Policies: The Ultimate Security Deep Dive
Published: June 22, 2025 | Author: Serverless Security Team
What Are AWS SAM Resource Policies?
Resource policies in AWS SAM (Serverless Application Model) are security rules that control who can access your serverless components and what actions they can perform. Think of them as bouncers for your serverless functions and APIs – they decide who gets in and what they’re allowed to do.
Explaining to a 6-Year-Old
Imagine your AWS resources are toys in your room. Resource policies are like the rules you make about who can play with which toys:
- “My sister can play with the LEGOs but can’t touch my robot”
- “Mom can come in anytime to clean up”
- “Nobody can open my treasure box except me”
Resource Policy vs. Execution Role
While execution roles define what your Lambda function can do, resource policies define who can invoke or access it:
MyLambdaFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: lambda/
Handler: app.handler
Policies: # Execution Role (what Lambda CAN DO)
- S3ReadPolicy:
BucketName: my-data-bucket
ResourcePolicy: # Resource Policy (who can INVOKE Lambda)
Statement:
- Effect: Allow
Principal: '*'
Action: lambda:InvokeFunction
Condition:
ArnLike:
aws:SourceArn: arn:aws:execute-api:us-east-1:123456789012:abc123/*
Why Resource Policies Are Essential for Security
Without proper resource policies, your serverless applications are vulnerable to:
- Unauthorized API access
- Accidental public exposure of functions
- Data breaches through over-permissive access
- Denial-of-wallet attacks (malicious overuse)
Security Best Practice
Always follow the principle of least privilege: Grant only the minimum permissions required for specific entities to perform necessary actions.
Implementing Resource Policies in SAM Templates
1. API Gateway Resource Policy
Control access to your REST APIs:
MyApi:
Type: AWS::Serverless::Api
Properties:
StageName: Prod
ResourcePolicy:
Version: "2012-10-17"
Statement:
- Effect: Deny
Principal: "*"
Action: execute-api:Invoke
Resource: execute-api:/*/*/*
Condition:
NotIpAddress:
aws:SourceIp:
- 203.0.113.0/24
- 198.51.100.0/24
- Effect: Allow
Principal: "*"
Action: execute-api:Invoke
Resource: execute-api:/*/*/GET/public
2. Lambda Function Policy
Restrict function invocation sources:
MyLambda:
Type: AWS::Serverless::Function
Properties:
...
ResourcePolicy:
Statement:
- Effect: Allow
Principal: apigateway.amazonaws.com
Action: lambda:InvokeFunction
Resource: !Sub arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:${self:MyFunction}
Condition:
ArnLike:
aws:SourceArn: !Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${MyApi}/*
3. S3 Bucket Policy
Secure your storage buckets:
MySecureBucket:
Type: AWS::S3::Bucket
Properties:
BucketPolicy:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
AWS: !GetAtt MyLambdaRole.Arn
Action: s3:GetObject
Resource: !Sub arn:aws:s3:::${MySecureBucket}/*
Real-World Security Scenarios
Scenario 1: VPC-Only Access
Restrict API access to your corporate network:
ResourcePolicy:
Statement:
- Effect: Allow
Principal: "*"
Action: execute-api:Invoke
Resource: execute-api:/*/*/*
Condition:
StringEquals:
aws:SourceVpc: vpc-12345678
Scenario 2: Cross-Account Access
Grant access to resources in another AWS account:
ResourcePolicy:
Statement:
- Effect: Allow
Principal:
AWS: arn:aws:iam::123456789012:root
Action: lambda:InvokeFunction
Resource: !Sub arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:${self:MyFunction}
Pro Tip: Use SAM Policy Templates
Leverage built-in templates for common security patterns:
Policies:
- LambdaInvokePolicy:
FunctionName: !Ref MyFunction
- SQSPollerPolicy:
QueueName: !GetAtt MyQueue.QueueName
Common Mistakes to Avoid
- Overly Permissive Principal: “*” – Avoid unless absolutely necessary
- Missing Condition Clauses – Always restrict by IP, VPC, or ARN
- Conflicting Allow/Deny Rules – Deny rules override Allow rules
- Forgetting Cross-Account Implications – Explicitly define cross-account access
- Ignoring Policy Length Limits – Maximum 20KB per resource policy
Security Audit Checklist
- ✅ Used specific principals instead of wildcards
- ✅ Added IP/VPC restrictions where applicable
- ✅ Tested policy with AWS Policy Simulator
- ✅ Verified resource policy + execution role alignment
- ✅ Set up CloudTrail for access monitoring
Best Practices for Production
- Automate Policy Validation – Integrate cfn-nag or AWS Config rules
- Version Control Policies – Track changes in Git history
- Use Least Privilege Templates:
# Least privilege S3 access template S3ReadPolicy: BucketName: !Ref MyDataBucket AllowGet: true AllowList: true AllowDelete: false
- Monitor with CloudWatch – Set alerts for policy changes
- Regular Policy Audits – Quarterly security reviews
Advanced Techniques
Dynamic Policy Generation
Use SAM macros for environment-specific policies:
Transform: AWS::Serverless-2016-10-31
Globals:
Function:
ResourcePolicy:
Statement:
- Effect: Allow
Principal: apigateway.amazonaws.com
Action: lambda:InvokeFunction
Resource: !Sub arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:*
Condition:
ArnLike:
aws:SourceArn: !Sub
- arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${ApiId}/*
- ApiId: !Ref MyApi
Policy Variables
Leverage AWS-specific variables for context-aware policies:
Condition:
StringEquals:
aws:PrincipalOrgID: o-1234567890
aws:PrincipalTag/Department: Engineering
Conclusion & Next Steps
Mastering AWS SAM resource policies is crucial for building secure serverless architectures. Remember:
- Resource policies control access to resources
- Execution roles control resource actions
- Always follow the least privilege principle
- Regularly audit and test your policies
Continue your learning with these resources: