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

128 lines
4.4 KiB
Rust
Raw Permalink Normal View History

//! SOPS (Mozilla SOPS) backend encryption example.
//!
//! Demonstrates encryption/decryption using SOPS, which supports multiple KMS
//! backends (AWS KMS, GCP KMS, Azure Key Vault) via `.sops.yaml` configuration.
//!
//! # Prerequisites
//!
//! 1. Install sops binary
//! 2. Create `.sops.yaml` configuration in current directory or parent
//! 3. Configure KMS credentials (AWS/GCP/Azure)
//!
//! # Setup Example (AWS KMS)
//!
//! ```bash
//! # Install sops
//! brew install sops # macOS
//! # or
//! apt-get install sops # Ubuntu/Debian
//!
//! # Create .sops.yaml in project root
//! cat > .sops.yaml << 'EOF'
//! creation_rules:
//! - path_regex: \.sops\.yaml$
//! kms: arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012
//! EOF
//!
//! # Ensure AWS credentials are configured
//! export AWS_PROFILE=default
//! export AWS_REGION=us-east-1
//!
//! # Run example
//! cargo run --example sops_backend --features sops
//! ```
use encrypt::{decrypt, encrypt, BackendSpec};
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("=== SOPS Backend Encryption Example ===\n");
// Create SOPS backend spec
let spec = BackendSpec::sops();
println!("Backend: {}", spec.backend_name());
println!("SOPS reads configuration from: .sops.yaml");
println!("SOPS supports: AWS KMS, GCP KMS, Azure Key Vault\n");
// Plaintext secret
let secret = "database-password-xyz789";
println!("Original secret: {}", secret);
// Encrypt
match encrypt(secret, &spec) {
Ok(ciphertext) => {
println!("✓ Encrypted successfully");
println!(
"Ciphertext (first 100 chars): {}...",
&ciphertext[..100.min(ciphertext.len())]
);
// Decrypt
match decrypt(&ciphertext, &spec) {
Ok(plaintext) => {
println!("✓ Decrypted successfully");
println!("Decrypted secret: {}", plaintext);
// Verify roundtrip
if plaintext == secret {
println!("\n✓ Roundtrip successful - plaintext matches!");
} else {
println!("\n✗ Roundtrip failed - plaintext mismatch!");
return Err("Roundtrip verification failed".into());
}
}
Err(e) => {
println!("✗ Decryption failed: {}", e);
return Err(e.into());
}
}
}
Err(e) => {
println!("✗ Encryption failed: {}", e);
println!("\nSetup .sops.yaml configuration:");
println!(" cat > .sops.yaml << 'EOF'");
println!(" creation_rules:");
println!(" - path_regex: .*");
println!(" kms: arn:aws:kms:REGION:ACCOUNT:key/KEY_ID");
println!(" EOF");
println!("\nOr use environment-based configuration:");
println!(" export AWS_REGION=us-east-1");
println!(" export SOPS_KMS_ARN=arn:aws:kms:us-east-1:123456789012:key/...");
return Err(e.into());
}
}
// Example 2: SOPS with AWS KMS context
println!("\n=== SOPS with KMS Context ===\n");
let spec_with_context = BackendSpec::sops();
println!("Backend: {}", spec_with_context.backend_name());
println!("Can add encryption context (key-value pairs)");
println!("Context helps with KMS key policies and audit trails\n");
// Note: We use the BackendSpec for now, but in real usage
// the context would be embedded in the encrypted output via SOPS
println!("Example SOPS configuration with multiple backends:");
println!(
"
creation_rules:
- path_regex: prod/.*
kms: arn:aws:kms:us-east-1:ACCOUNT:key/PROD_KEY
- path_regex: staging/.*
kms: arn:aws:kms:us-east-1:ACCOUNT:key/STAGING_KEY
gcp_kms: projects/PROJECT/locations/global/keyRings/RING/cryptoKeys/KEY
- path_regex: '.*'
kms: arn:aws:kms:us-east-1:ACCOUNT:key/DEFAULT_KEY
"
);
println!("\nSOPS Features:");
println!(" ✓ Multiple KMS backends (AWS, GCP, Azure)");
println!(" ✓ File-based encryption (YAML, JSON, TOML)");
println!(" ✓ Partial encryption (only sensitive fields)");
println!(" ✓ Git integration (diffs plaintext)");
println!(" ✓ Key rotation support");
Ok(())
}