Commit Graph

2 Commits (d6faf0d5bdda423d1fb72343a4b205722c0bc5f3)

Author SHA1 Message Date
Thomas Joise 79717133b8 feat(d32): remove the key concept entirely + keyless legacy cleanup
Owner has no HQ_SECRET_KEY, so the D31 unlock-with-key path was impossible. crypto is
now fully keyless: encrypt/decrypt ignore keyHex (params kept so a key can be wired back
later); decrypt returns '' for any leftover legacy AES value (unreadable → treated as
unset, never fed back as ciphertext). Key-based /admin/migrate-plaintext replaced by
keyless /admin/clear-legacy-credentials (clearLegacyCiphertext) which NULLs unreadable
pre-D31 values. .env.example marks HQ_SECRET_KEY removed.

Ran the cleanup on live data: 76 SMS + 110 client DB passwords were unrecoverable and
cleared (usernames intact) — must be re-populated in plaintext (APEX re-import / re-entry).

Also fixes the one real defect the D31 adversarial review confirmed: maybeRefreshSmsDaily
still had a 'keyHex==="" -> no-op' guard that would silently kill the DAILY auto-refresh
once the key was gone (manual refresh masked it). Removed; the daily pull now runs keyless
like the manual path. Full suite 416 green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 days ago
Thomas Joise 3e175b8da1 feat(d31): store credentials in the clear (owner decision) + one-time migration
Removes credential encryption at rest so the SMS-gateway logins (and other portal/DB
passwords, module secrets, Gmail token) are usable daily without a held-out
HQ_SECRET_KEY. Keystone: crypto.encrypt() stores tagged plaintext ('plain:'),
decrypt() untags keylessly and still reads legacy AES *with* the key to migrate it.
Drops the six 'refuses/cannot without HQ_SECRET_KEY' guards. Scope is the reversible
credential vault ONLY — login passwords stay one-way scrypt-hashed (@sims/auth).
Secrets still kept out of list payloads + audit rows; reveal still managerial+audited.

migrateLegacyCiphertext + POST /admin/migrate-plaintext (owner) rewrite existing AES
rows as plaintext using the key one final time (idempotent, one audit summary), after
which the key is never needed. SECURITY: a DB dump now exposes these in the clear.

Tests updated to the plaintext policy; new migrate-plaintext.test locks decrypt +
migration + idempotency. Full suite 416 green; typecheck clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 days ago