Make the project's documentation match the code and remove the sprawl. The docs
claimed Phase 2.8 (drug interactions) was 'planning/0%' and the backend '~91%
complete' — both wrong: 2.8 is implemented and live, plus the P0/P1 security
and test work is done. Five root CI/CD docs described a 'docker-build' CI job
that was removed; ~18 backend/ status snapshots and ~24 docs/implementation
duplicates cluttered the tree.
Deletions (85 files):
- Root: 4 stale CI/CD reports (CI-CD-{COMPLETION-REPORT,IMPLEMENTATION-SUMMARY,
STATUS-REPORT,FINAL-STATUS}.md) — all describe the removed docker-build job.
- backend/: 18 phase/build/fix snapshots and code-dump .txt files.
- docs/: the 3 one-time reorg reports; ~17 docs/implementation duplicates and
process artifacts; 4 stale docs/development CI docs + git snapshots;
redundant deployment/testing files.
- thoughts/: STATUS.md (said Phase 2.4 in-progress), superseded phase notes and
duplicative research inputs. tmp/ (928KB of CI debug logs, gitignored).
Moves (18 files):
- 9 genuine decision records -> docs/adr/ (Architecture Decision Records),
date-prefixes stripped, with an index README.
- 8 historical-but-valuable phase plans/specs + the old CI-CD-FINAL-SOLUTION ->
docs/archive/ (now-populated, with a README explaining it's superseded
material). thoughts/ tree removed.
Rewrites (13 files) to match reality:
- Drop the fake '% complete' figures everywhere in favor of Implemented /
In-Progress / Planned with concrete endpoint/feature lists.
- Phase 2.8 -> Implemented; add /api/interactions/* and /api/auth/{refresh,
logout} to the endpoint lists; fix 'Rust 1.93' -> edition 2021.
- Add a Security section (token_version validation, hashed refresh-token
persistence, fail-fast config, real-IP audit) and correct the test-coverage
and deployment claims to reality.
- New canonical docs/development/CI-CD.md (4 jobs: format/clippy/build/test,
mongo service, no docker-build + why).
- README, docs/README, product/{STATUS,ROADMAP,PROGRESS,README,introduction},
implementation/README, development/README, testing/README, AI_AGENT_GUIDE,
.cursorrules, .gooserules all updated.
Verified: greps for 'Phase 2.8 (Planning)', 'PLANNING (0%)', 'Rust 1.93',
'91%/10%/85% complete', and 'docker-build' return nothing outside docs/archive;
all internal doc links resolve; backend/src untouched (cargo build clean).
4.3 KiB
4.3 KiB
JWT Authentication Decision Summary
Date: 2026-02-14 Decision: JWT with Refresh Tokens + Recovery Phrases
Authentication Strategy
Primary: JWT (JSON Web Tokens)
Why JWT?
- Stateless design scales to 1000+ concurrent connections
- Works perfectly with mobile apps (AsyncStorage)
- No server-side session storage needed
- Easy to scale Axum horizontally
Token Types
Access Token (15 minutes)
- Used for API requests
- Short-lived for security
- Contains: user_id, email, family_id, permissions
Refresh Token (30 days)
- Used to get new access tokens
- Long-lived for convenience
- Stored in MongoDB for revocation
- Rotated on every refresh
Token Revocation Strategies
1. Refresh Token Blacklist (Recommended) ⭐
- Store refresh tokens in MongoDB
- Mark as revoked on logout
- Check on every refresh
2. Token Versioning
- Include version in JWT claims
- Increment on password change
- Invalidate all tokens when version changes
3. Access Token Blacklist (Optional)
- Store revoked access tokens in Redis
- For immediate revocation
- Auto-expires with TTL
Refresh Token Pattern
Token Rotation (Security Best Practice) ⭐
Flow:
- Client sends refresh_token
- Server verifies refresh_token (not revoked, not expired)
- Server generates new access_token
- Server generates new refresh_token
- Server revokes old refresh_token
- Server returns new tokens
Why? Prevents reuse of stolen refresh tokens
Zero-Knowledge Password Recovery
Recovery Phrases (from encryption.md)
Registration:
- Client generates recovery phrase (random 32 bytes)
- Client encrypts recovery phrase with password
- Client sends: email, password hash, encrypted recovery phrase
- Server stores: email, password hash, encrypted recovery phrase
Password Recovery:
- User requests recovery (enters email)
- Server returns: encrypted recovery phrase
- Client decrypts with recovery key (user enters manually)
- User enters new password
- Client re-encrypts recovery phrase with new password
- Client sends: new password hash, re-encrypted recovery phrase
- Server updates: password hash, encrypted recovery phrase, token_version + 1
- All existing tokens invalidated (version mismatch)
Family Member Access Control
Permissions in JWT
// JWT permissions based on family role
{
"parent": [
"read:own_data",
"write:own_data",
"read:family_data",
"write:family_data",
"manage:family_members",
"delete:data"
],
"child": [
"read:own_data",
"write:own_data"
],
"elderly": [
"read:own_data",
"write:own_data",
"read:family_data"
]
}
Permission Middleware
- Check permissions on protected routes
- Return 403 Forbidden if insufficient permissions
- Works with JWT claims
Technology Stack
Backend (Axum)
- jsonwebtoken 9.x (JWT crate)
- bcrypt 0.15 (password hashing)
- mongodb 3.0 (refresh token storage)
- redis (optional, for access token blacklist)
Client (React Native + React)
- AsyncStorage (token storage)
- axios (API client with JWT interceptor)
- PBKDF2 (password derivation)
- AES-256-GCM (data encryption)
Implementation Timeline
- Week 1: Basic JWT (login, register, middleware)
- Week 1-2: Refresh tokens (storage, rotation)
- Week 2: Token revocation (blacklist, versioning)
- Week 2-3: Password recovery (recovery phrases)
- Week 3: Family access control (permissions)
- Week 3-4: Security hardening (rate limiting, HTTPS)
Total: 3-4 weeks
Next Steps
- Implement basic JWT service in Axum
- Create MongoDB schema for users and refresh tokens
- Implement login/register/refresh/logout handlers
- Create JWT middleware for protected routes
- Implement token revocation (blacklist + versioning)
- Integrate password recovery (from encryption.md)
- Implement family access control (permissions)
- Test entire authentication flow
- Create client-side authentication (React Native + React)