I'm trying to setup a node.js app that will upload files to an S3 bucket. I keep getting this error:
SignatureDoesNotMatch : The request signature we calculated does not match the signature you provided.
I'm not sure what this means, but appears to be related to authentication or permissions? For simplicity sake, I'm trying this code to simply return a list of buckets:
import { S3Client, ListBucketsCommand } from "@aws-sdk/client-s3";
import { Upload } from "@aws-sdk/lib-storage";
const s3Client = new S3Client({
region: "us-west-2",
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
},
});
try {
const data = await s3Client.send(new ListBucketsCommand({}));
console.log("Success", data.Buckets);
} catch (err) {
console.log("Error", err);
}
For the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY values, I'm using an IAM User that I setup with these steps:
- Create a new user: Console > Identity and Access Management (IAM) > Access management > Users > Create User
- Set Permissions : Step 2 > Set Permissions > Create Group > Permission policies > Add user to group > Create Group > Admin > Attached policies Administrator
- Create access key: Local Code
I've tried various methods of configuring the access keys using the AWS CLI, manually adding configuration profiles, and lastly directly specifying them as environment variables and passing them into the S3Client() constructor. If I use the AWS Extension for VS Code and connect with my local profile using AWS: Connect to AWS > Profile:s3-uploader-user I can see the buckets listed under the US West (Oregon) > S3 > test-bucket. I can use the upload button in the UI to upload images. This confirms that I have sufficient permissions to upload files. In my code, I've logged the value's of the env variables to make sure they're set correctly when the s3client.send() command is invoked.
I'm embarrassed to say, the issue was I had setup a script to read from secrets in my container that wasn't working properly and it was blanking out the value of
AWS_SECRET_ACCESS_KEY. While I understand specifying the key/secret directly in the code is not best practice, it's good to know that it works.