AWS S3
Configure Amazon S3 with IAM, CORS, and TurboJet S3_* env vars.
Amazon S3 is the original S3 API that other providers implement. Use it when you already run on AWS or need tight integration with the AWS ecosystem.
1. Create an S3 bucket
In the AWS S3 console, create a bucket:
- Choose a globally unique name and a region close to your users
- Keep Block all public access enabled
- Versioning is optional but useful in production
Keep the bucket private
TurboJet uses presigned URLs for uploads and downloads. Public access is not required.
2. Create an IAM user
In the IAM console, create a user for the app and attach a policy scoped to your bucket:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::your-app-bucket",
"arn:aws:s3:::your-app-bucket/*"
]
}
]
}Create an access key under Security credentials and copy the Access Key ID and Secret Access Key.
3. Configure CORS
Bucket → Permissions → Cross-origin resource sharing (CORS):
[
{
"AllowedHeaders": ["*"],
"AllowedMethods": ["GET", "PUT", "POST", "DELETE", "HEAD"],
"AllowedOrigins": [
"https://your-marketing-domain.com",
"http://localhost:3001"
],
"ExposeHeaders": ["ETag"],
"MaxAgeSeconds": 3600
}
]Replace the origins with your real marketing URL and local port.
4. Environment variables
S3_ACCESS_KEY_ID="your-aws-access-key-id"
S3_SECRET_ACCESS_KEY="your-aws-secret-access-key"
S3_ENDPOINT="https://s3.us-east-1.amazonaws.com"
S3_REGION="us-east-1"
S3_BUCKET="your-app-bucket"Use your bucket’s region. The endpoint pattern is https://s3.<region>.amazonaws.com.
5. Test the upload
Run the marketing app and follow Upload files while signed in.
CloudFront (optional)
For lower latency in production, put a CloudFront distribution in front of the bucket with Origin Access Control (OAC) so the bucket stays private.
FAQ
How much does S3 cost?
Pricing varies by region and class. S3 Standard is roughly on the order of cents per GB-month plus request and egress charges. Check current AWS S3 pricing. For heavy egress, compare Cloudflare R2.
Do I need public access?
No. Use /api/storage/signed for private files.
How do I limit file types or sizes?
Edit packages/validations/src/storage/storage.ts — those limits are enforced when creating upload URLs.