简体   繁体   中英

Minimum Policy requirement for a Lambda function for generating presigned S3 urls

What I am trying to do here is create a lambda function to generate a presigned url for an object in S3 bucket. So the code for the function works as long as it has Full Access to S3. But when I try to restrict that by just adding the GetObject policy, the link shows access denied.

Here is my Lambda function

import boto3
import logging
import os
from botocore.exceptions import ClientError


def lambda_handler(event, context):
    """ Receives the date of the file as an input, and
    creates a presigned url to download the file
    args:
        - date
    returns:
        - response
    """
    bucket = os.environ["BUCKET_NAME"]
    s3_client = boto3.client('s3')
    try:
        response = s3_client.generate_presigned_url(
            'get_object',
            Params={
                'Bucket': bucket,
                'Key': event['object_name']
            },
            ExpiresIn=3600
            )
        return response
    except ClientError as e:
        logging.error(e)
        raise

And here is my template file, for SAM deployment

GetReportFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: !Sub 'getreport-${AWS::StackName}'
      Environment:
        Variables:
          BUCKET_NAME: !Ref LunchOrderBucket
      Runtime: python3.9
      PackageType: Zip
      CodeUri: src/get_report
      Handler: get_report.lambda_handler
      Role: !GetAtt GetReportFunctionRole.Arn
      # Policies:
      #   - S3FullAccessPolicy:
      #       BucketName: !Ref LunchOrderBucket
  
  GetReportFunctionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Action: sts:AssumeRole
            Principal:
              Service: lambda.amazonaws.com
      Policies:
        - PolicyName: GetReportFunctionPolicy
          PolicyDocument: 
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - s3:GetObject
                  - s3:PutObject
                Resource: !GetAtt LunchOrderBucket.Arn

I want to get this working with the least permissions required

What you are missing is the permission for the objects under the bucket. You will need to have the policy to have the /* for all objects under it.

GetReportFunction:
Type: AWS::Serverless::Function
Properties:
  FunctionName: !Sub 'getreport-${AWS::StackName}'
  Environment:
    Variables:
      BUCKET_NAME: !Ref LunchOrderBucket
  Runtime: python3.9
  PackageType: Zip
  CodeUri: src/get_report
  Handler: get_report.lambda_handler
  Role: !GetAtt GetReportFunctionRole.Arn
  # Policies:
  #   - S3FullAccessPolicy:
  #       BucketName: !Ref LunchOrderBucket
  GetReportFunctionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Action: sts:AssumeRole
            Principal:
              Service: lambda.amazonaws.com
      Policies:
        - PolicyName: GetReportFunctionPolicy
          PolicyDocument: 
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - s3:GetObject
                  - s3:PutObject
                Resource:
                  Fn::Join:
                  - ''
                  - - 'arn:aws:s3:::'
                    - Ref: LunchOrderBucket
                    - /*
                

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM