PROJECT 002
> cat laxstack-portfolio.md

Production-grade AWS Portfolio with Secure Serverless CI/CD.

Designed to demonstrate production-ready cloud engineering practices including Amazon S3, CloudFront, Route 53, AWS WAF, ACM, GitHub Actions, GitHub OIDC federation, cross-account IAM role assumption, and automated deployments using temporary STS credentials. Every deployment is performed without storing long-lived AWS access keys.

infrastructure live zero stored aws keys github oidc + sts cross-account iam
Visit laxstack.com View Repository Back to Portfolio
cat project-story.md

Engineering Story

1. Manual Deployments

The project started as a traditional static website uploaded manually to Amazon S3. Every update required manual synchronization and CloudFront cache invalidation.

2. Secure Automation

I replaced manual deployments with GitHub Actions authenticated through GitHub OIDC and AWS STS, eliminating long-lived credentials completely.

3. Enterprise Security

The final design separates deployment and production AWS accounts using cross-account IAM roles, mirroring enterprise landing zone patterns.

show request-flow

Request Lifecycle

Browser
Route53
CloudFront
AWS WAF
Origin Access Control
Amazon S3
Why this matters: Visitors never communicate directly with the S3 bucket. Every request is protected by CloudFront, HTTPS, AWS WAF, and Origin Access Control before reaching the origin.
show deployment-flow

CI/CD Authentication Flow

GitHub
OIDC JWT
AWS STS
Deploy Role
S3 Sync
CloudFront Invalidation
Trust Policy Highlights GitHub Repository │ └── OIDC JWT │ ▼ AWS STS issues temporary credentials │ ▼ Assume Deployment Role │ ▼ Deploy Website
show scorecard

Architecture Scorecard

0
Stored AWS Keys
2
AWS Accounts
100%
Serverless
TLS
HTTPS Everywhere
WAF
Managed Protection
OIDC
Federated Identity
preview architecture

Architecture at a Glance

Design Objective: I wanted this portfolio to resemble a production AWS deployment rather than a simple static website. The architecture emphasizes serverless infrastructure, least-privilege IAM, secure cross-account deployments, and zero long-lived AWS credentials while remaining inexpensive to operate.

Production AWS Architecture
Production Architecture — Click to enlarge
Security by design: The Amazon S3 origin bucket is never publicly accessible. DNS resolution is handled by Route 53, content is delivered through CloudFront, requests are inspected by AWS WAF, and Origin Access Control is the only path to the S3 origin. GitHub Actions authenticates through GitHub OIDC and AWS STS using temporary credentials, eliminating stored AWS access keys.
cat overview.md

No servers. No SSH. No 2am uploads.

laxstack.com is fully serverless — there's no EC2 instance to patch and no origin server sitting behind the scenes. It's static HTML, CSS, and JavaScript in an S3 bucket, distributed globally through CloudFront, filtered by WAF before it ever reaches the origin, resolved by Route 53, and encrypted end-to-end with a certificate ACM renews on its own.

Getting the infrastructure live was only half of this project. The other half was making sure updating the site never meant manually re-uploading files to S3 or babysitting a cache invalidation by hand — that's what the GitHub Actions + OIDC pipeline below solves.

show topology

Request Path

The bucket is never exposed directly to the internet — every request is fronted by CloudFront and screened by WAF before it reaches storage.

path — request to originclick to expand
YOU ROUTE 53 CLOUDFRONT AWS WAF AMAZON S3
5 hops · https via acm · edge cached · waf filtered
show interfaces

Website Infrastructure

Amazon S3

Origin for the website — static hosting, object storage, and durable storage behind CloudFront.

Amazon CloudFront

Global CDN, HTTPS termination, edge caching, and lower latency for every visitor.

Amazon Route 53

Authoritative DNS for laxstack.com, with an alias record pointing straight at CloudFront.

AWS Certificate Manager

Issues and auto-renews the TLS certificate CloudFront uses — HTTPS with nothing to renew by hand.

AWS WAF

Managed rule groups filter common exploits before requests ever reach CloudFront's origin.

show inventory

Technologies Used

HTML / CSS / JSGitGitHub GitHub ActionsGitHub OIDCAmazon S3 Amazon CloudFrontAmazon Route 53AWS WAF AWS IAMAWS STSAWS ACM
show pipeline

Deployment Pipeline

Manually uploading to S3 and invalidating CloudFront by hand worked, but it wasn't how production gets managed. This is what replaced it.

path — commit to liveclick to expand
DEV PUSH GITHUB ACTIONS OIDC + STS S3 SYNC ASSUME ROLE CDN INVALIDATED
6 hops · zero stored aws keys · two aws accounts
show running-config

Deployment Workflow

