mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 22:01:09 +02:00
feat(crypto): Phase 2e — flip encryption on for tags/scenes/missions
Turns on at-rest encryption for the four tables staged in Phase 2a.
New writes now encrypt the user-typed fields; future code paths read
via decryptRecords as normal (the modules already call decrypt on
read, no changes needed).
Flipped:
- globalTags.name — tag names can leak categorization intent
- tagGroups.name — same
- workbenchScenes.name/description — scene labels often encode
Space-specific context
- aiMissions.title/conceptMarkdown/objective — mission configuration
is user-authored
Deliberately unchanged:
- color / icon / groupId / sortOrder / openApps / wallpaper /
scopeTagIds / cadence / state / agentId — all structural, indexed,
or FK data needed for query paths
- agents.name stays plaintext per the prior design note (Actor
displayName cache key)
Migration approach — pre-live lenient: decryptRecords skips values
that aren't encrypted (isEncrypted gate in record-helpers.ts:256), so
existing plaintext rows stay readable after the flip. New writes
encrypt; existing rows get encrypted organically as the user edits
them. No Dexie migration needed. A post-login "encrypt-at-rest
sweep" over pre-existing rows is a follow-up if hard at-rest coverage
is required before launch.
Crypto audit: 196 Dexie tables (95 encrypted, +4 vs 91 before),
101 allowlisted plaintext. Type-check clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
0f8fbb381b
commit
09e6a8b9df
1 changed files with 26 additions and 24 deletions
|
|
@ -574,17 +574,14 @@ export const ENCRYPTION_REGISTRY: Record<string, EncryptionConfig> = {
|
|||
agents: { enabled: true, fields: ['systemPrompt', 'memory'] },
|
||||
|
||||
// ─── AI Missions ─────────────────────────────────────────
|
||||
// docs/plans/space-scoped-data-model.md §2a — declared with
|
||||
// enabled:false during prep so the audit script is happy; flips to
|
||||
// true in 2c alongside the Dexie v35 encryption migration.
|
||||
//
|
||||
// docs/plans/space-scoped-data-model.md §2e — encryption enabled.
|
||||
// User-typed content on missions: `title` (display label the user
|
||||
// types at create time), `conceptMarkdown` (free-form context the
|
||||
// planner reads), `objective` (the actionable goal string). State,
|
||||
// cadence, inputs (FK-only), nextRunAt, iterations, agentId all
|
||||
// stay plaintext — needed for the Runner's "due now" index walk
|
||||
// and mission-detail filters.
|
||||
aiMissions: { enabled: false, fields: ['title', 'conceptMarkdown', 'objective'] },
|
||||
aiMissions: { enabled: true, fields: ['title', 'conceptMarkdown', 'objective'] },
|
||||
|
||||
// ─── User-level Tag Presets ──────────────────────────────
|
||||
// Named templates the user applies when creating a new Space. The
|
||||
|
|
@ -598,27 +595,32 @@ export const ENCRYPTION_REGISTRY: Record<string, EncryptionConfig> = {
|
|||
userTagPresets: { enabled: true, fields: ['name', 'tags'] },
|
||||
|
||||
// ─── Tags (shared-stores) ────────────────────────────────
|
||||
// docs/plans/space-scoped-data-model.md §2a — declared with
|
||||
// enabled:false during prep; flips to true in 2c. Tag names like
|
||||
// "Therapie" or "Finanzen-privat" can leak personal categorization,
|
||||
// so they belong under encryption. `color` + `icon` + `groupId` +
|
||||
// `sortOrder` stay plaintext: they're visual metadata + the group
|
||||
// FK, none of which leak sensitive taxonomy. `name` is NOT indexed
|
||||
// for .where() lookups today, so encrypting it is safe — dedupe-
|
||||
// within-space lookups go through the new [spaceId+name] index after
|
||||
// Phase 2b and run over already-decrypted rows in the scoped store.
|
||||
globalTags: { enabled: false, fields: ['name'] },
|
||||
tagGroups: { enabled: false, fields: ['name'] },
|
||||
// docs/plans/space-scoped-data-model.md §2e — encryption enabled.
|
||||
// Tag names like "Therapie" or "Finanzen-privat" can leak personal
|
||||
// categorization. `color` + `icon` + `groupId` + `sortOrder` stay
|
||||
// plaintext: they're visual metadata + the group FK, none of which
|
||||
// leak sensitive taxonomy. `name` is NOT indexed for .where()
|
||||
// lookups today, so encrypting it is safe — dedupe-within-space
|
||||
// lookups go through the [spaceId+name] index from 2b and run over
|
||||
// already-decrypted rows in the scoped store.
|
||||
//
|
||||
// Pre-live migration note: decryptRecords is lenient (isEncrypted()
|
||||
// gate skips plaintext values), so existing rows from before the
|
||||
// flip stay readable. New writes encrypt; existing rows get
|
||||
// encrypted the next time they're edited. A post-login
|
||||
// "encrypt-at-rest sweep" over the pre-existing rows is a Phase 2e
|
||||
// follow-up if we want hard at-rest coverage before launch.
|
||||
globalTags: { enabled: true, fields: ['name'] },
|
||||
tagGroups: { enabled: true, fields: ['name'] },
|
||||
|
||||
// ─── Workbench Scenes ────────────────────────────────────
|
||||
// docs/plans/space-scoped-data-model.md §2a — declared with
|
||||
// enabled:false during prep; flips to true in 2c. `name` is the
|
||||
// user-visible scene label ("Heute", "Q2-Launch") and `description`
|
||||
// is the short subtitle — both are user-typed free text that can
|
||||
// leak Space-specific context. openApps / order / wallpaper /
|
||||
// viewingAsAgentId / scopeTagIds stay plaintext (structural /
|
||||
// indexed / foreign-key data).
|
||||
workbenchScenes: { enabled: false, fields: ['name', 'description'] },
|
||||
// docs/plans/space-scoped-data-model.md §2e — encryption enabled.
|
||||
// `name` is the user-visible scene label ("Heute", "Q2-Launch")
|
||||
// and `description` is the short subtitle — both are user-typed
|
||||
// free text that can leak Space-specific context. openApps /
|
||||
// order / wallpaper / viewingAsAgentId / scopeTagIds stay
|
||||
// plaintext (structural / indexed / foreign-key data).
|
||||
workbenchScenes: { enabled: true, fields: ['name', 'description'] },
|
||||
|
||||
// ─── Articles (Pocket-style read-it-later) ──────────────
|
||||
// Reading-behaviour data — same sensitivity class as newsArticles.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue