A secure, single-user web application for managing personal markdown notes, built with FastAPI and deployed on Google Cloud Platform.
- π Secure Authentication - Session-based auth with SHA256 password hashing
- π Dynamic AES Encryption - User-provided keys with SHA-256 derivation for secure note content
- π Markdown Editor - Rich editor with syntax highlighting and auto-save
- π File Upload - Secure drag-and-drop upload for .txt and .md files
- π Search Functionality - Full-text search across note titles and content
- π± Responsive Design - Works seamlessly on desktop and mobile devices
- βοΈ Cloud Storage - Notes persisted in Google Firestore
- π Auto-Deploy - Ready for Google Cloud Platform App Engine
- π‘οΈ Security Features - CSRF protection, secure cookies, HTTPS enforcement
βββββββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββ
β Web Browser βββββΊβ FastAPI App βββββΊβ Firestore β
β β β β β Database β
β β’ Authenticationβ β β’ Session Mgmt β β β’ Note Storage β
β β’ Markdown UI β β β’ CRUD APIs β β β’ Search Index β
β β’ Dynamic AES β β β’ SHA-256 Key β β β’ Backup β
β Encryption β β Derivation β β β
βββββββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββ
β² β²
β π Encrypted β
β Transmission β
βββββββββββββββββββββββββ
- Python 3.13+
- Google Cloud Platform account
- Git (optional)
git clone <repository-url>
cd note-gcp# Create virtual environment
python -m venv .venv
# Activate virtual environment
# Windows:
.venv\Scripts\activate
# macOS/Linux:
source .venv/bin/activate
# Install packages
pip install -r requirements.txt# Copy environment template
cp .env.example .env
# Edit .env with your settingsRequired environment variables:
USERNAME=admin
PASSWORD_HASH=5f4dcc3b5aa765d61d8327deb882cf99
FIRESTORE_PROJECT=your-gcp-project-id
SECRET_KEY=your-super-secret-key-here
AES_KEY=your-encryption-key-here-any-string-works
ENVIRONMENT=developmentuvicorn app.main:app --reload --host 0.0.0.0 --port 8080Visit: http://localhost:8080
Default login: Username: admin, Password: password
AES Key Setup: When you visit /notes pages, you'll be prompted to enter the same key you set in the AES_KEY environment variable.
Follow the detailed guide in DEPLOYMENT.md for production deployment.
| Document | Description |
|---|---|
PRD.md |
Product Requirements Document |
PLAN.md |
Implementation Plan & Architecture |
e2e_encryption_prd.md |
End-to-End Encryption Requirements |
DEPLOYMENT.md |
GCP App Engine & Firestore Setup Guide |
TEST.md |
Local Testing Guide |
CLAUDE.md |
Development Guidelines for AI Assistance |
Clean, secure authentication with CSRF protection.
Browse all your notes with search functionality and responsive grid layout.
Split-pane editor with real-time preview, syntax highlighting, and keyboard shortcuts.
Fully responsive design that works perfectly on all devices.
- FastAPI - Modern, fast web framework for Python
- Python 3.13 - Latest Python runtime
- Uvicorn/Gunicorn - ASGI server for production
- Pydantic - Data validation and settings management
- PyJWT - JSON Web Token implementation
- Python-Markdown - Markdown to HTML conversion
- Cryptography - AES-GCM encryption library
- Google Firestore - NoSQL cloud database
- Native Mode - For real-time updates and scaling
- Jinja2 - Modern templating engine
- Vanilla JavaScript - No heavy frameworks, just clean JS
- Web Crypto API - Browser-native AES-GCM encryption
- CSS Grid/Flexbox - Modern responsive layouts
- Progressive Enhancement - Core features work without JavaScript
- Google Cloud App Engine - Fully managed serverless platform
- Docker - Containerized deployment
- Cloud Build - Automated CI/CD pipeline
- β Authentication - Session-based with secure JWT tokens
- β Dynamic AES Encryption - User-provided keys with SHA-256 derivation for 256-bit encryption
- β Password Security - SHA256 hashing (as specified in requirements)
- β CSRF Protection - Token-based request validation
- β Secure Cookies - HttpOnly, Secure, SameSite flags
- β HTTPS Enforcement - Automatic SSL in production
- β Route Protection - Authentication required for all operations
- β Input Validation - Server-side validation for all user inputs
- β Session Management - Automatic expiration and cleanup
- π Key Management - User-controlled encryption keys with automatic key derivation
- Automatic encryption - All content encrypted before transmission
- Real-time editing - Smooth editing experience with encryption
- Syntax highlighting - Visual feedback for markdown syntax
- Auto-save - Never lose your work (with encryption)
- Keyboard shortcuts - Ctrl+S to save, Tab support in editor
- Responsive design - Adapts to all screen sizes
- Search functionality - Find notes quickly
- Pagination - Handle large collections efficiently
- Breadcrumb navigation - Always know where you are
- Create/Edit/Delete - Full CRUD operations
- Search - Full-text search across titles and content
- Preview mode - View notes in formatted HTML
- Timestamps - Track creation and modification dates
- Drag-and-drop interface - Intuitive file upload experience
- Secure encryption - Files encrypted client-side before upload
- File validation - Support for .txt and .md files up to 1MB
- Automatic processing - Uploaded files become editable notes
- Error handling - Clear feedback for invalid files or errors
note-gcp/
βββ app/ # Main application code
β βββ main.py # FastAPI application entry point
β βββ config.py # Configuration management
β βββ auth/ # Authentication logic
β β βββ auth.py # Session management & security
β βββ crypto/ # Encryption utilities
β β βββ encryption.py # Dynamic AES encryption with SHA-256 key derivation
β βββ models/ # Data models
β β βββ notes.py # Note data structures
β βββ repositories/ # Data access layer
β β βββ firestore.py # Firestore integration
β βββ routers/ # API endpoints
β β βββ auth.py # Authentication routes
β β βββ notes.py # Notes CRUD routes (with encryption)
β βββ templates/ # HTML templates
β β βββ base.html # Base template
β β βββ login.html # Login page
β β βββ notes_list.html# Notes listing (with decryption)
β β βββ note_editor.html# Note editor (with encryption)
β β βββ note_preview.html# Note preview (with decryption)
β β βββ upload.html # File upload page
β βββ static/ # Static assets
β βββ css/
β β βββ style.css # Main stylesheet (includes upload styles)
β βββ js/
β βββ crypto.js # Client-side encryption with dynamic key management
β βββ editor.js # Editor functionality
β βββ upload.js # File upload handling
βββ requirements.txt # Python dependencies
βββ Dockerfile # Container configuration
βββ app.yaml # GCP App Engine config
βββ .env.example # Environment variables template
βββ e2e_encryption_prd.md # End-to-end encryption requirements
βββ docs/ # Documentation
βββ PRD.md
βββ PLAN.md
βββ DEPLOYMENT.md
βββ TEST.md
βββ CLAUDE.md
# Install dependencies
pip install -r requirements.txt
# Run development server
uvicorn app.main:app --reload --port 8080
# Run tests
python test_basic.py
# Deploy to GCP
gcloud app deploy
# View logs
gcloud app logs tail| Method | Endpoint | Description |
|---|---|---|
GET |
/ |
Root redirect to login/notes |
GET |
/health |
Health check endpoint |
GET |
/login |
Login page |
POST |
/login |
Process login |
POST |
/logout |
Logout user |
GET |
/notes |
List all notes |
GET |
/notes/new |
Create note form |
POST |
/notes |
Create new note |
GET |
/notes/{id} |
Edit note form |
POST |
/notes/{id} |
Update note |
DELETE |
/notes/{id} |
Delete note |
GET |
/upload |
File upload page |
POST |
/upload |
Process file upload (encrypted) |
GET |
/notes/{id}/preview |
Preview note as HTML (encrypted) |
GET |
/api/notes |
JSON API: Get notes (encrypted) |
GET |
/api/notes/{id}/preview |
JSON API: Preview markdown (encrypted) |
Comprehensive testing guide available in TEST.md.
# Basic health check
curl http://localhost:8080/health
# Run manual tests
python test_basic.py- Authentication flow (login/logout)
- Dynamic AES key prompt and management
- Key persistence across sessions (localStorage)
- Automatic key re-prompt on decryption failures
- Note CRUD operations with encryption
- File upload functionality (.txt and .md files)
- Client-side encryption/decryption
- Preview functionality with encrypted content
- Search capability (server-side on unencrypted data)
- Responsive design
- Security features (CSRF, sessions, dynamic encryption)
- Browser compatibility (Web Crypto API)
- Error handling
- Performance
- Follow setup instructions above
- Use Firestore emulator for testing
- Run with
--reloadfor development
- Set up GCP project and Firestore
- Configure
app.yamlwith production values - Deploy with
gcloud app deploy - Verify deployment and test functionality
Detailed deployment instructions in DEPLOYMENT.md.
- Firestore: 50K reads, 20K writes per day
- App Engine Standard: 28 instance hours per day
- Estimated cost: $6-20/month for low-traffic single user
- Auto-scaling: Scales to zero when not in use
- Resource-based pricing: Pay for CPU, memory, disk usage
| Variable | Description | Example |
|---|---|---|
USERNAME |
Admin username | admin |
PASSWORD_HASH |
SHA256 hash of password | 5e8848... |
FIRESTORE_PROJECT |
GCP project ID | my-notes-app-123 |
SECRET_KEY |
JWT signing key | Random 32+ chars |
AES_KEY |
User encryption key | Any string (SHA-256 hashed) |
ENVIRONMENT |
Runtime environment | development/production |
π User-Controlled Keys: The application uses a dynamic AES key system where users provide their own encryption keys.
How It Works:
- Server: Set
AES_KEYenvironment variable with your chosen key - Client: Users are prompted to enter the same key when accessing notes
- Key Derivation: SHA-256 hashing converts any string to a proper 32-byte AES key
- Storage: Only the SHA-256 hash is stored in browser localStorage
Setting Up Encryption:
- Set
AES_KEYenvironment variable (any string) - Share the key securely with users who need access
- Users enter the key when prompted on
/notespages - The system handles key derivation and storage automatically
Security Features:
- Raw keys never stored in browser
- Automatic re-prompt on decryption failures
- Consistent SHA-256 key derivation
- Clean modal interface for key entry
See DEPLOYMENT.md for detailed setup and troubleshooting.
- Session expiry: 24 hours
- CSRF tokens: Required for state-changing operations
- Password hashing: SHA256 (as per requirements)
- Cookie security: HttpOnly, Secure (in production), SameSite
- Encryption: AES-GCM 256-bit, 12-byte nonce, Base64 encoding
- Browser requirements: Modern browser with Web Crypto API support
- Auto-scaling: 0-2 instances
- Memory: 1GB default
- CPU: 1 vCPU default
- Disk: 10GB default
This is a single-user application designed for personal use. However, if you'd like to extend or improve it:
- Fork the repository
- Create a feature branch
- Make your changes
- Test thoroughly
- Submit a pull request
- Follow existing code patterns
- Maintain security standards
- Update documentation
- Test all changes
- Consider mobile responsiveness
This project is licensed under the MIT License - see the LICENSE file for details.
PRD.md- Requirements and specificationsPLAN.md- Implementation detailsDEPLOYMENT.md- Deployment guideTEST.md- Testing procedures
Common issues and solutions:
- Login not working: Check password hash in environment variables
- Firestore errors: Verify project ID and authentication setup
- CSS not loading: Check static file configuration
- Deployment fails: Review GCP project settings and quotas
- Encryption errors: Ensure browser supports Web Crypto API
- Key prompt not appearing: Clear localStorage and reload
/notespages - Decryption failures: Verify AES_KEY matches between server and user input
- Old data unreadable: AES_KEY environment variable may have changed
- Check application logs:
gcloud app logs tail - Review Firestore console for data issues
- Verify environment variables are set correctly
- Test locally before deploying
Built with β€οΈ using FastAPI and Google Cloud Platform
A secure, efficient, and user-friendly solution for personal markdown note management.