Skip to main content

Setting Up AWS SDK & Credentials

Before you can interact with any AWS service from your Express app, you need two things: an IAM user with the right permissions, and the AWS SDK installed in your project.

Create an IAM User

Never use your AWS root account credentials in code. Instead, create a dedicated IAM user.

  1. Go to AWS Console → IAM → Users → Create user
  2. Give it a name like my-app-s3-user
  3. Choose Attach policies directly
  4. Attach AmazonS3FullAccess (or a more restrictive custom policy — recommended for production)
  5. After creating the user, go to Security credentials → Create access key
  6. Choose Application running outside AWS
  7. Download or copy the Access Key ID and Secret Access Key
danger

Never commit AWS credentials to git. Use environment variables or a secrets manager.

Install the AWS SDK

AWS SDK v3 is modular — you install only the services you need.

npm install @aws-sdk/client-s3 @aws-sdk/s3-request-presigner

Configure Credentials via Environment Variables

Store credentials in a .env file and load them with dotenv.

npm install dotenv
.env
AWS_ACCESS_KEY_ID=your_access_key_id
AWS_SECRET_ACCESS_KEY=your_secret_access_key
AWS_REGION=us-east-1
AWS_S3_BUCKET_NAME=your-bucket-name

Add .env to your .gitignore:

.gitignore
.env

Create an S3 Client

Create a single reusable S3 client and import it wherever you need it.

config/s3.js
import { S3Client } from "@aws-sdk/client-s3";

const s3 = new S3Client({
region: process.env.AWS_REGION,
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
},
});

export default s3;
tip

If your app runs on an EC2 instance, ECS task, or Lambda function, you don't need to pass credentials at all. The SDK automatically uses the IAM role attached to the compute resource. This is the preferred approach in production.

config/s3.js (on AWS compute)
import { S3Client } from "@aws-sdk/client-s3";

// Credentials are picked up automatically from the IAM role
const s3 = new S3Client({ region: process.env.AWS_REGION });

export default s3;

Creating an S3 Bucket

If you haven't created a bucket yet:

  1. Go to AWS Console → S3 → Create bucket
  2. Choose a globally unique name (e.g., my-app-uploads-2024)
  3. Select your region (should match AWS_REGION in your .env)
  4. Block all public access — keep this enabled for private files. You'll use presigned URLs to serve files securely.
  5. Click Create bucket

Instead of AmazonS3FullAccess, restrict the IAM user to only the operations your app needs:

IAM Policy (least privilege)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::your-bucket-name/*"
},
{
"Effect": "Allow",
"Action": ["s3:ListBucket"],
"Resource": "arn:aws:s3:::your-bucket-name"
}
]
}

This limits the IAM user to only PutObject, GetObject, DeleteObject, and ListBucket on your specific bucket — nothing else.

Next Steps

With the client configured, you're ready to upload files, generate presigned URLs, and delete objects from your Express routes.