Help us measure site usage?

With your permission, we use self-hosted analytics to understand page usage. It is optional and does not affect the Service. Learn more.

RustintermediatecliAI generated

Encrypted Notes CLI

Build a command-line notes app in Rust that keeps every note encrypted on disk. You unlock the vault with a password, then add, list, read, edit, delete and search your notes, for example: notes add Groceries, or notes search milk. Notes are encrypted with ChaCha20-Poly1305, using a key derived from your password with Argon2, so anyone who copies the files sees only unreadable data. Search decrypts notes in memory only; plaintext is never written to disk. You'll practice designing a CLI with subcommands, serializing data with Serde, async file I/O with Tokio, and using well-reviewed cryptography crates correctly instead of inventing your own.

Estimate
~14.5h
Steps
7
Completed by
0
Proposed by
codeseed.app

Tokio · Serde

Project roadmap

  1. 01

    Set up the CLI

    ~1.5h

    Create a binary crate and add: tokio (with the fs, macros and rt-multi-thread features), serde, serde_json, clap with the derive feature, chacha20poly1305, argon2, rand and rpassword. Define these subcommands with clap: init, add <title>, list, show <id>, edit <id>, delete <id> and search <query>. Use a #[tokio::main] main that matches the subcommand and prints a placeholder for each. Done when: notes --help lists all seven subcommands.

  2. 02

    Design the storage format

    ~2h

    Store the vault in a directory (default ~/.notes-vault, changeable with --vault). Define a Serde Note struct with id, title, body, created_at and updated_at, and a vault.json file holding the Argon2 salt and a format version. Each note is saved as <id>.enc. Write async load and save functions with tokio::fs. Done when: the structs serialize to JSON, and notes init creates the vault directory and vault.json.

  3. 03

    Derive the key from a password

    ~2h

    In init, ask for the password twice with rpassword (never echo it or accept it as an argument), generate a random 16-byte salt, and derive a 32-byte key with Argon2id. Save only the salt, never the password or the key. Every other command asks once and derives the same key. To detect a wrong password, store an encrypted known value in vault.json and check that it decrypts. Done when: init creates a vault and a wrong password is rejected clearly.

  4. 04

    Encrypt and decrypt notes

    ~2.5h

    Serialize a Note to JSON and encrypt it with ChaCha20-Poly1305 using the derived key and a new random 12-byte nonce for every save. Write the nonce followed by the ciphertext to <id>.enc. Decrypting reads the nonce back, decrypts and deserializes. A modified or corrupted file must return an error, never garbage. Done when: add followed by show returns the same note, and the .enc file contains no readable text.

  5. 05

    Implement the commands

    ~2.5h

    Implement add (title from the argument, body read from stdin until Ctrl-D), list (id, title and last update, newest first), show, edit (replaces the body with new text read from stdin and updates updated_at) and delete (asks for confirmation first). Plaintext must never be written to disk, so don't use temporary files. Done when: all five commands work end to end on a real vault.

  6. 06

    Add search

    ~2h

    Implement search <query>: decrypt every note in memory and match the query case-insensitively against the title and body. Print each match with its id, title and a short snippet around the first occurrence. Decrypt notes concurrently with Tokio tasks. Done when: searching for a word that appears in two out of five notes returns exactly those two.

  7. 07

    Write tests

    ~2h

    Write tests for: key derivation gives the same key for the same password and salt, encrypting then decrypting returns the original note, a modified ciphertext fails to decrypt, a wrong password is rejected, and search finds the right notes. Use a temporary directory (the tempfile crate) so tests never touch a real vault. Done when: cargo test passes.

Ready to build this?

Get a GitHub repo and start building. Your AI reviewer checks each step as you go.

~14.5h · 7 steps

Tech stack

TokioSerde