5.9 KiB
5.9 KiB
Encryption Testing - Quick Start
Quick Summary
# 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
sensitiveflag
⏳ RustyVault (HTTP service) - Framework ready, tests pending
- Needs: Docker or manual build
- Service:
http://localhost:8200 - API: Transit secrets engine
- Configuration demo:
credentials.tomlvault_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:
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
# 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
#[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)
# 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