dev site โ experiments, projects, etc.
Completely rewrote the backend for gfd.sh today. What started as a simple Lambda-powered blog with environment-variable authentication turned into a properly architected serverless app with OAuth2 and clean module separation.
The old version had a hacky username/password system where credentials lived in Lambda env vars:
if username in os.environ and password == os.environ[username]:
# you're in
Now it's a full OAuth2/OIDC flow with Cognito Hosted UI:
/login redirects to Cognito/test handles the callback, exchanges the authorization code for tokens/logout clears the cookie and redirects to Cognito's logout endpointZero external dependencies โ just urllib, hmac, and base64 from the standard library.
Replaced the custom BBCode parser with a zero-dependency Markdown renderer. Supports:
Still renders entirely at write-time (Markdown โ HTML before saving to S3), so serving is instant.
Broke the 300-line lambda_function.py into focused modules:
modules/
โโโ config.py # strict env var loader (no defaults)
โโโ cognito_auth.py # OAuth flow + session cookies
โโโ s3_handler.py # posts.json CRUD
โโโ markdown_parser.py # Markdown โ HTML
โโโ html_builder.py # template injection + auth-aware nav
The main handler is now just a thin router โ all business logic lives in modules.
Posts are now attributed to the Cognito username:
{
"posts": [
{
"timestamp": "2026-03-04 12:00:00 MST",
"author": "username",
"html": "<div class=\"textPost\">...</div>"
}
]
}
The UI displays them Discord-style: username ยท timestamp at the top of each message.
Security: No plaintext passwords in env vars. Cognito handles user management, MFA, password resets, etc.
Maintainability: Modular code is easier to test, extend, and debug. Each module has a single responsibility.
Portability: The Markdown parser has zero dependencies beyond Python stdlib. No pip install markdown or beautifulsoup4 needed โ runs on bare Lambda Python runtime.
Strict Config: Added a require_env() helper that fails fast at startup if any required env var is missing. No silent fallbacks, no "it worked locally but not in prod."
Still running on:
Added:
Cost: still pennies per month.
Might add:
For now, it's stable, clean, and ready to ship. GitHub-safe (no secrets in source), well-documented, and actually fun to work on.
*Posted from the /post form using the new Markdown renderer. Meta.*
I made a little entry where you can leave a mark on my website.
Love,
Nolan
We should add username to the post!
hey, this is my site!