hexvault 1.1.2

Cascading cell-partitioned encryption architecture.
Documentation
use hexvault::error::HexvaultError;
use hexvault::stack::{Layer, LayerContext, TokenResolver};
use hexvault::{generate_master_key, Vault};

struct DummyResolver;
impl TokenResolver for DummyResolver {
    fn resolve(&self, _token: &str) -> Result<LayerContext, HexvaultError> {
        Ok(LayerContext::empty())
    }
}

#[test]
fn test_insider_access_no_audit() {
    // Threat Model: Insider attempts to traverse data without audit.
    // Goal: Verify that the PUBLIC API does not offer a way to move data between cells
    // without invoking the Audit system.

    // NOTE: This test is structural/negative. We check that `Vault` has no
    // `traverse_no_log` or similar methods, and that accessing `Edge` directly
    // requires going through `traverse` which logs.

    let master = generate_master_key().unwrap();
    let mut vault = Vault::new(master, std::sync::Arc::new(DummyResolver));

    let partition = vault.get_partition("test").unwrap();
    let mut cell_a = partition.create_cell("a".into());
    let mut cell_b = partition.create_cell("b".into());
    let token = "";

    partition
        .seal(&mut cell_a, "secret", b"hush", Layer::AtRest, token)
        .unwrap();

    // The only way to move "secret" to "b" using `Vault` is `traverse`.
    vault
        .traverse(
            &partition,
            &cell_a,
            &partition,
            &mut cell_b,
            "secret",
            Layer::AtRest,
            token,
            token,
        )
        .unwrap();

    // And that MUST produce a log.
    assert!(!vault.audit_log().is_empty());
}