! 01-commit
Developer commits locally and pushes to GitHub.
! 02-trigger
A push to the main branch automatically triggers the GitHub Actions deployment workflow.
! 03-oidc-auth
GitHub authenticates to AWS via OpenID Connect — no stored access keys.
! 04-sts-creds
AWS STS issues short-lived credentials scoped to the deploy role.
! 05-s3-sync
Website files sync to the S3 bucket in the free AWS account.
! 06-cross-account
The deploy role assumes a role in the paid AWS account via STS.
! 07-invalidate
CloudFront cache is invalidated — visitors get the latest build.
show iam trust-policy

Cross-Account Trust

The pipeline spans two AWS accounts — a free account handling deployment, and a paid account holding CloudFront and WAF. Each role can do exactly one thing.

Free AWS Account
Github-website-Deploy
Paid AWS Account
Cloudfront-Invalidation

Github-website-Deploy can

  • s3:ListBucket
  • s3:GetObject
  • s3:PutObject
  • s3:DeleteObject
  • sts:AssumeRole

Cloudfront-Invalidation can

  • cloudfront:CreateInvalidation
the paid account trusts only this one deploy role — nothing else

The trickiest part of this build wasn't the AWS side — it was GitHub's OIDC trust policy. Diagnosing a failed federation handshake meant decoding the actual JWT claims GitHub was sending and tracing a mismatch back to GitHub's newer subject-claim format. That's the kind of bug that doesn't show up until federation actually happens.

GitHub OIDC Temporary STS credentials Least-privilege IAM Cross-account role assumption AWS WAF protection HTTPS via ACM Zero stored AWS keys
cat engineering-decisions.md

Engineering Decisions

Why Serverless?

I intentionally avoided EC2 to eliminate operating system maintenance, patching, backups, and unnecessary operational overhead. Static hosting provides high durability with minimal cost.

Why CloudFront?

CloudFront provides global edge caching, TLS termination, Origin Access Control, and seamless integration with AWS WAF, improving both performance and security.

Why GitHub OIDC?

Instead of storing AWS access keys inside GitHub Secrets, GitHub exchanges a signed OIDC token for short-lived AWS STS credentials. No permanent AWS credentials exist in the repository.

Why Two AWS Accounts?

The deployment pipeline and production infrastructure reside in separate AWS accounts. Cross-account IAM role assumption mirrors enterprise environments while enforcing least-privilege access.

cat troubleshooting.log

Engineering Challenges

OIDC Federation
Resolved GitHub OIDC subject-claim mismatches by decoding JWT claims and updating IAM trust policies.
Cross-Account IAM
Designed least-privilege IAM roles allowing deployment and CloudFront invalidation across separate AWS accounts.
Origin Security
Configured Origin Access Control and bucket policies so Amazon S3 is never directly exposed to the Internet.
show metrics

Project Metrics

Deployment

~90 second manual workflow execution from GitHub to production.

Security

Zero long-lived AWS credentials, least-privilege IAM, HTTPS via ACM, AWS WAF, and temporary STS credentials.

Cost

Designed to operate almost entirely within the AWS Free Tier. Primary recurring cost is the Route 53 hosted zone.

Future Improvements

Terraform, GitHub Environments, automated security scanning, Lighthouse testing, CloudFront Functions, and CloudWatch monitoring.

ls -la Images/

Implementation Evidence

Evidence collected from AWS and GitHub demonstrating how the architecture, security controls, and deployment pipeline were implemented.

Infrastructure

Production architecture
Amazon S3 origin bucket
CloudFront distribution
Route 53 DNS
ACM certificate
AWS WAF

Identity & Security

GitHub OIDC Provider
Cross-account IAM role
Bucket policy (OAC)

CI/CD Pipeline

Developer push
GitHub Actions deployment history
git diff --stat

Current State & What's Next

committed — current features
+Serverless static hosting on S3
+CloudFront CDN + HTTPS termination
+AWS WAF request filtering
+Route 53 DNS management
+ACM auto-renewing TLS
+GitHub Actions CI/CD
+GitHub OIDC auth, zero stored keys
+Cross-account IAM role assumption
candidate-config — future improvements
~Infrastructure as Code via Terraform
~AWS CDK implementation
~Separate dev / prod environments
~Automated HTML validation
~Lighthouse performance testing
~Slack / Teams deploy notifications
~Automated security scanning
show notes

Lessons Learned

#Static hosting on Amazon S3
#Content delivery with CloudFront
#DNS management with Route 53
#HTTPS via ACM
#Web protection with AWS WAF
#GitHub Actions automation
#OpenID Connect (OIDC)
#AWS Security Token Service
#IAM trust & permission policies
#Cross-account role assumption
#CloudFront cache invalidation
#Designing secure CI/CD, not just working CI/CD
×