blindplane-access 0.1.0

Signed enterprise access grants, capability policies, revocation and encrypted audit events for Blindplane
Documentation

Blindplane

Enterprise control without surrendering your users' plaintext.

Blindplane is an embeddable Rust security library for products that need encrypted data, organization-wide administration, and auditable access. It lets authorized users and tenant administrators share controlled visibility while the relay that stores and routes the data remains unable to decrypt it.

Clients encrypt records and audit events, sign every protected object, and enforce administrator-signed grants, policies, and revocation state. The relay can validate, store, index, and return those objects without holding a key that opens their protected content.

Prototype, not audited. Blindplane implements cryptographic primitives directly from their specifications and tests them against published vectors and established implementations. That is not a substitute for an independent security audit. Do not use this project for production secrets.

Why Blindplane

  • Embed it in an existing product. Keep your own identity, UI, storage, and business logic instead of adopting a complete security platform.
  • Give enterprises real control. Administrators can grant scoped access, enable or disable capabilities, rotate role keys, and revoke future access.
  • Preserve user visibility. A user can inspect their own encrypted activity; an authorized tenant administrator can inspect activity across the tenant.
  • Keep the service provider blind. Storage and routing code can verify authenticity and monotonic updates without receiving decryption keys.

Typical integrations include enterprise MCP and agent controls, encrypted audit trails, protected SaaS fields, and internal tools that must offer administrative oversight without making the hosting layer a universal plaintext reader.

How it works

A sealed record contains:

  • an AEAD-encrypted payload under a fresh object secret;
  • an HPKE envelope for each recipient;
  • a commitment to the object secret;
  • blind-index tokens for selected equality lookups;
  • an Ed25519 signature over the canonical record encoding.

The enterprise access layer adds:

  • principals for users, administrators, devices, and services;
  • administrator-signed role-key grants with explicit scope and expiry;
  • default-deny policies for MCP servers, tools, skills, and CLI access;
  • signed revocation epochs for future authorization and key rotation;
  • encrypted audit events readable by the owning user and tenant administrators.

The relay validates structure, signatures, route context, and monotonic versions. It cannot decrypt payloads or recipient envelopes because the server-side crates expose no decryption key type.

client                         relay                         client
  |                              |                              |
  | seal and sign                |                              |
  |----------------------------->| validate, store, index       |
  |                              |----------------------------->|
  |                              |                  verify, open |

What the relay can see

Blindplane does not hide all metadata. The relay sees:

  • tenant, object, field, epoch, version, and schema identifiers;
  • ciphertext length;
  • recipient identifiers and access changes;
  • grant subjects, scopes, permissions, expiry, and policy capability names;
  • equality and frequency within each blind-index scope;
  • access patterns.

The caller must decide whether those leaks are acceptable for its data model.

Workspace crates

Crate Purpose
blindplane-crypto Cryptographic primitives and simple high-level helpers
blindplane-wire Canonical record encoding and validation; no decryption API
blindplane-core Client-side sealing, opening, rekeying, and blind indexes
blindplane-access Signed grants, capability policies, revocation, and encrypted audit events
blindplane-relay Framework-neutral in-memory relay
blindplane-blazingly Typed Blazingly API for records and signed access objects
blindplane-cli Key generation and end-to-end self-check

The shipped crypto, wire, core, access, and relay crates have no third-party runtime dependencies. Their development dependencies are used only for tests.

Protect a record

use blindplane_core::{Author, RecipientKeypair, fastest_payload_suite, open, seal};
use blindplane_wire::RecordContext;

let author = Author::generate()?;
let alice = RecipientKeypair::generate("alice", 1)?;

let record = seal(
    &author,
    RecordContext {
        tenant: "acme".into(),
        object_id: "patient-42".into(),
        field: "diagnosis".into(),
        epoch: 1,
        version: 1,
        schema_version: 1,
    },
    b"the relay never sees this",
    &[alice.recipient()],
    vec![],
    fastest_payload_suite(),
)?;

// `record.encode()` is sent to a relay for validation and storage.
let plaintext = open(&record, &alice, author.public_key())?;
assert_eq!(plaintext.as_bytes(), b"the relay never sees this");
# Ok::<(), Box<dyn std::error::Error>>(())

Run the complete local self-check:

