0

Using Node + aws-sdk in a FaaS, I'm trying to get a presigned url to upload a file to an S3 bucket. When I upload the file I get the following response

InvalidAccessKeyIdThe AWS Access Key Id you provided does not exist in our records.

// getUploadUrl
import { FunctionEvent } from 'graphcool-lib'
import * as AWS from 'aws-sdk'

const BUCKET = process.env['BUCKET'];
const AWS_ACCESS_KEY_ID = process.env['AWS_ACCESS_KEY_ID'];
const AWS_SECRET_ACCESS_KEY = process.env['AWS_SECRET_ACCESS_KEY'];

const signedUrlExpiresSeconds = 60*10;

AWS.config.update({
  accessKeyId: AWS_ACCESS_KEY_ID,
  secretAccessKey: AWS_SECRET_ACCESS_KEY,
  region: 'eu-west-2'
});

const s3 = new AWS.S3({ apiVersion: "2006-03-01" })

interface EventData {
  fileName: string
}

export default async (event: FunctionEvent<EventData>) => {

  if (!event.context.auth || !event.context.auth.nodeId) {
    return { error: 'No user logged in.' }
  }

  try {
    const { fileName } = event.data;

    // Pre-signing a putObject (asynchronously)
    const params = { Bucket: BUCKET, Key: fileName, Expires: signedUrlExpiresSeconds }
    const uploadUrl: string = await s3.getSignedUrl('putObject', params)

    if (!uploadUrl) {
      return { error: 'Unable to get presigned upload URL from S3' }
    }



    return { data: { uploadUrl } }
  } catch (e) {
    console.log(e)
    return { error: 'An unexpected error occured during password change.' }
  }
}

Here are my permissions on AWS IAM

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject"
            ],
            "Resource": "arn:aws:s3:::bucket-name/*"
        }
    ]
}

I'm using the following to upload the file

curl -v -T test.pdf presignedUrl

Any ideas?

Here's the generated path

"https://my-aws-s3-domain.s3.eu-west-2.amazonaws.com/test.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=XXXXXXX1222%2Feu-west-2%2Fs3%2Faws4_request&X-Amz-Date=20171222T153846Z&X-Amz-Expires=600&X-Amz-Signature=XXXXXX-268d&X-Amz-SignedHeaders=host"

I updated the AWS config to AWS.config.update({ region: 'eu-west-2' }); as it'll pick up AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY from process.ENV automatically (as pointed out by Michael).

I tried it again and I got Access denied response so I changed the IAM policy to:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::my-s3-bucket-name"
        }
    ]
}

and it still is giving an Access denied error.

Blackstone4
  • 681
  • 1
  • 9
  • 21
  • Show us what the generated URL looks like. You can redact the path, the contents of the signature, token, and key, but the first 4 characters of the access key id are important for context (`AKIA` vs `ASIA`) so we need to see those. – Michael - sqlbot Dec 22 '17 at 15:25
  • @Michael-sqlbot thanks Michael - I add the path above – Blackstone4 Dec 22 '17 at 15:42
  • The `X-Amz-Credential` -- does it have AKIA or ASIA at the beginning? – Michael - sqlbot Dec 22 '17 at 16:07
  • @Michael-sqlbot ASIA – Blackstone4 Dec 22 '17 at 16:08
  • Remove the credentials from `AWS.config.update...`. The environment variables should be used automatically, but you're not picking up the third one, which I believe should be `AWS_SESSION_TOKEN`. By setting the other two explicitly, you are breaking things. Without this, `ASIA` credentials (the S is for **S**ession key) aren't valid. – Michael - sqlbot Dec 22 '17 at 16:56
  • I don't understand. I read the docs and it says `AWS_SESSION_TOKEN` is optional. See here http://docs.amazonaws.cn/en_us/AWSJavaScriptSDK/guide/node-configuring.html Under the section titled Hard-Coding Credentials, it shows I can use the following `AWS.config.update({accessKeyId: 'akid', secretAccessKey: 'secret'});` – Blackstone4 Dec 22 '17 at 17:13
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/161832/discussion-between-blackstone4-and-michael-sqlbot). – Blackstone4 Dec 22 '17 at 17:54

1 Answers1

1

Turns out there was a bug in Graphcool's environmental variables which meant the AWS keys weren't updating.

Possible related to this issue: https://github.com/graphcool/framework/issues/799

EDIT - In Graphcool, AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are protected environment variables. So you can't use them

Blackstone4
  • 681
  • 1
  • 9
  • 21