encino
Document Vault

Documents, Sealed at Rest

A local encrypted vault for a folder of sensitive documents. Contents and filenames are encrypted at rest; documents are checked out one at a time and re-encrypted when you are done. No network, no service, no account. One binary on one machine.

3

Rust Crates

9,360

Lines of Rust

221

Tests

13

Commands

1

Binary

0

Runtime Deps

2

Platforms

24

Recovery Words

Key Capabilities

Every decision here exists to shrink what an attacker with your disk learns, and to keep the failure modes honest.

Per-Document Checkout

Documents are decrypted one at a time and re-encrypted when you close them. A design that decrypted the whole folder would leak plaintext revisions into a sync provider's version history, where you cannot delete them.

Encrypted Filenames

Names and folder structure live only inside the encrypted index, so the blob store on disk is flat and anonymous. A locked vault folder contains nothing but an opaque .encino directory.

Random Blob IDs

Each document is stored under 16 random bytes, never a hash of its contents. Content addressing would give identical documents identical names and let an attacker confirm a guessed document by hashing a candidate.

Size Padding

Blob sizes are padded with Padmé and floored at 4 KiB, so every document under 4 KiB is identical on disk and larger ones cost at most 12%. Enough to tell a note from a scan, not enough to confirm a document by its size.

Session Agent

unlock derives the key once — Argon2id is deliberately about a second — and hands it to a background agent that holds it in memory locked out of swap. It writes nothing to disk and decrypts nothing.

24-Word Recovery Code

A BIP39-checksummed recovery code wraps the master key independently of your passphrase. Printed once at init and never stored, so it cannot be shown again — and it opens the vault outright.

What the Disk Reveals

Stated plainly, because a vault that overstates what it hides is worse than one that hides less.

Protected

Recovering these needs the passphrase or the recovery code

  • Document contents

    XChaCha20-Poly1305, per-document keys

  • Document filenames

    held only in the encrypted index

  • Folder and subfolder structure

    the blob store is flat

Still Visible

What an observer with the disk learns anyway

  • Document count

    the number of blobs is visible

  • Document sizes

    padded to a bucket, so only the bucket shows

  • Access times

    filesystem timestamps on blobs are visible

Hiding the count needs decoy blobs, which carry an ongoing storage cost rather than a one-off one. Both remain recorded in the format spec as candidates for a future revision.

Three Crates, One Executable

encino-core and encino-agent are libraries compiled into encino-cli, which produces the single encino binary.

encino-core

5,553 LOC

Vault engine

  • Crypto, index, blob store, journal
  • Forbids unsafe outright — the risky code is directly testable
  • Does no terminal I/O at all
  • A future GUI or filesystem mount is another front-end, not a rewrite

encino-agent

2,067 LOC

Session daemon and client

  • Holds the master key in memory locked out of swap
  • Every unsafe block in the project lives in 3 of its files
  • Verifies the connecting client is the account that started it
  • Performs timer-driven auto-close and expiry

encino-cli

1,740 LOC

The encino command

  • The only binary the workspace produces
  • Hosts the hidden agent subcommand, so there is one file
  • Prompts, confirmations, and table output
  • No unsafe at all; statically linked CRT, no redistributable
imports

> The release binary imports nothing but Windows itself

kernel32.dll   ntdll.dll   advapi32.dll   bcryptprimitives.dll   dbghelp.dll

api-ms-win-core-synch-l1-2-0.dll

// .cargo/config.toml links the C runtime statically. Without it, Rust's MSVC

// target pulls in vcruntime140.dll — present on most machines, guaranteed on none.

// Static linking costs ~100 KB and removes the failure mode entirely.

Before you trust it with anything

This protects against a stolen laptop, a leaked backup, a synced cloud copy, or another account on the machine. It does not protect against malware running as you while the vault is unlocked. That is the fundamental limit of at-rest encryption, and no design here changes it.

Shredding cannot guarantee erasure on an SSD — wear levelling means overwriting a logical block does not reliably erase the physical one. Run encino on a BitLocker-encrypted volume; volume encryption is the real mitigation, and it also covers the hibernation file for the times you forget to lock.

This has not been independently audited.

Read the full threat model

Ready to explore the code?

encino is open source, dual-licensed MIT OR Apache-2.0. Clone the repository, read the format spec and threat model, and build it yourself.

GitHub