Research: JWT authentication selected
- Comprehensive JWT research completed - JWT with refresh tokens selected (9.5/10 score) - Token revocation strategies (blacklist + versioning) - Refresh token pattern (token rotation) - Zero-knowledge password recovery integration - Family member access control (permissions in JWT) Key decisions: - Access tokens: 15 minutes (short-lived) - Refresh tokens: 30 days (long-lived, stored in MongoDB) - Token rotation: Prevents reuse of stolen tokens - Token versioning: Invalidate all tokens on password change - Recovery phrases: Zero-knowledge password recovery from encryption.md - Family permissions: parent, child, elderly roles Updated tech stack decisions Next: Database schema design (MongoDB collections)
This commit is contained in:
parent
195ba2ec4e
commit
203c0b4331
3 changed files with 1560 additions and 26 deletions
174
thoughts/research/2026-02-14-jwt-authentication-decision.md
Normal file
174
thoughts/research/2026-02-14-jwt-authentication-decision.md
Normal file
|
|
@ -0,0 +1,174 @@
|
||||||
|
# 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**:
|
||||||
|
1. Client sends refresh_token
|
||||||
|
2. Server verifies refresh_token (not revoked, not expired)
|
||||||
|
3. Server generates new access_token
|
||||||
|
4. Server generates new refresh_token
|
||||||
|
5. Server revokes old refresh_token
|
||||||
|
6. Server returns new tokens
|
||||||
|
|
||||||
|
**Why?** Prevents reuse of stolen refresh tokens
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Zero-Knowledge Password Recovery
|
||||||
|
|
||||||
|
### Recovery Phrases (from encryption.md)
|
||||||
|
|
||||||
|
**Registration**:
|
||||||
|
1. Client generates recovery phrase (random 32 bytes)
|
||||||
|
2. Client encrypts recovery phrase with password
|
||||||
|
3. Client sends: email, password hash, encrypted recovery phrase
|
||||||
|
4. Server stores: email, password hash, encrypted recovery phrase
|
||||||
|
|
||||||
|
**Password Recovery**:
|
||||||
|
1. User requests recovery (enters email)
|
||||||
|
2. Server returns: encrypted recovery phrase
|
||||||
|
3. Client decrypts with recovery key (user enters manually)
|
||||||
|
4. User enters new password
|
||||||
|
5. Client re-encrypts recovery phrase with new password
|
||||||
|
6. Client sends: new password hash, re-encrypted recovery phrase
|
||||||
|
7. Server updates: password hash, encrypted recovery phrase, token_version + 1
|
||||||
|
8. All existing tokens invalidated (version mismatch)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Family Member Access Control
|
||||||
|
|
||||||
|
### Permissions in JWT
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// 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
|
||||||
|
|
||||||
|
1. Implement basic JWT service in Axum
|
||||||
|
2. Create MongoDB schema for users and refresh tokens
|
||||||
|
3. Implement login/register/refresh/logout handlers
|
||||||
|
4. Create JWT middleware for protected routes
|
||||||
|
5. Implement token revocation (blacklist + versioning)
|
||||||
|
6. Integrate password recovery (from encryption.md)
|
||||||
|
7. Implement family access control (permissions)
|
||||||
|
8. Test entire authentication flow
|
||||||
|
9. Create client-side authentication (React Native + React)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- [Comprehensive JWT Research](./2026-02-14-jwt-authentication-research.md)
|
||||||
|
- [Normogen Encryption Guide](../encryption.md)
|
||||||
|
- [JWT RFC 7519](https://tools.ietf.org/html/rfc7519)
|
||||||
|
- [Axum JWT Guide](https://docs.rs/axum/latest/axum/)
|
||||||
|
- [OWASP JWT Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/JSON_Web_Token_for_Java_Cheat_Sheet.html)
|
||||||
1340
thoughts/research/2026-02-14-jwt-authentication-research.md
Normal file
1340
thoughts/research/2026-02-14-jwt-authentication-research.md
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -74,12 +74,35 @@
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### 5. Authentication: JWT with Refresh Tokens
|
||||||
|
**Decision**: JWT (JSON Web Tokens) with Refresh Tokens + Recovery Phrases
|
||||||
|
|
||||||
|
**Score**: 9.5/10
|
||||||
|
|
||||||
|
**Rationale**:
|
||||||
|
- **Stateless design**: Scales to 1000+ concurrent connections (no session storage)
|
||||||
|
- **Mobile-friendly**: Works perfectly with React Native (AsyncStorage)
|
||||||
|
- **Zero-knowledge compatible**: Integrates with recovery phrases from encryption.md
|
||||||
|
- **Token revocation**: Refresh token blacklist (MongoDB) + token versioning
|
||||||
|
- **Token rotation**: Prevents reuse of stolen refresh tokens
|
||||||
|
- **Family access control**: Permissions in JWT claims (parent, child, elderly)
|
||||||
|
- **Security best practices**: Short-lived access tokens (15 min), long-lived refresh tokens (30 days)
|
||||||
|
|
||||||
|
**Trade-offs**:
|
||||||
|
- Revocation requires storage (MongoDB for refresh tokens, optional Redis for access tokens)
|
||||||
|
- More complex than sessions (but better for scaling)
|
||||||
|
|
||||||
|
**Reference**: [2026-02-14-jwt-authentication-research.md](./2026-02-14-jwt-authentication-research.md)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Technology Stack Summary
|
## Technology Stack Summary
|
||||||
|
|
||||||
### Backend
|
### Backend
|
||||||
- **Framework**: Axum 0.7.x
|
- **Framework**: Axum 0.7.x
|
||||||
- **Runtime**: Tokio 1.x
|
- **Runtime**: Tokio 1.x
|
||||||
- **Middleware**: Tower, Tower-HTTP
|
- **Middleware**: Tower, Tower-HTTP
|
||||||
|
- **Authentication**: JWT with refresh tokens
|
||||||
- **Database**: MongoDB (with zero-knowledge encryption)
|
- **Database**: MongoDB (with zero-knowledge encryption)
|
||||||
- **Language**: Rust
|
- **Language**: Rust
|
||||||
|
|
||||||
|
|
@ -88,6 +111,7 @@
|
||||||
- **Language**: TypeScript
|
- **Language**: TypeScript
|
||||||
- **State Management**: Redux Toolkit 2.x
|
- **State Management**: Redux Toolkit 2.x
|
||||||
- **Data Fetching**: RTK Query 2.x
|
- **Data Fetching**: RTK Query 2.x
|
||||||
|
- **Authentication**: JWT with AsyncStorage
|
||||||
- **Navigation**: React Navigation
|
- **Navigation**: React Navigation
|
||||||
- **Health Sensors**:
|
- **Health Sensors**:
|
||||||
- react-native-health (iOS HealthKit)
|
- react-native-health (iOS HealthKit)
|
||||||
|
|
@ -102,6 +126,7 @@
|
||||||
- **Language**: TypeScript
|
- **Language**: TypeScript
|
||||||
- **State Management**: Redux Toolkit 2.x
|
- **State Management**: Redux Toolkit 2.x
|
||||||
- **Data Fetching**: RTK Query 2.x
|
- **Data Fetching**: RTK Query 2.x
|
||||||
|
- **Authentication**: JWT with localStorage (or httpOnly cookies)
|
||||||
- **Routing**: React Router
|
- **Routing**: React Router
|
||||||
- **Charts**: Recharts
|
- **Charts**: Recharts
|
||||||
- **Persistence**: Redux Persist 6.x (localStorage)
|
- **Persistence**: Redux Persist 6.x (localStorage)
|
||||||
|
|
@ -122,23 +147,7 @@
|
||||||
|
|
||||||
## Still To Be Decided
|
## Still To Be Decided
|
||||||
|
|
||||||
### 1. Authentication Strategy (Priority: High)
|
### 1. Database Schema (Priority: High)
|
||||||
|
|
||||||
**Options**:
|
|
||||||
- JWT (stateless, scalable)
|
|
||||||
- Session-based (traditional, easier revocation)
|
|
||||||
- Passkey/WebAuthn (passwordless, modern)
|
|
||||||
|
|
||||||
**Considerations for Normogen**:
|
|
||||||
- Zero-knowledge password recovery (from encryption.md)
|
|
||||||
- Token revocation strategy
|
|
||||||
- Multi-factor authentication (future)
|
|
||||||
- Integration with client-side encryption keys
|
|
||||||
- Family member access control
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 2. Database Schema (Priority: High)
|
|
||||||
|
|
||||||
**Collections to Design**:
|
**Collections to Design**:
|
||||||
- Users (authentication, profiles)
|
- Users (authentication, profiles)
|
||||||
|
|
@ -148,6 +157,16 @@
|
||||||
- Medications (encrypted medication data)
|
- Medications (encrypted medication data)
|
||||||
- Appointments (encrypted appointment data)
|
- Appointments (encrypted appointment data)
|
||||||
- Shared Links (time-limited access tokens)
|
- Shared Links (time-limited access tokens)
|
||||||
|
- Refresh Tokens (JWT refresh token storage)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2. API Architecture (Priority: Medium)
|
||||||
|
|
||||||
|
**Options**:
|
||||||
|
- REST (current plan)
|
||||||
|
- GraphQL (alternative)
|
||||||
|
- gRPC (for microservices)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -156,8 +175,8 @@
|
||||||
1. Rust Framework: Axum (COMPLETED)
|
1. Rust Framework: Axum (COMPLETED)
|
||||||
2. Mobile/Web Framework: React Native + React (COMPLETED)
|
2. Mobile/Web Framework: React Native + React (COMPLETED)
|
||||||
3. State Management: Redux Toolkit 2.x (COMPLETED)
|
3. State Management: Redux Toolkit 2.x (COMPLETED)
|
||||||
4. Authentication: JWT with recovery phrase
|
4. Authentication: JWT with refresh tokens (COMPLETED)
|
||||||
5. Database Schema: Design MongoDB collections
|
5. Database Schema: Design MongoDB collections (NEXT)
|
||||||
6. Create POC: Health sensor integration test
|
6. Create POC: Health sensor integration test
|
||||||
7. Implement Core Features: Authentication, encryption, CRUD
|
7. Implement Core Features: Authentication, encryption, CRUD
|
||||||
|
|
||||||
|
|
@ -165,13 +184,14 @@
|
||||||
|
|
||||||
## Next Research Priority
|
## Next Research Priority
|
||||||
|
|
||||||
**Research Question**: How to implement zero-knowledge authentication with JWT and recovery phrase support?
|
**Research Question**: What should the MongoDB schema look like for Normogen's encrypted health data platform?
|
||||||
|
|
||||||
**Considerations**:
|
**Considerations**:
|
||||||
- Zero-knowledge password recovery (from encryption.md)
|
- Zero-knowledge encryption (all sensitive data encrypted)
|
||||||
- Token revocation strategy
|
- Family structure (parents, children, elderly)
|
||||||
- Multi-factor authentication (future)
|
- Health data types (lab results, medications, appointments)
|
||||||
- Integration with client-side encryption keys
|
- Refresh tokens (JWT storage)
|
||||||
- Family member access control
|
- Shared links (time-limited access)
|
||||||
|
- Permissions (family member access control)
|
||||||
|
|
||||||
**Estimated Research Time**: 2-3 hours
|
**Estimated Research Time**: 3-4 hours
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue