AWS SAM Resource Policies: The Ultimate Security Deep Dive

Published: June 22, 2025 | Author: Serverless Security Team

Download Full Guide

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

  1. Overly Permissive Principal: “*” – Avoid unless absolutely necessary
  2. Missing Condition Clauses – Always restrict by IP, VPC, or ARN
  3. Conflicting Allow/Deny Rules – Deny rules override Allow rules
  4. Forgetting Cross-Account Implications – Explicitly define cross-account access
  5. 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:

Download Full Guide