blindplane-access 0.1.0

Signed enterprise access grants, capability policies, revocation and encrypted audit events for Blindplane
Documentation
//! Public principal and canonical-codec behavior.

use blindplane_access::{
    AccessError, AccessIssuer, AccessValidationPolicy, Principal, PrincipalKeypair, PrincipalKind,
};

#[test]
fn principal_encoding_is_canonical_and_bounded() {
    let keys = PrincipalKeypair::from_secret_bytes(
        "acme",
        "alice",
        PrincipalKind::User,
        1,
        [7; 32],
        [9; 32],
    )
    .unwrap();
    let encoded = keys.principal().encode();

    assert_eq!(
        Principal::decode(&encoded, &AccessValidationPolicy::default()).unwrap(),
        *keys.principal()
    );

    let with_trailing_byte = [encoded, vec![0]].concat();
    assert_eq!(
        Principal::decode(&with_trailing_byte, &AccessValidationPolicy::default()),
        Err(AccessError::TrailingBytes)
    );
}

#[test]
fn principals_reject_invalid_identity_and_key_epochs() {
    assert_eq!(
        PrincipalKeypair::from_secret_bytes("", "alice", PrincipalKind::User, 1, [7; 32], [9; 32],)
            .unwrap_err(),
        AccessError::InvalidIdentifier
    );
    assert_eq!(
        PrincipalKeypair::from_secret_bytes(
            "acme",
            "alice",
            PrincipalKind::User,
            0,
            [7; 32],
            [9; 32],
        )
        .unwrap_err(),
        AccessError::InvalidEpoch
    );
}

#[test]
fn issuer_identity_is_derived_from_the_signing_key() {
    let issuer = AccessIssuer::from_seed("tenant-admin", [11; 32]).unwrap();
    let trusted = issuer.trusted();

    assert_eq!(trusted.issuer_id(), "tenant-admin");
    assert_ne!(trusted.key_id(), [0; 32]);
    assert_eq!(trusted.public_key(), issuer.public_key());
}

#[test]
fn every_truncated_principal_encoding_is_rejected() {
    let keys = PrincipalKeypair::from_secret_bytes(
        "acme",
        "alice",
        PrincipalKind::User,
        1,
        [7; 32],
        [9; 32],
    )
    .unwrap();
    let encoded = keys.principal().encode();

    for end in 0..encoded.len() {
        assert!(
            Principal::decode(&encoded[..end], &AccessValidationPolicy::default()).is_err(),
            "accepted truncation at byte {end}"
        );
    }
}