From 3b9756a4e1544ada013ab12a8308e645062c8231 Mon Sep 17 00:00:00 2001 From: Maxime Van Hees Date: Fri, 22 Aug 2025 14:21:16 +0200 Subject: [PATCH] clean workspace: remove supervisor packe + add instructions about how AGE redis commands work --- Cargo.lock | 4 - Cargo.toml | 5 +- herodb/instructions/age_usage.md | 173 +++++++++++++++++++++++++++++++ supervisor/Cargo.toml | 9 -- supervisor/src/main.rs | 4 - 5 files changed, 174 insertions(+), 21 deletions(-) create mode 100644 herodb/instructions/age_usage.md delete mode 100644 supervisor/Cargo.toml delete mode 100644 supervisor/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index 86db035..15bf240 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1526,10 +1526,6 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" -[[package]] -name = "supervisor" -version = "0.1.0" - [[package]] name = "syn" version = "1.0.109" diff --git a/Cargo.toml b/Cargo.toml index 9ca5311..2eedb5f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,5 @@ [workspace] -members = [ - "herodb", - "supervisor", -] +members = ["herodb"] resolver = "2" # You can define shared profiles for all workspace members here diff --git a/herodb/instructions/age_usage.md b/herodb/instructions/age_usage.md new file mode 100644 index 0000000..7aeab38 --- /dev/null +++ b/herodb/instructions/age_usage.md @@ -0,0 +1,173 @@ +# HeroDB AGE usage: Stateless vs Key‑Managed + +This document explains how to use the AGE cryptography commands exposed by HeroDB over the Redis protocol in two modes: +- Stateless (ephemeral keys; nothing stored on the server) +- Key‑managed (server‑persisted, named keys) + +If you are new to the codebase, the exact tests that exercise these behaviors are: +- [rust.test_07_age_stateless_suite()](herodb/tests/usage_suite.rs:495) +- [rust.test_08_age_persistent_named_suite()](herodb/tests/usage_suite.rs:555) + +Implementation entry points: +- [herodb/src/age.rs](herodb/src/age.rs) +- Dispatch from [herodb/src/cmd.rs](herodb/src/cmd.rs) + +Note: Database-at-rest encryption flags in the test harness are unrelated to AGE commands; those flags control storage-level encryption of DB files. See the harness near [rust.start_test_server()](herodb/tests/usage_suite.rs:10). + +## Quick start + +Assuming the server is running on localhost on some PORT: + +```bash +# Generate an ephemeral keypair and encrypt/decrypt a message (stateless mode) +redis-cli -p PORT AGE GENENC +# → returns an array: [recipient, identity] + +redis-cli -p PORT AGE ENCRYPT "hello world" +# → returns ciphertext (base64 in a bulk string) + +redis-cli -p PORT AGE DECRYPT +# → returns "hello world" +``` + +For key‑managed mode, generate a named key once and reference it by name afterwards: + +```bash +redis-cli -p PORT AGE KEYGEN app1 +# → persists encryption keypair under name "app1" + +redis-cli -p PORT AGE ENCRYPTNAME app1 "hello" +redis-cli -p PORT AGE DECRYPTNAME app1 +``` + +## Stateless AGE (ephemeral) + +Characteristics +- No server‑side storage of keys. +- You pass the actual key material with every call. +- Not listable via AGE LIST. + +Commands and examples + +1) Ephemeral encryption keys + +```bash +# Generate an ephemeral encryption keypair +redis-cli -p PORT AGE GENENC +# Example output (abridged): +# 1) "age1qz..." # recipient (public) +# 2) "AGE-SECRET-KEY-1..." # identity (secret) + +# Encrypt with the recipient +redis-cli -p PORT AGE ENCRYPT "age1qz..." "hello world" +# → returns bulk string payload: base64 ciphertext + +# Decrypt with the identity (secret) +redis-cli -p PORT AGE DECRYPT "AGE-SECRET-KEY-1..." "" +# → "hello world" +``` + +2) Ephemeral signing keys + +```bash +# Generate an ephemeral signing keypair +redis-cli -p PORT AGE GENSIGN +# Example output: +# 1) "" +# 2) "" + +# Sign a message with the secret +redis-cli -p PORT AGE SIGN "" "msg" +# → returns "" + +# Verify with the public key +redis-cli -p PORT AGE VERIFY "" "msg" "" +# → 1 (valid) or 0 (invalid) +``` + +When to use +- You do not want the server to store private keys. +- You already manage key material on the client side. +- You need ad‑hoc operations without persistence. + +Reference test: [rust.test_07_age_stateless_suite()](herodb/tests/usage_suite.rs:495) + +## Key‑managed AGE (persistent, named) + +Characteristics +- Server generates and persists keypairs under a chosen name. +- Clients refer to keys by name; raw secrets are not supplied on each call. +- Keys are discoverable via AGE LIST. + +Commands and examples + +1) Named encryption keys + +```bash +# Create/persist a named encryption keypair +redis-cli -p PORT AGE KEYGEN app1 +# → returns [recipient, identity] but also stores them under name "app1" + +# Encrypt using the stored public key +redis-cli -p PORT AGE ENCRYPTNAME app1 "hello" +# → returns bulk string payload: base64 ciphertext + +# Decrypt using the stored secret +redis-cli -p PORT AGE DECRYPTNAME app1 "" +# → "hello" +``` + +2) Named signing keys + +```bash +# Create/persist a named signing keypair +redis-cli -p PORT AGE SIGNKEYGEN app1 +# → returns [verify_pub_b64, sign_secret_b64] and stores under name "app1" + +# Sign using the stored secret +redis-cli -p PORT AGE SIGNNAME app1 "msg" +# → returns "" + +# Verify using the stored public key +redis-cli -p PORT AGE VERIFYNAME app1 "msg" "" +# → 1 (valid) or 0 (invalid) +``` + +3) List stored AGE keys + +```bash +redis-cli -p PORT AGE LIST +# Example output includes labels such as "encpub" and your key names (e.g., "app1") +``` + +When to use +- You want centralized key storage/rotation and fewer secrets on the client. +- You need names/labels for workflows and can trust the server with secrets. +- You want discoverability (AGE LIST) and simpler client commands. + +Reference test: [rust.test_08_age_persistent_named_suite()](herodb/tests/usage_suite.rs:555) + +## Choosing a mode + +- Prefer Stateless when: + - Minimizing server trust for secret material is the priority. + - Clients already have a secure mechanism to store/distribute keys. +- Prefer Key‑managed when: + - Centralized lifecycle, naming, and discoverability are beneficial. + - You plan to integrate rotation, ACLs, or auditability on the server side. + +## Security notes + +- Treat identities and signing secrets as sensitive; avoid logging them. +- For key‑managed mode, ensure server storage (and backups) are protected. +- AGE operations here are application‑level crypto and are distinct from database-at-rest encryption configured in the test harness. + +## Repository pointers + +- Stateless examples in tests: [rust.test_07_age_stateless_suite()](herodb/tests/usage_suite.rs:495) +- Key‑managed examples in tests: [rust.test_08_age_persistent_named_suite()](herodb/tests/usage_suite.rs:555) +- AGE implementation: [herodb/src/age.rs](herodb/src/age.rs) +- Command dispatch: [herodb/src/cmd.rs](herodb/src/cmd.rs) +- Bash demo: [herodb/examples/age_bash_demo.sh](herodb/examples/age_bash_demo.sh) +- Rust persistent demo: [herodb/examples/age_persist_demo.rs](herodb/examples/age_persist_demo.rs) +- Additional notes: [herodb/instructions/encrypt.md](herodb/instructions/encrypt.md) \ No newline at end of file diff --git a/supervisor/Cargo.toml b/supervisor/Cargo.toml deleted file mode 100644 index 509b273..0000000 --- a/supervisor/Cargo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[package] -name = "supervisor" -version = "0.1.0" -edition = "2021" - -[dependencies] -# The supervisor will eventually depend on the herodb crate. -# We can add this dependency now. -# herodb = { path = "../herodb" } \ No newline at end of file diff --git a/supervisor/src/main.rs b/supervisor/src/main.rs deleted file mode 100644 index deca46d..0000000 --- a/supervisor/src/main.rs +++ /dev/null @@ -1,4 +0,0 @@ -fn main() { - println!("Hello from the supervisor crate!"); - // Supervisor logic will be implemented here. -} \ No newline at end of file