2 Commits

Author SHA1 Message Date
6e86aeb2af Fix R5: SealedStore plaintext tmp is 0600 with fsync/cleanup
Plaintext working copy and export backup were creatable world-readable
under a 0700 temp dir. Write via os.open(mode=0600), fsync, unlink on
failure; pin temp dir 0700; remove export after flush. Document SQLCipher
as deferred — seal-on is not an encrypted DB while the process is open.
2026-10-06 06:28:01 +08:00
leora
73f802a5e6 Sealed store: AES-256-GCM encryption at rest for the DB file
Tokens/codes/secrets were already digests; a stolen cleartext SQLite file
still leaked the agent roster, revocation state and audit history.
SealedStore / SIGIL_SEAL_PASS wraps on-disk bytes in AES-256-GCM
(PBKDF2-HMAC-SHA256, 480k iters). Working copy is plaintext only while
open (temp file); flush/close re-seals. Incremental path short of
SQLCipher page-level encryption.

11 new tests in test_sealed.py (stolen seal has no SQLite header / no
agent rows; wrong passphrase fails; works with off-box anchor). Suite
130 green.

Part of Quarry 18a5d762. Independent crypto review + platform glue remain.
2026-10-06 06:28:01 +08:00