Skip to content

feat: add client-side crypto and vault file indexing - #65

Merged
mtiluk merged 1 commit into
mainfrom
feat/client-crypto-and-vault-indexing
Sep 16, 2026
Merged

mtiluk merged 1 commit into
mainfrom
feat/client-crypto-and-vault-indexing

Conversation

@mtiluk

@mtiluk mtiluk commented Sep 16, 2026

Copy link
Copy Markdown
Owner

Two independent client-side pieces that push/pull will build on: internal/client/vault scans a vault directory into a file index (relative path, size, mtime, SHA-256 content hash), and internal/client/crypto derives an AES-256 key from a passphrase via Argon2id and does AES-GCM encrypt/decrypt.

vault.ScanVault: stats the root first so a bad/nonexistent path returns a clean error instead of panicking through WalkDir on a nil DirEntry, checks the walk callback's own error instead of ignoring it (an unreadable subdirectory now surfaces an error rather than silently vanishing from the index), and uses filepath.Rel so nested files with the same basename don't collide. Content hash streams the file through SHA-256 rather than buffering it whole.

crypto.DeriveKey wraps argon2.IDKey (t=1, 2GiB memory, p=4, 32-byte key - OWASP's "uniformly safe" high-memory recommendation). Encrypt/Decrypt wrap AES-GCM, generating a random nonce per Encrypt call and prepending it to the ciphertext; Decrypt splits it back off before authenticating. A wrong key or a tampered/truncated ciphertext fails cleanly instead of returning garbage.

Two independent client-side pieces that push/pull will build on:
internal/client/vault scans a vault directory into a file index
(relative path, size, mtime, SHA-256 content hash), and
internal/client/crypto derives an AES-256 key from a passphrase via
Argon2id and does AES-GCM encrypt/decrypt.

vault.ScanVault: stats the root first so a bad/nonexistent path
returns a clean error instead of panicking through WalkDir on a nil
DirEntry, checks the walk callback's own error instead of ignoring it
(an unreadable subdirectory now surfaces an error rather than
silently vanishing from the index), and uses filepath.Rel so nested
files with the same basename don't collide. Content hash streams the
file through SHA-256 rather than buffering it whole.

crypto.DeriveKey wraps argon2.IDKey (t=1, 2GiB memory, p=4, 32-byte
key - OWASP's "uniformly safe" high-memory recommendation).
Encrypt/Decrypt wrap AES-GCM, generating a random nonce per Encrypt
call and prepending it to the ciphertext; Decrypt splits it back off
before authenticating. A wrong key or a tampered/truncated ciphertext
fails cleanly instead of returning garbage.
@mtiluk
mtiluk merged commit 8a5a228 into main Sep 16, 2026
1 check passed
@mtiluk
mtiluk deleted the feat/client-crypto-and-vault-indexing branch September 16, 2026 01:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant