docs: decide multi-person ZK sharing ADR; reconcile jwt/encryption docs
Some checks failed
Lint and Build / format (pull_request) Successful in 37s
Lint and Build / clippy (pull_request) Successful in 1m40s
Lint and Build / build (pull_request) Successful in 3m44s
Lint and Build / test (pull_request) Failing after 0s

Rewrite the encryption/persona/JWT docs to match the implemented code and
record the multi-person sharing design.

- multi-person-sharing.md (NEW): ADR for per-profile DEK + X25519 envelope
  sharing. All five original open questions resolved 2026-07-18. Covers
  divorced-parents, pets, graduation, and elderly-parent care; adds an
  admin permission tier for owner-incapacity. Decided, not yet implemented.
  (#3)
- encryption.md: full rewrite to the implemented wrapped-DEK / Web Crypto
  model; the old version described ZK encryption as 'planned'. (#4)
- jwt-authentication-decision.md: rewritten to match implementation
  (PBKDF2 not bcrypt, no Redis, token_version revocation, real Claims).
  Original aspirational content preserved in a History section. (#4)
- PERSONA_AND_FAMILY_MANAGEMENT.md: 'Current reality' section added, old
  'Implementation Status' marked superseded, encryption section corrected. (#4)
- ENCRYPTION_UPDATE_SUMMARY.md: archived (changelog for a rewrite that
  itself went stale). (#4)
- ADR README index updated for the new + reconciled entries.
This commit is contained in:
goose 2026-07-18 19:26:43 -03:00
parent 6a569da3b1
commit e322145ffb
6 changed files with 737 additions and 990 deletions

View file

@ -1,105 +0,0 @@
# Encryption.md Update Summary
**Date**: 2026-03-09
**File**: docs/product/encryption.md
**Update**: Added Rust implementation examples and current status
---
## Changes Made
### 1. Added Implementation Status Section 🆕
- Currently implemented features marked with ✅
- Planned features marked with 📋
- Clear distinction between design and implementation
### 2. Added Rust Implementation Examples 🆕
**Current Security Features**:
- JWT Authentication Service (actual code from `backend/src/auth/mod.rs`)
- Password Hashing with PBKDF2 (100,000 iterations)
- Rate Limiting Middleware (tower-governor)
- Account Lockout Service (exponential backoff)
- Security Audit Logger (MongoDB logging)
**Proposed Encryption Features**:
- Encryption Service design (AES-256-GCM)
- Encrypted Health Data Model
- Deterministic Encryption for searchable fields
- Key Management Strategy
- Shareable Links implementation
### 3. Updated Code Examples
- Replaced JavaScript/Node.js examples with Rust
- Used actual implementation from Normogen codebase
- Added real-world examples from existing code
- Maintained theoretical examples for planned features
### 4. Added Comparison Table
- Current Implementation vs Proposed
- Implementation status for all features
- Priority and complexity ratings
### 5. Updated Dependencies
- Listed currently used crates (jsonwebtoken, pbkdf2, etc.)
- Proposed additions for encryption features
---
## File Statistics
### Before
- Size: 32KB
- Lines: 1,248
- Language: JavaScript/Node.js examples
- Focus: Theoretical design
### After
- Size: 28KB (slightly smaller)
- Lines: ~1,100
- Language: Rust examples (matching backend)
- Focus: Current implementation + future design
---
## Key Improvements
1. **Accurate**: Reflects actual implementation status
2. **Rust-focused**: Matches backend technology
3. **Practical**: Real code from codebase, not just theory
4. **Clear**: Distinguishes between implemented and planned
5. **Comprehensive**: Covers current security + future encryption
---
## Implementation Coverage
### Currently Implemented ✅
- JWT authentication (15min access, 30day refresh)
- PBKDF2 password hashing (100K iterations)
- Rate limiting (15 req/s, burst 30)
- Account lockout (5 attempts, exponential backoff)
- Security audit logging
- Session management
### Planned for Future 📋
- End-to-end encryption
- Client-side encryption
- Zero-knowledge encryption
- Shareable links with embedded passwords
- Key rotation
---
## Next Steps
1. ✅ Document current security implementation
2. ✅ Add Rust code examples
3. 📋 Implement zero-knowledge encryption (Phase 3+)
4. 📋 Add client-side encryption
5. 📋 Implement shareable links
---
**Update Complete**: 2026-03-09
**Status**: Documentation now matches actual implementation
**Quality**: Improved accuracy and relevance

View file

@ -1,10 +1,16 @@
# Persona and Family Management - Product Definition
**Document Version**: 1.0
**Date**: 2026-03-09
**Status**: Draft - For Refinement
**Document Version**: 1.1
**Date**: 2026-07-18 (reconciled with code; original draft 2026-03-09)
**Status**: Vision doc — implementation status section corrected to match code
**Purpose**: Consolidate all current information about persona and family management features for further product refinement
> **How to read this doc.** Sections marked **Vision** describe the target
> product and are still valid for discussion. Sections marked **Today (code)**
> describe what is actually implemented and have been verified against the
> codebase as of 2026-07-18. Where the two diverge, the gap is called out and
> linked to the relevant Forgejo issue.
---
## 📋 Table of Contents
@ -35,6 +41,28 @@ Normogen supports **multi-person health data management** through a persona and
---
## Current reality (as of 2026-07-18)
This section corrects the earlier "Current Implementation Status" section below,
which described an earlier state. Verified against the code:
| Capability | Status | Notes |
|---|---|---|
| Single profile per user account | ✅ Done | `GET/PUT /api/profiles/me`; profile is auto-created as `profile_{user_id}` at registration. Display name is client-encrypted. |
| Multi-profile (child/dependent) within one account | ❌ Not built | `ProfileRepository::find_by_user_id` returns a single profile; no create/list/switch endpoints. `profileId` can be tagged onto medications but there is no backing entity beyond the owner's. |
| Family groups | ❌ Not built | `Family` model exists but has **no handler and no routes**. JWT carries `family_id` but nothing populates or checks it. |
| Cross-user sharing (spouse, caregiver) | ❌ **Blocked by design** | `/api/shares` routes exist but cannot grant decryption access — all data is encrypted under the owner's DEK and there is no key-distribution mechanism. See **[issue #3](https://gitea.soliverez.com.ar/alvaro/normogen/issues/3)**. |
| Caregiver roles / permissions | ❌ Not built | `permissions` field exists on Profile and in JWT claims but is not enforced. |
| Zero-knowledge encryption of health data | ✅ Done | Client-side Web Crypto, wrapped-DEK recovery. See [`encryption.md`](encryption.md). |
**Implication for the family/caregiver personas below:** the single biggest
open question is architectural — *how does sharing work under zero-knowledge?*
That must be decided before family/caregiver features can be implemented. Until
then, the realistic near-term scope is **multi-profile within a single account**
(one login managing several people's data, no cross-account sharing).
---
## User Personas
### Primary: Privacy-Conscious Individual
@ -167,7 +195,12 @@ User Account: jane.doe@example.com (Jane)
---
## Current Implementation Status
## Current Implementation Status (superseded — see "Current reality" above)
> The detail below was written 2026-03-09 against an earlier state and
> overstates what existed then. It is retained for history. For the accurate
> current picture, read the **Current reality** section near the top of this
> document, and [`encryption.md`](encryption.md) for encryption.
### ✅ Implemented (Backend)
@ -595,16 +628,23 @@ if profile.role == "child" || profile.age < 18 {
### Encryption
**Zero-Knowledge Encryption**:
- Profile names are encrypted (AES-256-GCM)
- Family names are encrypted
- Only users with correct password can decrypt
- Server cannot see profile names
> **Correction (2026-07-18):** the bullets below described a planned
> server-side scheme that was never built. The shipped system is
> **client-side** zero-knowledge via the browser's Web Crypto API with a
> wrapped-DEK model. The server has no crypto code at all — it is a blind
> store. Profile/medication/appointment data is encrypted in the browser
> before upload and the server cannot read any of it. Full details:
> [`encryption.md`](encryption.md) and
> [`adr/zero-knowledge-encryption.md`](../adr/zero-knowledge-encryption.md).
**Encrypted Fields**:
- `profile.name` - Person's name
- `family.name` - Family group name
- Medication data (when implemented)
**What's actually encrypted (client-side, today):**
- Medication data blob (name, dosage, frequency, route, notes, …)
- Appointment data blob (title, provider, date/time, …)
- Profile display name
**What stays plaintext (queryable by the server):**
- IDs (`profileId`, `medicationId`, `userId`, `appointmentId`)
- Medication `active` flag, appointment `status`, `doseSchedule`, timestamps
---

File diff suppressed because it is too large Load diff