From 1457de487fdebe3c1b161c6f58f75bd6b3ea8205 Mon Sep 17 00:00:00 2001 From: null Date: Sun, 5 Jul 2026 19:15:32 -0500 Subject: [PATCH] feat(security): show a key fingerprint (not the key) in the encryption status MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The encryption key must never be retrievable through the app (that would undo the whole point of TOKEN_ENCRYPTION_KEY — a stolen session/XSS could then read the master key). Instead surface a non-reversible fingerprint so operators can: - verify which key is currently active, - confirm a running instance matches the key they backed up, and - spot an accidental key change (which would make existing secrets unrecoverable). - encryptionService.keyFingerprint(): domain-separated SHA-256 prefix of the active key (env if set, else the stored DB key); never force-creates a key (returns null when none exists), shares nothing with the cipher derivation. - admin bank-sync-config exposes key_fingerprint alongside encryption_key_source. - Admin Bank Sync card renders it with backup guidance. - Test: stable per key, differs by key, not reversible / not the raw key. Co-Authored-By: Claude Opus 4.8 --- client/components/admin/BankSyncAdminCard.tsx | 12 ++++++++ routes/admin.js | 4 +-- services/encryptionService.js | 23 ++++++++++++++- tests/encryptionService.test.js | 28 +++++++++++++++++++ 4 files changed, 64 insertions(+), 3 deletions(-) diff --git a/client/components/admin/BankSyncAdminCard.tsx b/client/components/admin/BankSyncAdminCard.tsx index 65dbee2..53f3182 100644 --- a/client/components/admin/BankSyncAdminCard.tsx +++ b/client/components/admin/BankSyncAdminCard.tsx @@ -23,6 +23,7 @@ interface BankSyncConfig { seed_days?: number; worker?: BankSyncWorker; encryption_key_source?: string; + key_fingerprint?: string | null; } function timeAgo(iso: string | null | undefined): string | null { @@ -293,6 +294,17 @@ export default function BankSyncAdminCard() { Regular database backups preserve all user connections.

+ {config?.key_fingerprint && ( +

+ Active key fingerprint{' '} + {config.key_fingerprint} + {' '}— a one-way check of the current key (never the key itself). Keep your{' '} + TOKEN_ENCRYPTION_KEY in a password manager; this fingerprint lets you + confirm a running instance matches the key you saved, and spot an accidental key change (which would make + existing secrets unrecoverable). +

+ )} +