Circles App – Secure SDLC Walkthrough In Progress
A real example of how I approach product vision, UX design, cloud architecture, security, and delivery management – using a small but fully deployable serverless app.
Live demo: circles.behrens-hub.com
1. Product Vision
Circles started as a simple idea: help families and close-knit groups strengthen real-world relationships with less friction. The concept is a lightweight, privacy-respecting space for sharing messages, notes, and reminders inside small "circles" – without the noise and manipulation of large social platforms.
At the same time, I wanted Circles to serve as a concrete demonstration of how I approach modern cloud-native product delivery: from vision and requirements, through architecture and security, to incremental, cost-aware implementation on AWS.
2. Requirements & Discovery
I started with structured discovery: who is this for, what problems does it solve, and what is the smallest version that still feels meaningful? Even though the current demo focuses on messaging, the underlying idea is broader: helping people maintain relational rhythm in a healthy, human-centered way.
Requirements were grouped into three buckets:
- Functional requirements: circles, messaging, timestamps, basic identity
- Non-functional / security requirements: privacy by default, scoped access per circle, secure hosting, encrypted transport
- Operational constraints: low cost, minimal operational burden, fast iteration using serverless patterns
3. User Journey Mapping
Before writing code, I mapped the key user journeys to understand emotional flow, friction points, and what "success" looks like from a human perspective. Even for a small demo, this keeps the technical work anchored in real behavior.
- First-time visit and onboarding (what should the user see first?)
- Signing in and understanding “who am I” in the system
- Selecting a circle (e.g., Behrens family, Dickerson family, dev team)
- Posting a message and seeing it appear for that circle
4. Wireframes & UX Flow
I sketched low-fidelity wireframes to validate navigation and interaction patterns before touching the backend. The current UI is intentionally simple: a clean layout that shows the signed-in user, the current circle, and a chronological list of messages with author and timestamp.
Even in this minimal version, I paid attention to clarity: the user can see if they are signed in, which circle they are viewing, and what action they can take next.
5. Architecture & Secure Design
Under the hood, Circles is a fully serverless, cloud-native application designed for low cost, low operational overhead, and a clear path to scale. The architecture emphasizes identity, authorization, and clean separation of concerns.
- Frontend hosting: S3 (private bucket) + CloudFront with an Origin Access Identity
- Networking & delivery: CloudFront routes
/to the SPA and/api/*to API Gateway, keeping a single domain and avoiding CORS complexity - API layer: API Gateway (REST) with a
/prodstage exposingGET /api/circles– list messages for a circlePOST /api/circles– create a new messageGET /api/circles/config– return circles the current user can see
- Compute: AWS Lambda (Node.js 20) for all API business logic
- Data: DynamoDB tables for messages, circle metadata, and circle memberships
- Identity & auth: Amazon Cognito User Pool + Hosted UI, JWT-based auth, and an API Gateway Cognito authorizer
- Domain & TLS: Route 53 + ACM certificate for
circles.behrens-hub.com
The result is a small but realistic production-style environment: private data stores, a hardened public surface, and a clean identity and authorization model.
6. Infrastructure as Code (IaC)
All infrastructure for Circles is defined using AWS CDK (TypeScript) and deployed via CloudFormation. This includes:
- S3 bucket and CloudFront distribution
- Route 53 record set and ACM certificate
- API Gateway REST API and stage settings (including throttle limits)
- Lambda functions and permissions
- DynamoDB tables: messages, circles, and circle memberships
- Cognito User Pool, User Pool Client, Hosted UI domain, and API Gateway authorizer
- IAM roles and policies with least-privilege access to data stores
This approach keeps the system reproducible, reviewable, and versioned. It also provides a natural place to embed secure defaults (e.g., private buckets, HTTPS only, no public write access to data stores).
7. Backlog, Planning & Roadmap
I treated Circles like any product: the vision was translated into a structured backlog and a sequence of increments that could deliver value while validating the architecture. The roadmap emphasized:
- Start with a simple, working end-to-end slice
- Add identity and authorization once the core messaging path was stable
- Introduce circle membership and access control as a separate increment
- Leave room to evolve into richer features (invites, notifications, mobile views)
Planning also explicitly considered cost and re-architecture. It was more valuable to build a lean, correct MVP on serverless primitives than to overbuild a complex stack “just in case.” The design intentionally leaves a clean path to evolve if usage ever justifies it.
8. Incremental Delivery & Early Value
Rather than trying to build “the whole product,” I delivered a series of small, testable increments. Each step added real capability and also validated a piece of the architecture or security model.
Key increments included:
-
Increment 1 – Static site + API skeleton:
CloudFront, S3, and API Gateway were wired together so that
https://circles.behrens-hub.comcould call a real Lambda function behind/api/circles. -
Increment 2 – DynamoDB-backed messaging:
The
CirclesMessagestable was created withfamilyIdandcreatedAtkeys, and the Lambda implemented GET and POST behavior against DynamoDB. -
Increment 3 – Identity and sign-in:
Amazon Cognito was introduced with a Hosted UI. The frontend added
“Sign in / Sign out” behavior, parsed JWTs, and started sending
Authorization: Bearer <token>headers. -
Increment 4 – Backend authorization and memberships:
Two supporting tables (
CirclesandCircleMemberships) were added so the backend could enforce which circles a user may access. The UI now loads circle options from the API rather than hard-coding them. -
Increment 5 – Invitations and onboarding:
A dedicated
CircleInvitationstable and Lambda endpoints were added to generate single-use invite tokens, enforce TTL, and automatically attach new members to the right circle when they accept an invite. The frontend handles?invite=links and guides users through joining. -
Increment 6 – Analytics dashboard:
A lightweight
/api/statsendpoint was introduced to surface counts of circles, memberships, and unique members. The UI renders a simple analytics view so I can validate adoption patterns and keep an eye on growth without overbuilding observability too early. -
Increment 7 – AI prompt engine:
A Bedrock-backed
/api/promptsendpoint (Claude 3 Haiku) was added to generate 3–5 short, family-safe conversation starters on demand. The frontend exposes this via a “Suggest prompts” button, keeping the feature modular while setting the stage for future scheduled and tailored prompt experiments.
Each increment was small enough to validate quickly, but significant enough to demonstrate that the underlying approach was sound.
At a roadmap level, I track these increments in a simple Done / Next / Later view, which keeps the work visible without locking the implementation into a rigid Gantt chart.
9. Secure SDLC & Ongoing Improvement
Security wasn’t treated as a separate phase; it was layered in as the system matured. My goal was to apply the right level of security at each stage, rather than over-engineering up front.
Conceptually, the secure SDLC for Circles followed these stages:
- Stage 0 – Safe defaults: private S3 buckets, CloudFront OAI, HTTPS everywhere, least-privilege IAM for Lambdas and tables.
- Stage 1 – Authentication: Cognito User Pool + Hosted UI with JWT-based identity, and API Gateway Cognito authorizers in front of the API.
- Stage 2 – Backend authorization (zero trust): the Lambda no longer trusts the frontend to decide which circle is valid. Instead, it reads the user identity from JWT claims and checks membership in DynamoDB before returning or accepting any data.
- Stage 3 – Hardening & iteration: code and configuration are managed via CDK; future iterations can add PKCE, more granular roles, and richer monitoring as usage and risk justify.
This pattern mirrors how I’d evolve security in a larger product: start with strong defaults, layer in identity and authorization as first-class concepts, and then deepen the controls as value, usage, and risk increase.
10. Summary
Circles is intentionally small, but it reflects the same principles I bring to large-scale initiatives: clear vision, structured discovery, disciplined architecture, secure-by-default design, cost-aware delivery, and iterative improvement. The result is a working, production-style application that can be extended into a richer product or simply used as a transparent example of how I think and work.
For hiring managers, this project is a tangible view into how I translate strategy into architecture, and architecture into running software – while balancing usability, security, and cost.