Encrypt synchronized unfiled drafts at rest #1098

Closed
opened 2026-08-18 21:54:40 +00:00 by timmy · 0 comments
Owner

Evidence

Synchronized unfiled drafts currently serialize private titles, bodies, planning metadata, blocker names, evidence notes, and screenshot bytes as plaintext JSON in src/unfiled_draft_store.py. The existing owner-only SQLite boundary shipped in #891 protects filesystem permissions but explicitly does not provide encryption at rest. No open issue, historical issue title, open PR, or recent commit covers encrypted unfiled-draft payloads.

User impact

A copied database, snapshot, or backup should not reveal private cross-device draft content without the independently injected encryption key. Existing synchronized drafts must remain readable and migrate without losing revision/conflict behavior.

Acceptance criteria

  • Encrypt every newly stored unfiled-draft collection with authenticated encryption and bind ciphertext to the normalized account identity.
  • Read existing plaintext rows and migrate them to encrypted storage without changing revision or draft order.
  • Fail closed on missing, malformed, tampered, or wrong-key ciphertext; never return partial or fabricated draft state.
  • Preserve collection/evidence bounds, account isolation, optimistic conflicts, API cache controls, and cross-device sync behavior.
  • Document secret injection and rotation/recovery constraints; never commit key material.
  • Add behavioral tests that prove ciphertext hides title/body/evidence, legacy migration works, tampering is rejected, focused tests pass, and the full suite stays green.
## Evidence Synchronized unfiled drafts currently serialize private titles, bodies, planning metadata, blocker names, evidence notes, and screenshot bytes as plaintext JSON in `src/unfiled_draft_store.py`. The existing owner-only SQLite boundary shipped in #891 protects filesystem permissions but explicitly does not provide encryption at rest. No open issue, historical issue title, open PR, or recent commit covers encrypted unfiled-draft payloads. ## User impact A copied database, snapshot, or backup should not reveal private cross-device draft content without the independently injected encryption key. Existing synchronized drafts must remain readable and migrate without losing revision/conflict behavior. ## Acceptance criteria - Encrypt every newly stored unfiled-draft collection with authenticated encryption and bind ciphertext to the normalized account identity. - Read existing plaintext rows and migrate them to encrypted storage without changing revision or draft order. - Fail closed on missing, malformed, tampered, or wrong-key ciphertext; never return partial or fabricated draft state. - Preserve collection/evidence bounds, account isolation, optimistic conflicts, API cache controls, and cross-device sync behavior. - Document secret injection and rotation/recovery constraints; never commit key material. - Add behavioral tests that prove ciphertext hides title/body/evidence, legacy migration works, tampering is rejected, focused tests pass, and the full suite stays green.
timmy self-assigned this 2026-08-18 21:54:40 +00:00
timmy closed this issue 2026-08-18 22:27:54 +00:00
Sign in to join this conversation.
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: stackchain/stackchain-dashboard#1098
No description provided.