Harden private SQLite state filesystem boundaries #891

Closed
opened 2026-08-15 12:22:40 +00:00 by timmy · 0 comments
Owner

Evidence

Private operator state databases are created with inconsistent filesystem protection. Current store constructors for Today, Later, saved searches, drafts, security events, and idempotency create parent directories/connect directly, while only a subset of stores enforce private modes. Under a normal umask 022, sensitive issue drafts, work history, searches, device labels, and mutation receipts can remain mode 0644. No historical issue title or recent commit covers a shared private-state filesystem boundary.

Product/security slice

Introduce one shared private SQLite path guard and adopt it across every durable private store. The guard must create/repair the state directory to 0700, create/repair database plus SQLite WAL/SHM sidecars to 0600, reject symlink database paths, and preserve existing store behavior. This protects the full signed-in/offline workflow without requiring operators to tune umask.

Acceptance tests

  • Under umask 022, each private store creates its directory as 0700 and database as 0600.
  • Opening a pre-existing permissive database repairs its mode without losing rows.
  • WAL and SHM sidecars are 0600 while a WAL connection is active.
  • A symlink database path is rejected before SQLite reads or writes the target.
  • Existing store-focused tests and the full suite pass.
  • Documentation states the enforced filesystem boundary and its limits (host access/backups still require encryption controls).
## Evidence Private operator state databases are created with inconsistent filesystem protection. Current store constructors for Today, Later, saved searches, drafts, security events, and idempotency create parent directories/connect directly, while only a subset of stores enforce private modes. Under a normal `umask 022`, sensitive issue drafts, work history, searches, device labels, and mutation receipts can remain mode `0644`. No historical issue title or recent commit covers a shared private-state filesystem boundary. ## Product/security slice Introduce one shared private SQLite path guard and adopt it across every durable private store. The guard must create/repair the state directory to `0700`, create/repair database plus SQLite WAL/SHM sidecars to `0600`, reject symlink database paths, and preserve existing store behavior. This protects the full signed-in/offline workflow without requiring operators to tune umask. ## Acceptance tests - Under `umask 022`, each private store creates its directory as `0700` and database as `0600`. - Opening a pre-existing permissive database repairs its mode without losing rows. - WAL and SHM sidecars are `0600` while a WAL connection is active. - A symlink database path is rejected before SQLite reads or writes the target. - Existing store-focused tests and the full suite pass. - Documentation states the enforced filesystem boundary and its limits (host access/backups still require encryption controls).
timmy self-assigned this 2026-08-15 12:22:40 +00:00
timmy closed this issue 2026-08-15 12:33:36 +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#891
No description provided.