provisioning-platform/prov-ecosystem/crates/encrypt/examples/multi_backend.rs

148 lines
4.8 KiB
Rust
Raw Permalink Normal View History

//! 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<dyn std::error::Error>> {
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(())
}