envseal 0.3.8

Write-only secret vault with process-level access control — post-agent secret management
Documentation
//! Performance benchmarks for envseal.
//!
//! Measures encrypt/decrypt throughput and policy operations.
//! Run with: cargo test --test benchmark --release

#[path = "common/mod.rs"]
mod common;

use std::time::Instant;

fn main() {
    let iterations = 1000;

    println!("envseal benchmark — {iterations} iterations each\n");

    bench_store_decrypt(iterations);
    bench_policy_operations(iterations);
    bench_hash_binary();
    bench_guard_env_check(iterations);

    println!("\nAll benchmarks complete.");
}

fn bench_store_decrypt(iterations: usize) {
    let dir = common::vault_tempdir();
    let key = envseal::keychain::MasterKey::from_test_bytes([0x42; 32]);
    let vault = envseal::vault::Vault::open_with_key(dir.path(), key).unwrap();

    // Store benchmark
    let start = Instant::now();
    for i in 0..iterations {
        let name = format!("bench-{i}");
        vault
            .store(
                &name,
                b"benchmark-secret-value-that-is-realistic-length-for-api-keys",
                false,
            )
            .unwrap();
    }
    let store_elapsed = start.elapsed();
    println!(
        "store:   {iterations} ops in {:?} ({:.0} ops/sec)",
        store_elapsed,
        iterations as f64 / store_elapsed.as_secs_f64()
    );

    // Decrypt benchmark
    let start = Instant::now();
    for i in 0..iterations {
        let name = format!("bench-{i}");
        let _ = vault.decrypt(&name).unwrap();
    }
    let decrypt_elapsed = start.elapsed();
    println!(
        "decrypt: {iterations} ops in {:?} ({:.0} ops/sec)",
        decrypt_elapsed,
        iterations as f64 / decrypt_elapsed.as_secs_f64()
    );
}

fn bench_policy_operations(iterations: usize) {
    let mut policy = envseal::policy::Policy::default();
    let start = Instant::now();
    for i in 0..iterations {
        let binary = format!("/usr/bin/app-{i}");
        policy.allow_key_with_hash(&binary, "secret", "hash123");
    }
    let elapsed = start.elapsed();
    println!(
        "policy allow_key: {iterations} ops in {:?} ({:.0} ops/sec)",
        elapsed,
        iterations as f64 / elapsed.as_secs_f64()
    );

    let start = Instant::now();
    let mut hits = 0_usize;
    for _ in 0..iterations {
        if policy.is_authorized("/usr/bin/app-500", "secret") {
            hits += 1;
        }
    }
    let elapsed = start.elapsed();
    println!(
        "policy is_authorized (with {iterations} rules): {iterations} lookups in {elapsed:?} ({:.0} ops/sec, {hits} hits)",
        iterations as f64 / elapsed.as_secs_f64()
    );
}

fn bench_hash_binary() {
    let dir = tempfile::tempdir().unwrap();
    let path = dir.path().join("bench-binary");
    // Simulate a 1MB binary
    std::fs::write(&path, vec![0xAB; 1024 * 1024]).unwrap();

    let iterations = 100;
    let start = Instant::now();
    for _ in 0..iterations {
        let _ = envseal::guard::hash_binary(&path).unwrap();
    }
    let elapsed = start.elapsed();
    println!(
        "hash_binary (1MB): {iterations} ops in {:?} ({:.0} ops/sec)",
        elapsed,
        iterations as f64 / elapsed.as_secs_f64()
    );
}

fn bench_guard_env_check(iterations: usize) {
    // Save and clear hostile vars
    let saved_ld = std::env::var_os("LD_PRELOAD");
    let saved_dbg = std::env::var_os("DEBUGINFOD_URLS");
    let saved_ldlib = std::env::var_os("LD_LIBRARY_PATH");
    std::env::remove_var("LD_PRELOAD");
    std::env::remove_var("DEBUGINFOD_URLS");
    std::env::remove_var("LD_LIBRARY_PATH");

    let start = Instant::now();
    for _ in 0..iterations {
        let _ = envseal::guard::assess_environment();
    }
    let elapsed = start.elapsed();
    println!(
        "assess_environment: {iterations} ops in {:?} ({:.0} ops/sec)",
        elapsed,
        iterations as f64 / elapsed.as_secs_f64()
    );

    // Restore
    if let Some(v) = saved_ld {
        std::env::set_var("LD_PRELOAD", v);
    }
    if let Some(v) = saved_dbg {
        std::env::set_var("DEBUGINFOD_URLS", v);
    }
    if let Some(v) = saved_ldlib {
        std::env::set_var("LD_LIBRARY_PATH", v);
    }
}