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.
- Go to AWS Console → IAM → Users → Create user
- Give it a name like
my-app-s3-user - Choose Attach policies directly
- Attach
AmazonS3FullAccess(or a more restrictive custom policy — recommended for production) - After creating the user, go to Security credentials → Create access key
- Choose Application running outside AWS
- Download or copy the Access Key ID and Secret Access Key
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
- Yarn
- pnpm
- Bun
npm install @aws-sdk/client-s3 @aws-sdk/s3-request-presigner
yarn add @aws-sdk/client-s3 @aws-sdk/s3-request-presigner
pnpm add @aws-sdk/client-s3 @aws-sdk/s3-request-presigner
bun add @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
- Yarn
- pnpm
- Bun
npm install dotenv
yarn add dotenv
pnpm add dotenv
bun add dotenv
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:
.env
Create an S3 Client
Create a single reusable S3 client and import it wherever you need it.
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;
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.
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:
- Go to AWS Console → S3 → Create bucket
- Choose a globally unique name (e.g.,
my-app-uploads-2024) - Select your region (should match
AWS_REGIONin your.env) - Block all public access — keep this enabled for private files. You'll use presigned URLs to serve files securely.
- Click Create bucket
Custom IAM Policy (Recommended)
Instead of AmazonS3FullAccess, restrict the IAM user to only the operations your app needs:
{
"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.