# Encryption Testing - Quick Start ## TL;DR ```bash # 1. Setup services (Age already configured, RustyVault requires Docker) ./scripts/encryption-test-setup.sh # 2. Load environment source /tmp/typedialog-env.sh # 3. Test redaction (no service) - Simple example typedialog form examples/08-encryption/simple-login.toml --redact --format json # 4. Test Age encryption (requires ~/.age/key.txt) typedialog form examples/08-encryption/simple-login.toml \ --encrypt --backend age \ --key-file ~/.age/key.txt \ --format json # 5. Full feature demo (all encryption features) typedialog form examples/08-encryption/credentials.toml --redact --format json # 6. Run all integration tests cargo test --test nickel_integration test_encryption -- --nocapture ``` ## Example Forms ### Simple Login Form (`examples/08-encryption/simple-login.toml`) Minimal example for quick testing: - `username` (plaintext) - `password` (sensitive, auto-detected from type) **Use this for**: - Quick verification of redaction - Basic Age encryption testing - First-time setup validation ### Full Credentials Form (`examples/08-encryption/credentials.toml`) Comprehensive example demonstrating all encryption features: - Non-sensitive fields: username, email, company - Auto-detected sensitive: password, confirm_password (FieldType::Password) - Explicitly marked sensitive: api_token, ssh_key, database_url - Field-level backends: vault_token (RustyVault config) - Override: demo_password (type=password but NOT sensitive) **Use this for**: - Testing field-level sensitivity control - Field-specific encryption backend configuration - Demonstrating RustyVault setup ### Nickel Schema (`examples/08-encryption/nickel-secrets.ncl`) Demonstrates encryption in Nickel schema language: - `Sensitive Backend="age"` annotations - Key path specification - Nested structure with sensitive fields **Use this for**: - Understanding Nickel contract syntax - Converting Nickel schemas to TOML forms See `examples/08-encryption/README.md` for detailed examples and testing instructions. ## Current Status ✅ **Age (Local encryption)** - Ready to test - Public key: Generated automatically - Private key: `~/.age/key.txt` - No service required, uses CLI tool - Forms ready: `simple-login.toml`, `credentials.toml` ✅ **Redaction** - Fully functional - Works without any encryption service - Auto-detects sensitive fields from FieldType::Password - Field-level control with explicit `sensitive` flag ⏳ **RustyVault (HTTP service)** - Framework ready, tests pending - Needs: Docker or manual build - Service: `http://localhost:8200` - API: Transit secrets engine - Configuration demo: `credentials.toml` vault_token field ## Test Results **Tests passing (redaction, metadata mapping):** ``` cargo test --test nickel_integration test_encryption ``` Output: ``` running 5 tests test test_encryption_metadata_parsing ... ok test test_encryption_metadata_in_nickel_field ... ok test test_encryption_auto_detection_from_field_type ... ok test test_encryption_roundtrip_with_redaction ... ok test test_encryption_metadata_to_field_definition ... ok test result: ok. 5 passed; 0 failed ``` All tests use the example forms for verification. ## Next Steps for Full Encryption Testing ### 1. Create test forms with encryption **test_form_age.toml:** ```toml name = "age_test" display_mode = "complete" [[fields]] name = "username" type = "text" prompt = "Username" sensitive = false [[fields]] name = "password" type = "password" prompt = "Password" sensitive = true encryption_backend = "age" [fields.encryption_config] key = "~/.age/key.txt" ``` ### 2. Test Age encryption manually ```bash # Generate test message echo "test-secret-123" > /tmp/test.txt # Get public key PUBLIC_KEY=$(grep "^public key:" ~/.age/key.txt | cut -d' ' -f3) # Encrypt age -r "$PUBLIC_KEY" /tmp/test.txt > /tmp/test.age # Decrypt age -d -i ~/.age/key.txt /tmp/test.age # Output: test-secret-123 ``` ### 3. Implement Age roundtrip test File: `crates/typedialog-core/tests/encryption_roundtrip.rs` ```rust #[test] fn test_age_encrypt_decrypt_roundtrip() { use typedialog_core::helpers::{EncryptionContext, transform_results}; let mut results = HashMap::new(); results.insert("secret".to_string(), json!("my-password")); let field = FieldDefinition { name: "secret".to_string(), sensitive: Some(true), encryption_backend: Some("age".to_string()), encryption_config: Some({ let mut m = HashMap::new(); m.insert("key".to_string(), "~/.age/key.txt".to_string()); m }), ..Default::default() }; // Encrypt let context = EncryptionContext::encrypt_with("age", Default::default()); let encrypted = transform_results(&results, &[field.clone()], &context, None) .expect("Encryption failed"); // Verify ciphertext let ciphertext = encrypted.get("secret").unwrap().as_str().unwrap(); assert!(ciphertext.starts_with("age1-"), "Should be Age format"); assert_ne!(ciphertext, "my-password", "Should be encrypted"); } ``` ### 4. Test with RustyVault (optional, requires Docker) ```bash # Pull RustyVault image docker pull rustyvault:latest # Re-run setup script ./scripts/encryption-test-setup.sh # Test encryption with vault typedialog form test_form_age.toml \ --encrypt --backend rustyvault \ --vault-addr http://localhost:8200 \ --vault-token root \ --vault-key-path transit/keys/typedialog-key \ --format json ``` ## Verification Checklist - [ ] Age installed: `age --version` - [ ] Age keys generated: `cat ~/.age/key.txt` - [ ] Test redaction: `typedialog form ... --redact` - [ ] Run encryption tests: `cargo test --test nickel_integration test_encryption` - [ ] All 5 tests passing - [ ] (Optional) Docker available for RustyVault - [ ] (Optional) RustyVault running: `curl http://localhost:8200/v1/sys/health` ## Documentation Full setup guide: See `docs/ENCRYPTION-SERVICES-SETUP.md`