Harden credential encryption key derivation (PBKDF2 with versioned ciphertext)
Author: lfnovoCreated Sep 5, 2026Updated Sep 17, 2026
Labelsenhancement
Context
open_notebook/utils/encryption.py derives the Fernet key from OPEN_NOTEBOOK_ENCRYPTION_KEY with a bare, unsalted hashlib.sha256(key.encode()). There are no tests for the module. #1020 proposed PBKDF2 but went stale (branch stacked on since-merged PRs, author inactive since July), so this issue tracks the work for a fresh PR off current main. Credit to @kwp3 for the original proposal.
Scope
- Derive the key with PBKDF2-HMAC-SHA256 (600k iterations, fixed app salt) instead of plain SHA-256.
- Prefix new ciphertext with a version marker (e.g.
pbkdf2v1:) and keep a legacy decrypt path for unprefixed values. - One-shot re-encryption command (
commands/) that rewrites existingCredential.api_key/ProviderConfig.api_keyvalues, fail-closed per record. Lazy re-encrypt on save is not enough: API keys are set once and would never upgrade. tests/test_encryption.py: round-trip, legacy fallback, marker handling, re-encryption command.- Docs:
security.mdguidance on high-entropy keys; CHANGELOG entry with a downgrade warning (older versions can't readpbkdf2v1:values). - Short decision record in
docs/7-DEVELOPMENT/decisions/.
Supersedes #1020.
Source: lfnovo/open-notebook