๐ KeyLocker โ Protocol Files
The 5 workflow files from github.com/mccloudmedia/keylocker
BRIEF.md
SPEC.md
ARCHITECTURE.md
TASKS.md
DEPLOY.md
# KeyLocker โ Brief
**One-line:** A single-user, self-hosted API key manager for developers who need keys at their fingertips without the friction of a password manager.
**The problem:** Developers manage dozens of API keys across multiple providers and applications. Password managers treat keys like passwords โ too slow to retrieve mid-flow. Developers resort to `.env` files, unencrypted text files, or memorizing keys, which is insecure and breaks flow.
**Core features:**
- Add a key in under 10 seconds (name, key, provider, app)
- One-click copy + 30-second automatic clipboard clearing
- Search and filter by name, provider, application, environment
- Direct one-click links to every provider's key management page
- AES-256-GCM encryption at rest with Argon2id key derivation
- Keyboard-driven interface (Ctrl+N, Ctrl+F, Ctrl+L, Ctrl+K)
- Four themes: Dark, Sepia, Slate, Light โ switch with `[` / `]`
**Success looks like:** A developer can go from "I need my Stripe prod key" to having it pasted in their terminal in under 3 seconds.
**Constraints:**
- Single-user, single-session (no team features in v1)
- No browser extension (webapp first, extension later)
- No PWA / offline support in v1
- Self-hosted only โ no cloud sync
- Encryption is unrecoverable by design โ lose the master password, lose everything
Full SPEC.md on GitHub:
https://github.com/mccloudmedia/keylocker/blob/main/SPEC.md
Screens: Lock Screen ยท Key List ยท Add/Edit Modal ยท Command Palette (Ctrl+K)
Data Model: keys (encrypted) ยท providers ยท settings
Encryption: Master Password โ Argon2id โ 256-bit key โ AES-256-GCM
Rules: clipboard auto-clear, session, search, provider URLs
Edge cases: 11 scenarios (empty state, duplicate names, lost password, etc.)
Stress test: 12 scenarios ร capability matrix
Non-goals: 10 items explicitly excluded from v1
# KeyLocker โ Architecture
## Overview
Single-user, self-hosted API key management webapp. Server-rendered HTML with a dense TUI-style interface, encrypted at rest, keyboard-driven. Deployed via Docker on vps-apps behind Traefik.
## Tech Stack
| Layer | Choice | Rationale |
|---|---|---|
| Backend | FastAPI (Python) | Lightweight, well-audited crypto |
| Frontend | Server-rendered HTML + CSS + JS | No SPA needed |
| Database | SQLite (single file) | Zero ops overhead |
| Encryption | AES-256-GCM + Argon2id | Battle-tested |
| Container | Docker (nginx + gunicorn) | Minimal footprint |
| Deploy | vps-apps โ `keys.mccloud.media` | Traefik + SSL |
## Encryption Architecture
```
Master Password
โ
Argon2id (salt stored in settings table)
โ
256-bit derived key (memory only โ never stored)
โ
AES-256-GCM encrypt/decrypt each key's `encrypted_key` field
โ
Per-key random 12-byte nonce prepended to ciphertext
```
## Data Model
**keys table:** id, name, encrypted_key, provider, application, environment, expires_at, permissions, notes, provider_url, created_at, updated_at, version
**providers table:** id, name, key_url, is_builtin
**settings table:** theme, clipboard_clear_seconds, key (salt + params)
## Key Rules
- Clipboard auto-clear: 30s (configurable)
- Session: until explicit lock (Ctrl+L)
- Search: case-insensitive substring on name/provider/application
- Master password lost: irrecoverable
## Non-Goals (v1)
No multi-user ยท No browser ext ยท No CLI ยท No PWA ยท No export ยท No audit log ยท No mobile
# KeyLocker โ Tasks
## Phase 1: Foundation (DONE)
- [x] Product ideation & problem definition
- [x] SPEC.md written with data model, screens, edge cases, stress test
- [x] Tech stack selected (FastAPI + SQLite + AES-256-GCM)
- [x] Repo initialized at `/opt/data/keylocker/`
## Phase 2: Backend Core
- [ ] Scaffold FastAPI project structure โ `app/`, `requirements.txt`, config
- [ ] Encryption module โ Argon2id KDF + AES-256-GCM encrypt/decrypt
- [ ] SQLite schema โ `keys`, `providers`, `settings` tables
- [ ] First-run setup โ create master password, generate salt, initialize DB
- [ ] CRUD endpoints for keys โ list, create, read, update, delete
- [ ] Provider endpoints โ list built-in + custom providers
- [ ] Settings endpoints โ theme, clipboard timer
- [ ] Session management โ master password auth, lock/unlock
## Phase 3: Frontend
- [ ] Lock screen โ master password entry
- [ ] Main screen โ key table with search + filters
- [ ] Add/Edit key modal
- [ ] Command palette โ Ctrl+K
- [ ] Copy-to-clipboard with auto-clear
- [ ] Theme system โ Dark / Sepia / Slate / Light
- [ ] Keyboard shortcuts โ Ctrl+N, Ctrl+F, Ctrl+L, `[` / `]`
- [ ] Provider quick-link submenu
## Phase 4: Polish & Security
- [ ] Empty / error / loading states
- [ ] Clipboard denied fallback
- [ ] Optimistic locking
- [ ] Input validation & sanitization
- [ ] Secret stripping
- [ ] XSS / CSRF protections
- [ ] DB file permissions (600)
## Phase 5: Deploy
- [ ] Dockerfile โ gunicorn + nginx:alpine
- [ ] `.dockerignore`
- [ ] Docker Compose / docker run + Traefik labels
- [ ] Deploy to vps-apps โ `keys.mccloud.media`
- [ ] Smoke test every flow in production
## Decisions Log
| Decision | Rationale |
|---|---|
| Single-user, Path A | Ship fast, generalize later |
| Webapp first, ext later | Immediate value |
| Ctrl+L lock, no timeout | Don't break dev flow |
| Clipboard auto-clear 30s | Standard security |
| TUI-style dense layout | Proven design preference |
# KeyLocker โ Deploy
## Target
| Thing | Value |
|---|---|
| Server | vps-apps (72.62.96.149) |
| Domain | `keys.mccloud.media` |
| Method | Docker + Traefik, SSH via key auth |
| Service name | `keylocker` |
## Container Setup
Build stage: gunicorn serving FastAPI.
Serving stage: nginx:alpine (reverse proxy to gunicorn).
## Traefik Labels
```
traefik.enable=true
traefik.http.routers.keylocker-http.rule=Host(`keys.mccloud.media`)
traefik.http.routers.keylocker-http.entrypoints=http
traefik.http.routers.keylocker.entrypoints=https
traefik.http.routers.keylocker.tls=true
traefik.http.routers.keylocker.tls.certResolver=letsencrypt
```
## Volumes
- `keylocker-data:/app/data` (persistent SQLite DB)
- Docker socket for container management
## Post-Deploy Verification
1. Visit `https://keys.mccloud.media` โ lock screen renders
2. Create master password โ first-run flow works
3. Add a test key โ encrypt and store
4. Lock and re-unlock โ session persists
5. Copy a key โ clipboard timer counts down
Created by the app-ideation-workflow skill ยท github.com/mccloudmedia/keylocker