//! Multi-backend encryption example. //! //! Demonstrates how to switch between different encryption backends //! using the same unified API. //! //! # Key Point //! //! The same code path works with Age, SOPS, AWS KMS, GCP KMS, Azure KMS, //! SecretumVault. Just change the backend specification - no code changes //! needed! //! //! # Usage //! //! ```bash //! # Test with Age backend //! age-keygen -o ~/.age/key.txt //! cargo run --example multi_backend --features age //! //! # Test with SOPS backend (requires .sops.yaml) //! cargo run --example multi_backend --features sops //! //! # Test with both (shows feature-gating) //! cargo run --example multi_backend --features age,sops //! ``` use encrypt::{decrypt, encrypt, is_available, BackendSpec}; fn main() -> Result<(), Box> { println!("=== Multi-Backend Encryption Example ===\n"); let secret = "my-application-secret"; // Define specs for different backends let backends = vec![ ("Age (local)", BackendSpec::age_default()), ("SOPS (AWS KMS)", BackendSpec::sops()), ( "SecretumVault (PQC)", BackendSpec::secretumvault("https://vault.internal:8200", "hvs.token", "app-key"), ), ( "AWS KMS", BackendSpec::aws_kms("us-east-1", "arn:aws:kms:us-east-1:123456789:key/12345678"), ), ]; println!("Testing encryption with available backends:\n"); let mut success_count = 0; let mut skipped_count = 0; for (name, spec) in backends { print!("{:<30} ", format!("{}...", name)); // Check if backend feature is enabled if !is_available(&spec) { println!("SKIPPED (feature not enabled)"); skipped_count += 1; continue; } // Try encryption with this backend match encrypt(secret, &spec) { Ok(ciphertext) => { // Try decryption match decrypt(&ciphertext, &spec) { Ok(plaintext) => { if plaintext == secret { println!("✓ SUCCESS"); success_count += 1; } else { println!("✗ FAILED (roundtrip mismatch)"); } } Err(e) => { println!("✗ FAILED (decrypt: {})", e); } } } Err(e) => { println!("✗ FAILED (encrypt: {})", e); } } } println!("\n=== Results ==="); println!("Successful: {}", success_count); println!("Skipped (feature not enabled): {}", skipped_count); // Show how to handle backend fallback println!("\n=== Backend Fallback Pattern ===\n"); println!("Common pattern: Try production backend, fall back to local\n"); // Try SecretumVault (production) let secretumvault_spec = BackendSpec::secretumvault("https://vault.prod:8200", "token", "app-key"); if is_available(&secretumvault_spec) { println!("Using SecretumVault (production, post-quantum ready)"); match encrypt(secret, &secretumvault_spec) { Ok(_) => println!("✓ Encrypted with SecretumVault"), Err(_) => println!("! SecretumVault unavailable, trying fallback..."), } } else { // Fallback to Age let age_spec = BackendSpec::age_default(); if is_available(&age_spec) { println!("SecretumVault not available"); println!("Falling back to Age (local, X25519)"); match encrypt(secret, &age_spec) { Ok(_) => println!("✓ Encrypted with Age"), Err(e) => println!("✗ Age also failed: {}", e), } } } // Show available backends println!("\n=== Configuration Examples ===\n"); println!("Age (local X25519):"); println!(" BackendSpec::age_default()"); println!(" BackendSpec::age(\"/custom/path.txt\")\n"); println!("SOPS (multi-KMS via .sops.yaml):"); println!(" BackendSpec::sops()\n"); println!("SecretumVault (post-quantum ready):"); println!(" BackendSpec::secretumvault(\"https://vault:8200\", \"token\", \"key\")\n"); println!("AWS KMS:"); println!(" BackendSpec::aws_kms(\"us-east-1\", \"arn:aws:kms:...:key/...\")\n"); println!("GCP KMS:"); println!(" BackendSpec::gcp_kms(\"project\", \"global\", \"key\", \"global\")\n"); println!("Azure KMS:"); println!(" BackendSpec::azure_kms(\"vault-name\", \"tenant-id\")\n"); println!("Key Architecture Benefits:"); println!(" ✓ Same API for all backends"); println!(" ✓ Feature-gated compilation"); println!(" ✓ Easy to switch backends"); println!(" ✓ Fallback support"); println!(" ✓ No backend-specific code in application"); Ok(()) }