TypeDialog/docs/encryption/encryption-quick-start.md
2026-01-11 22:35:49 +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
```text

## 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):**

```text
cargo test --test nickel_integration test_encryption
```text

Output:

```text
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
```text

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"
```text

### 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
```text

### 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");
}
```text

### 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
```text

## 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`