AWS S3 and Rekognition Setup
This document describes the AWS integration setup for CAIRL's ID document upload functionality.
Overview
The application uses AWS S3 for secure document storage and AWS Rekognition for ID verification.
Configuration
Environment Variables
Add the following to your .env.local file (never commit this file):
AWS_REGION=us-east-1
AWS_ACCESS_KEY_ID=your-actual-access-key-id
AWS_SECRET_ACCESS_KEY=your-actual-secret-access-key
AWS_S3_BUCKET=cairl-id-documents-production
AWS_S3_BUCKET_REGION=us-east-1
IMPORTANT: The .env.example file contains placeholder values only. Always use your real credentials in .env.local.
File Structure
src/lib/aws/
├── index.ts # Main exports
├── s3.ts # S3 client configuration
├── rekognition.ts # Rekognition client configuration
└── upload.ts # File upload utilities
src/app/api/
├── upload/id/ # ID upload endpoint
│ └── route.ts
└── test-s3/ # S3 connection test endpoint
└── route.ts
API Endpoints
POST /api/upload/id
Upload an ID document to S3.
Request:
- Method:
POST - Content-Type:
multipart/form-data - Body:
file(required): The ID document fileuserId(optional): User ID for metadatadocumentType(optional): Type of document (e.g., "passport", "drivers_license")
Response:
{
"success": true,
"data": {
"key": "id-documents/1234567890-abc123.jpg",
"fileName": "1234567890-abc123.jpg",
"url": "https://presigned-url...",
"bucket": "cairl-id-documents-production"
}
}
Validation:
- Allowed file types: JPEG, PNG, WebP, PDF
- Maximum file size: 10MB
GET /api/upload/id
Health check endpoint for the upload service.
Response:
{
"message": "ID upload endpoint is ready",
"allowedTypes": [
"image/jpeg",
"image/jpg",
"image/png",
"image/webp",
"application/pdf"
],
"maxSize": "10MB"
}
GET /api/test-s3
Test S3 connection and configuration.
Response:
{
"success": true,
"message": "S3 connection successful",
"config": {
"bucket": "cairl-id-documents-production",
"region": "us-east-1"
}
}
Usage Examples
Upload a File (cURL)
curl -X POST http://localhost:3000/api/upload/id \
-F "file=@/path/to/id-document.jpg" \
-F "userId=user123" \
-F "documentType=drivers_license"
Upload a File (JavaScript)
const formData = new FormData();
formData.append("file", fileInput.files[0]);
formData.append("userId", "user123");
formData.append("documentType", "drivers_license");
const response = await fetch("/api/upload/id", {
method: "POST",
body: formData,
});
const result = await response.json();
console.log(result);
Test S3 Connection
curl http://localhost:3000/api/test-s3
Utility Functions
uploadToS3
Upload a file buffer to S3.
import { uploadToS3 } from "@/lib/aws";
const result = await uploadToS3(buffer, "document.jpg", {
folder: "id-documents",
metadata: { userId: "123", documentType: "passport" },
isPublic: false,
});
getSignedS3Url
Get a signed URL for accessing a private S3 object.
import { getSignedS3Url } from "@/lib/aws";
const url = await getSignedS3Url("id-documents/file.jpg", 3600);
// URL expires in 1 hour (3600 seconds)
validateFile
Validate a file before upload.
import { validateFile } from "@/lib/aws";
const validation = validateFile({
size: file.size,
type: file.type,
});
if (!validation.valid) {
console.error(validation.error);
}
Security
- All ID documents are stored as private objects in S3
- Access is controlled via signed URLs with expiration times
- Files are validated for type and size before upload
- Environment variables are never exposed to the client
- The
.env.localfile is gitignored to prevent credential leaks
Testing
Start the development server:
npm run devTest S3 connection:
curl http://localhost:3000/api/test-s3Test file upload:
curl -X POST http://localhost:3000/api/upload/id \ -F "file=@test-image.jpg"
Troubleshooting
"AWS_REGION is not defined"
Make sure your .env.local file exists and contains all required AWS environment variables.
"Failed to connect to S3"
- Verify your AWS credentials are correct
- Check that the S3 bucket exists and is accessible
- Ensure your IAM user has the necessary S3 permissions
"Invalid file type"
Only JPEG, PNG, WebP, and PDF files are allowed. Check the file MIME type.
"File too large"
Maximum file size is 10MB. Compress or resize the file before uploading.
Required IAM Permissions
Your AWS IAM user needs the following permissions:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:PutObject", "s3:GetObject", "s3:HeadBucket"],
"Resource": [
"arn:aws:s3:::cairl-id-documents-production",
"arn:aws:s3:::cairl-id-documents-production/*"
]
},
{
"Effect": "Allow",
"Action": [
"rekognition:DetectText",
"rekognition:DetectFaces",
"rekognition:CompareFaces"
],
"Resource": "*"
}
]
}
Next Steps
- Implement Rekognition integration for ID verification
- Add image preprocessing (rotation, compression)
- Implement virus scanning for uploaded files
- Add upload progress tracking
- Set up S3 lifecycle policies for automatic deletion of old documents
- Implement server-side encryption for S3 objects