Merge pull request 'clean workspace: remove supervisor packe + add instructions about how AGE redis commands work' (#2) from blpop into main
Reviewed-on: #2
This commit is contained in:
		
							
								
								
									
										4
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										4
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| @@ -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" | ||||
|   | ||||
| @@ -1,8 +1,5 @@ | ||||
| [workspace] | ||||
| members = [ | ||||
|     "herodb", | ||||
|     "supervisor", | ||||
| ] | ||||
| members = ["herodb"] | ||||
| resolver = "2" | ||||
|  | ||||
| # You can define shared profiles for all workspace members here | ||||
|   | ||||
							
								
								
									
										173
									
								
								herodb/instructions/age_usage.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										173
									
								
								herodb/instructions/age_usage.md
									
									
									
									
									
										Normal file
									
								
							| @@ -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 <recipient> "hello world" | ||||
| # → returns ciphertext (base64 in a bulk string) | ||||
|  | ||||
| redis-cli -p PORT AGE DECRYPT <identity> <ciphertext_b64> | ||||
| # → 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 <ciphertext_b64> | ||||
| ``` | ||||
|  | ||||
| ## 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..." "<ciphertext_b64>" | ||||
| # → "hello world" | ||||
| ``` | ||||
|  | ||||
| 2) Ephemeral signing keys | ||||
|  | ||||
| ```bash | ||||
| # Generate an ephemeral signing keypair | ||||
| redis-cli -p PORT AGE GENSIGN | ||||
| # Example output: | ||||
| # 1) "<verify_pub_b64>" | ||||
| # 2) "<sign_secret_b64>" | ||||
|  | ||||
| # Sign a message with the secret | ||||
| redis-cli -p PORT AGE SIGN "<sign_secret_b64>" "msg" | ||||
| # → returns "<signature_b64>" | ||||
|  | ||||
| # Verify with the public key | ||||
| redis-cli -p PORT AGE VERIFY "<verify_pub_b64>" "msg" "<signature_b64>" | ||||
| # → 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 "<ciphertext_b64>" | ||||
| # → "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 "<signature_b64>" | ||||
|  | ||||
| # Verify using the stored public key | ||||
| redis-cli -p PORT AGE VERIFYNAME app1 "msg" "<signature_b64>" | ||||
| # → 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) | ||||
| @@ -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" } | ||||
| @@ -1,4 +0,0 @@ | ||||
| fn main() { | ||||
|     println!("Hello from the supervisor crate!"); | ||||
|     // Supervisor logic will be implemented here. | ||||
| } | ||||
		Reference in New Issue
	
	Block a user