cargo run -p blindplane-cli -- selfcheck

Add enterprise access

blindplane-access is application-neutral. Your service keeps responsibility for identity onboarding, storage, UI, and provider adapters. Blindplane provides the canonical signed objects and cryptographic enforcement layer:

  • a personal audit role opens one subject's stream;
  • a tenant audit role opens every stream sealed to that role;
  • administrators receive the tenant role through signed grants;
  • capability decisions are available only after issuer, subject, time, revision, and revocation checks pass;
  • policy evaluation is exact-name and default-deny.

The runnable example issues grants and policy, seals one request for a user and tenant administrator, and opens it as both recipients:

cargo run -p blindplane-access --example enterprise_access

An agent platform such as GrantTap/Nodvox can map MCP servers, tools, skills, and usage events onto this API. Blindplane itself stays independent of any particular agent, model provider, or identity system.

HTTP examples

The Blazingly example runs a complete seal, store, search, fetch, and open flow through the adapter:

cargo run -p blindplane-blazingly --example sealed_api

The framework-neutral relay is also exposed through a small Axum adapter:

cargo run -p blindplane-relay --example axum_relay

The Blazingly adapter represents records and signed grants, policies, and revocation states as base64 inside typed JSON models. The Axum example accepts canonical record bytes directly. This is an adapter choice; the relay itself is independent of either wire shape.

Feature flags and targets

blindplane-crypto enables std and accel by default.

  • std enables operating-system entropy and heap-backed helpers.
  • accel enables runtime-selected CPU instruction paths and implies std.
  • --no-default-features --features std uses portable cryptographic paths.
  • --no-default-features builds the allocation-free no_std core with caller-supplied keys and entropy.

The portable std build still uses a small reviewed FFI block to request entropy from the operating system. The freestanding no_std build contains no unsafe code.

The core can be checked for WebAssembly without a separate implementation:

cargo build --target wasm32-unknown-unknown \
  -p blindplane-crypto --no-default-features

A browser binding must supply secure entropy for key generation and should run Argon2id outside the UI thread.

Security properties

  • Secret-dependent branches and memory addresses are treated as defects.
  • Secret comparisons use constant-time masked operations.
  • AEAD opening authenticates before releasing plaintext.
  • Failed opening clears the destination buffer.
  • AES-GCM is available only where supported CPU instructions are present; there is no table-based software AES fallback.
  • Ed25519 verification rejects non-canonical scalars and small-order keys.
  • Records use a canonical binary encoding before signing.
  • Recipient public keys must be pinned through a trusted channel.
  • Access objects are domain-separated and verified with a pinned issuer key.
  • Policy evaluation fails closed before trust, time, revision, and epoch checks.
  • Audit content is encrypted for a user role and tenant-administrator role.
  • A persisted signed chain head detects rollback for one client history.

Current limitations

  • The project has not received an independent security audit.
  • The included relay store is in memory and is not a production database.
  • Identity-provider login, recovery, device enrolment, and issuer-key onboarding are integration responsibilities and are not included.
  • A modified endpoint can bypass a locally embedded policy verifier. MDM, attestation, code signing, and gateway enforcement require separate controls.
  • Offline clients learn revocation only after refreshing signed state or when a short-lived grant expires.
  • Tenant administrators intentionally receive access to audit content sealed to the tenant audit role.
  • The per-client rollback head does not provide cross-client fork consistency.
  • Password-derived vault data remains subject to offline guessing if an attacker obtains the encrypted blob.
  • Revocation prevents future access after rekeying but cannot revoke plaintext a former recipient already obtained.
  • AES-256-GCM currently requires AArch64 crypto extensions; other targets use ChaCha20-Poly1305.

Verification

cargo fmt --all --check
cargo test --workspace --all-targets --locked
cargo test --workspace --doc --locked
cargo test -p blindplane-crypto \
  --no-default-features --features std --locked
cargo check -p blindplane-crypto --no-default-features --locked
cargo check -p blindplane-access --no-default-features --locked
cargo clippy --workspace --all-targets --locked -- -D warnings

The crypto test suite includes RFC, FIPS, and NIST vectors, negative tests, split-call streaming tests, and byte-for-byte interoperability checks against independent implementations.

License

MIT OR Apache-2.0.