A minimal employee access portal using AWS ALB for OAuth2 authentication and FastAPI for group-based authorization.
https://github.com/davidbmar/2026-jan-vibecodeportal-aws-cognito-alb-auth-portal · public · shipped
This project is a reference implementation of an 'Employee Access Portal' deployed on AWS. It leverages the Application Load Balancer (ALB) to handle the heavy lifting of OpenID Connect (OIDC) authentication with AWS Cognito, passing user identity via HTTP headers to a backend FastAPI application running on EC2. The application enforces fine-grained, group-based access control (e.g., Engineering, HR) and provides a simple UI for viewing user details and protected areas. It includes infrastructure-as-code (Terraform) for one-command deployment and seeded test users.
./scripts/deploy.sh USER_POOL_ID=$(cd terraform/envs/tier5 && terraform output -raw cognito_user_pool_id) aws cognito-idp admin-set-user-password --user-pool-id $USER_POOL_ID --username dmar@capsule.com --password "YourSecurepw23!" --permanent --region us-east-1 cd terraform/envs/tier5 && terraform output -raw alb_dns_name
flowchart TD
User([User Browser]) -->|HTTPS| ALB[Application Load Balancer]
ALB -->|Auth Required| Cognito[AWS Cognito User Pool]
Cognito -->|OIDC Callback| ALB
ALB -->|x-amzn-oidc-* Headers| EC2[EC2 Instance]
subgraph EC2_Instance [EC2 Instance]
FastAPI[FastAPI App]
Cache[(In-Memory Cache)]
end
EC2 --> FastAPI
FastAPI --> Cache
FastAPI -->|IAM Role| CognitoAPI[Cognito API]
CognitoAPI -->|Group Membership| FastAPI
ALB -->|Health Check Bypass| FastAPI
The infrastructure is defined in Terraform, provisioning a VPC, public subnets, an Internet Gateway, an ALB, an EC2 instance (t3.micro), and a Cognito User Pool with custom auth triggers (Lambda functions for email-based MFA). The ALB listener rules route unauthenticated traffic to Cognito and bypass authentication for health checks. The EC2 instance runs a systemd-managed FastAPI service, initialized via user_data scripts. The app reads `x-amzn-oidc-data` or similar ALB-injected headers to identify users and queries Cognito (via IAM role) to resolve group memberships, caching results in memory.
sequenceDiagram
participant User as User Browser
participant ALB as Application Load Balancer
participant Cognito as AWS Cognito
participant App as FastAPI App
participant DB as DynamoDB/MFA
User->>ALB: GET /areas/engineering
ALB->>Cognito: Authenticate-Cognito Action
Cognito->>User: Redirect to Hosted UI
User->>Cognito: Submit Credentials
Cognito->>DB: Trigger CreateAuthChallenge (MFA)
DB->>User: Send Email Code
User->>Cognito: Submit MFA Code
Cognito->>DB: VerifyAuthChallenge
Cognito->>ALB: Return OIDC Tokens
ALB->>App: Forward Request + User Headers
App->>App: Extract Email from Headers
App->>App: Check Group Cache
alt Cache Miss
App->>Cognito: ListGroupsForUser (IAM)
Cognito-->>App: Return Groups
App->>App: Update Cache
end
alt Authorized
App-->>User: Render Engineering Page
else Denied
App-->>User: Redirect to /denied
end
Use this as a starter template for internal tools requiring secure, group-based access without building a custom auth backend. It demonstrates how to offload authentication to the load balancer layer, reducing application complexity. The Terraform modules can be adapted for other AWS regions or integrated into existing VPCs. The custom MFA Lambda triggers provide a pattern for implementing step-up authentication or custom verification flows beyond standard SMS/TOTP.
✓ all on main — nothing unmerged.