fix(manager-core): F-M-002 coupled-nullness CHECK on encrypted-secret column pairs
Two (encrypted, nonce) column pairs are each nullable independently in the current schema: - email_trigger_details.inbound_secret_encrypted / _nonce - app_secrets.realtime_signing_key_encrypted / _nonce A bug or partial write could leave one populated and the other NULL, silently bypassing signature verification (receivers decrypt only if the encrypted column is set). Migration 0038 adds CHECK ((enc IS NULL) = (nonce IS NULL)) on both tables — defence-in-depth: catches an invariant violation at the DB boundary even if the writing code regresses. AUDIT.md anchor: F-M-002. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
-- F-M-002 (audit 2026-06-07): coupled-nullness CHECK constraints on
|
||||
-- (encrypted, nonce) pairs.
|
||||
--
|
||||
-- The current schema has each column nullable independently:
|
||||
-- email_trigger_details.inbound_secret_encrypted / _nonce
|
||||
-- app_secrets.realtime_signing_key_encrypted / _nonce
|
||||
--
|
||||
-- A bug or partial write could leave one populated and the other NULL
|
||||
-- — silently bypassing signature verification (receiver decrypts only
|
||||
-- if the encrypted column is set). Defend with a coupled-nullness
|
||||
-- CHECK on each pair so a partial state is rejected at the DB
|
||||
-- boundary.
|
||||
ALTER TABLE email_trigger_details
|
||||
ADD CONSTRAINT email_trigger_details_inbound_secret_pair
|
||||
CHECK ((inbound_secret_encrypted IS NULL) = (inbound_secret_nonce IS NULL));
|
||||
|
||||
ALTER TABLE app_secrets
|
||||
ADD CONSTRAINT app_secrets_realtime_signing_key_pair
|
||||
CHECK ((realtime_signing_key_encrypted IS NULL) = (realtime_signing_key_nonce IS NULL));
|
||||
Reference in New Issue
Block a user