TypeDialog/docs/encryption/encryption-quick-start.md
2025-12-24 03:11:32 +00:00

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 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:

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