-
Notifications
You must be signed in to change notification settings - Fork 0
Closed
Labels
enhancementNew feature or requestNew feature or request
Description
Attaching of binary and text files, eg. images, audio, video, docx, csv, etc. to a note should be possible.
Here is a design proposed by Claude Opus, please consider this for the implementation/brainstorming:
Encrypted File Attachments — Technical Design
Overview
Allow users to attach an arbitrary number of files (images, documents, audio, etc.) to any note. Attachments must be encrypted at rest, consistent with the existing SQLCipher-encrypted database.
Architecture: Encrypted Sidecar Files
Store attachments as individually encrypted files on disk alongside the database. The database holds only metadata — never the file contents.
~/.krillnotes/
└── workspaces/
├── <workspace-id>/
│ ├── notes.db (SQLCipher encrypted database)
│ └── attachments/
│ ├── a1b2c3d4.enc (encrypted attachment)
│ ├── e5f6g7h8.enc
│ └── ...
├── <workspace-id>/
│ ├── notes.db
│ └── attachments/
│ └── ...
└── ...
Encryption Scheme
- Algorithm: ChaCha20-Poly1305 (authenticated encryption)
- Key derivation: HKDF from the master passphrase + a unique random salt per file
- No keys or passwords stored in the database — only the per-file salt is stored. The master passphrase (same one that unlocks SQLCipher) is the single secret.
- Rust crate:
ring(provides ChaCha20-Poly1305 and HKDF)
Why ChaCha20-Poly1305?
- Industry standard (used by TLS 1.3, WireGuard, Signal)
- Authenticated encryption — detects tampering, not just encrypts
- Fast in software without requiring hardware AES support
- Excellent Rust ecosystem support
Encrypted File Format
Each .enc file on disk:
[ 12-byte nonce ][ 32-byte salt ][ encrypted payload + 16-byte auth tag ]
Encrypt Flow
- Generate random 32-byte salt
- Derive file-specific key:
HKDF(master_passphrase, salt, info="krillnotes-attachment") - Generate random 12-byte nonce
- Encrypt file contents with ChaCha20-Poly1305
- Write
nonce || salt || ciphertext+tagto<uuid>.enc - Store metadata (salt, uuid, original filename, mime type, size, hash) in DB
Decrypt Flow
- Read nonce and salt from
.encfile header - Derive key from master passphrase + salt via HKDF
- Decrypt and authenticate payload
- Return plaintext bytes
Database Schema
CREATE TABLE attachments (
id TEXT PRIMARY KEY, -- UUID, matches filename on disk
note_id TEXT NOT NULL, -- FK to notes table
filename TEXT NOT NULL, -- original filename (e.g. "photo.jpg")
mime_type TEXT, -- e.g. "image/jpeg"
size_bytes INTEGER NOT NULL, -- original unencrypted size
hash_sha256 TEXT NOT NULL, -- hash of original file (integrity check)
salt BLOB NOT NULL, -- 32-byte salt for HKDF key derivation
created_at TEXT NOT NULL, -- ISO 8601 timestamp
FOREIGN KEY (note_id) REFERENCES notes(id) ON DELETE CASCADE
);
CREATE INDEX idx_attachments_note_id ON attachments(note_id);Attachment Lifecycle
Add
- User selects file(s) via file picker
- For each file: encrypt → write
.enc→ insert DB row - Wrap in a transaction so DB and disk stay in sync
Retrieve / View
- Query DB for attachment metadata by note_id
- Read
.encfile, decrypt in memory - Serve to UI (display inline for images, download/open for others)
Delete
- Delete DB row
- Delete
.encfile from disk - Wrap in transaction; if file deletion fails, log for cleanup
Orphan Cleanup
On startup (or periodically), scan the attachments/ directory and compare against DB records. Remove any .enc files that have no matching DB row. Also check for DB rows pointing to missing files and flag/remove them.
Considerations
- Large files: ChaCha20-Poly1305 can encrypt/decrypt in streaming chunks to keep memory usage bounded. Consider a chunked approach for files over a configurable threshold (e.g. 10MB).
- Thumbnails: For image attachments, consider generating and storing an encrypted thumbnail for quick preview in the notes list without decrypting the full file.
- Backup: A complete backup requires both
notes.dband theattachments/folder. Document this clearly for users. - Migration: Existing databases without the attachments table will need a migration step to add the table and create the attachments directory.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request
Projects
Status
Done