A fully serverless and security-focused file-sharing backend inspired by enterprise cloud security platforms.
Users authenticate through AWS Cognito and securely upload/download files using time-limited presigned URLs, with a full audit trail in DynamoDB.
- Amazon S3 → Encrypted file storage (versioning + no public access)
- AWS Lambda
uploader→ Generates presigned PUT upload URLspresigner→ Generates presigned GET download URLs
- API Gateway (HTTP API) → Routes:
/upload,/presign - AWS Cognito → Authentication using JWT tokens
- DynamoDB
*-files(optional metadata)*-audit(security logging)
- IAM → Least-privilege execution roles
- CloudWatch Logs → Lambda + API observability
| Feature | Status |
|---|---|
| Cognito authentication | ✔ |
| Time-limited presigned access | ✔ |
| Direct to S3 uploads (no backend file handling) | ✔ |
| Full audit logging in DynamoDB | ✔ |
| Provisioned with Terraform | ✔ |
| CLI testing with curl | ✔ |
| Least-privilege IAM | ✔ |
cd infra
terraform init
terraform applyTerraform provisions:
secure-file-sharing-*S3 bucket- DynamoDB tables:
*-files,*-audit - Lambda functions:
*-uploader,*-presigner - API Gateway with secured routes
- Cognito User Pool + Client App
- IAM execution roles + policies
Terraform Deployment Output
COGNITO_POOL_ID="<your_pool_id>"
aws cognito-idp admin-create-user \
--user-pool-id "$COGNITO_POOL_ID" \
--username "you@example.com" \
--message-action SUPPRESS \
--temporary-password "TempPassword123!"
aws cognito-idp admin-set-user-password \
--user-pool-id "$COGNITO_POOL_ID" \
--username "you@example.com" \
--password "YourPassword123!" \
--permanentCognito User Successfully Created
CLIENT_ID="<your_client_id>"
ID_TOKEN=$(aws cognito-idp initiate-auth \
--client-id "$CLIENT_ID" \
--auth-flow USER_PASSWORD_AUTH \
--auth-parameters USERNAME="you@example.com",PASSWORD="YourPassword123!" \
--query "AuthenticationResult.IdToken" \
--output text)
echo "${ID_TOKEN:0:60}..."JWT Token Retrieved
curl -X POST "$API/upload" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ID_TOKEN" \
-d '{"filename": "hello-auth.txt", "expires": 600}'Authenticated Upload Request (Cognito Token Validated)
echo "Hello secure world!" > file.txt
curl -X PUT -T file.txt "<presigned_upload_url>"Authenticated S3 Object after Successful Upload
curl -X POST "$API/presign" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ID_TOKEN" \
-d '{"file_key": "<user_id>/hello.txt", "expires": 600}'Example DynamoDB record:
{
"audit_id": "uuid",
"ts": "2025-11-27T16:30:00Z",
"user": "you@example.com",
"action": "generate_presigned_put",
"file_key": "user-123/hello.txt",
"source_ip": "203.0.113.42",
"expires_in_seconds": 600
}Audit Log After Authenticated Access
| Layer | Security |
|---|---|
| S3 | No public access, encryption enabled, versioning |
| IAM | Strict least-privilege execution roles |
| Auth | Cognito JWT validation |
| API | HTTPS enforced, short-lived URLs |
| Audit | Immutable log trail stored in DynamoDB |





