128 lines
4.4 KiB
Rust
128 lines
4.4 KiB
Rust
|
|
//! 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(())
|
||
|
|
}
|