Serverless Cloud Client Gallery
Executive Summary
Engineered to replace third-party photo delivery SaaS platforms like Pixieset, this architecture eliminates recurring monthly subscription fees by leveraging AWS's pay-as-you-go serverless ecosystem. By utilizing Amazon S3 ($0.023/GB standard storage) combined with CloudFront edge caching and Lambda's free usage tier, the platform operates at a $0 static base running cost.
A photographer would need to host approximately 40,000 full-resolution JPEG photos (or roughly 400 GB of media storage) on AWS before incurring a monthly bill equivalent to Pixieset's $10.99 base tier threshold. The system features secure client link generation via S3 Presigned URLs, single-digit millisecond metadata retrieval via DynamoDB, and keyless infrastructure deployment driven by Terraform and GitHub Actions.
Architecture & Workflow Decisions
- Client Request & Authentication: Inbound client requests pass through Amazon CloudFront edge locations, enforcing HTTPS and negotiating secure TLS handshakes before reaching API Gateway.
- Session & Access Validation: API Gateway routes authentication requests to AWS Lambda microservices, which validate gallery access tokens and query Amazon DynamoDB for gallery states, expiration limits, and image keys.
- Presigned Media Streaming: Instead of proxying heavy media files through Lambda payloads, the backend dynamically generates time-bounded, secure S3 Presigned URLs and streams response payloads for full-resolution image downloads.
- Edge Caching & Delivery: Amazon CloudFront caches public assets at global edge locations, minimizing latency for repeat photo downloads while shielding private S3 buckets from direct Internet access.
- Keyless Infrastructure CI/CD: Commits to the repository trigger a GitHub Actions pipeline that uses OpenID Connect (OIDC) short-lived tokens to authenticate with AWS, executing Terraform execution plans to deploy infrastructure without storing long-lived access keys.
Infrastructure & Code Highlights
Keyless Pipeline Authentication (`deploy.yml`)
Configured passwordless OAuth federation using OpenID Connect (OIDC) between GitHub Actions and AWS IAM, eliminating static AWS credentials in CI/CD environments.
name: Deploy Cloud Client Gallery
on:
push:
branches: [ main ]
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Authenticate via AWS OIDC
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/GitHubActions-Gallery-Role
aws-region: eu-west-2
- name: Provision Infrastructure
run: |
terraform init
terraform apply -auto-approve
Presigned URL Generation (`streamHandler.js`)
Bypasses API Gateway 10 MB payload limits by streaming signed S3 download links directly to clients with explicit CORS header configurations.
import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
const s3Client = new S3Client({ region: "eu-west-2" });
export const handler = awslambda.streamifyResponse(async (event, responseStream) => {
const { galleryId, imageKey } = JSON.parse(event.body);
// Generate 15-minute time-bounded S3 download token
const command = new GetObjectCommand({
Bucket: process.env.GALLERY_S3_BUCKET,
Key: `${galleryId}/${imageKey}`,
});
const presignedUrl = await getSignedUrl(s3Client, command, { expiresIn: 900 });
responseStream.write(JSON.stringify({
statusCode: 200,
headers: { "Access-Control-Allow-Origin": "https://samuelojo.tech" },
downloadUrl: presignedUrl
}));
responseStream.end();
});
Key Technical Challenges Resolved
Payload Limits & Response Streaming
Overcame API Gateway's strict 10 MB payload limit when serving full-resolution photography by implementing AWS Lambda Response Streaming and S3 Presigned URLs, allowing direct client downloads without exhausting function memory or timing out.
Keyless Pipeline Authentication
Eliminated security risks associated with static AWS IAM secret keys in CI/CD pipelines by configuring OpenID Connect (OIDC) identity federation between GitHub Actions and AWS IAM role trust policies.
Cross-Origin & Edge Cache Headers
Resolved CORS errors and preview caching issues across React frontend requests by standardizing `Access-Control-Allow-Origin` headers and configuring explicit CloudFront Cache Policies for signed image query parameters.