AWS getSignedUrl using Lambda function's Role policy, instead of provided credentials

0

Inside a lambda function, I am trying to generate a presigned url to an s3 object. I am using getSignedUrl from @aws-sdk/s3-request-presigner. The code snippet to generate the URL is as follows:

const s3Client=new S3Client({
                region:region,
                Credentials:{
                    accessKeyId:accessKey, //Temporary Access key from Cognito Identity Pool
                    secretAccessKey:secretKey //Temporary Secret from Cognito Identity pool
                }
              });

              const bucketName=process.env.ASSET_STORE;
              const objectKey=`${requestAssetId}/${requestAssetId}.${requestAssetIdExtension}`;
              const command = new GetObjectCommand({
                Bucket: bucketName,
                Key: objectKey,
                ExpiresIn: 60
              });

              const presignedURL=await getSignedUrl(s3Client,command,{ expiresIn: 60 });

The temporary credentials are generated by the following code snippet:

const getCredentialsCommand = new GetCredentialsForIdentityCommand({
                IdentityId: identityId,
                Logins: {
                    // Use the Cognito User Pool token as the login provider
                    'cognito-idp.<Region>.amazonaws.com/<Pool Id>': idTokenReceived
                  },
                  CustomRoleArn:'arn:aws:iam::<AccountId>:policy/<PolicyName>' //Points to Custom Role which has Get Object access to the said s3 object
              });

              let accessKey='';
              let secretKey='';
              let sessionKey='';
              await cognitoIdentityClient.send(getCredentialsCommand,
                (err,data)=>{
                    if(err){
                        console.error(`Error while retrieving credentials:${JSON.stringify(err)}`);
                        throw new ('Access Key Retrieval Error');
                    }else{
                        accessKey=data.Credentials.AccessKeyId;
                        secretKey=data.Credentials.SecretKey;
                        sessionKey=data.Credentials.SessionToken;
                    }
              });

The issue is, the presignedUrl generated by this gives access denied exception, unless I add the policy of the custom role here to the lambda function. What I mean is, the policy xyz, that gives GetObject access to the s3 object, if it gets attached to the lambda function, then the presigned url works, else it does not. This behaviour leads me to believe that the getPresignedUrl function is using the policy attached to the lambda function, rather than the ones associated with the temporary credentials. Is that the case. ? If so, then how to ensure the policy attached to temporary credentials are used? Please advise.

1 Answer
0

You're correct - when generating a pre-signed URL within a Lambda function, it will use the IAM permissions associated with the Lambda function itself, not the temporary credentials you've supplied.

To use the permissions associated with the temporary credentials, you would need to move the pre-signed URL generation outside of the Lambda function. For example:

  • Generate the temporary credentials in your Lambda
  • Pass those credentials to an EC2 instance or separate function with more restricted IAM permissions
  • Generate the pre-signed URL there, where the temporary credentials will be used
  • Another option is to add a resource-based permissions policy to your Lambda role/function that allows the specific S3 GetObject access needed to generate the pre-signed URL for that object. This keeps everything within the Lambda but grants it restricted access based on resource ARNs vs wide open permissions.

But in general, LambdaExecutionRole permissions will take precedence over temporary creds from inside the function itself. You need to move that pre-signed URL generation elsewhere to leverage the temporary credentials directly.

profile pictureAWS
answered 8 months ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions