assay_core/runtime/mod.rs
1//! Runtime mandate enforcement.
2//!
3//! This module provides runtime authorization and consumption of mandates
4//! for tool calls. It ensures atomic single-use enforcement, nonce replay
5//! prevention, and idempotent consumption.
6//!
7//! ## Architecture (SPEC-Mandate-v1.0.3 §7)
8//!
9//! ```text
10//! ┌─────────────────────────────────────────────────────────────────┐
11//! │ MCP Proxy │
12//! │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │
13//! │ │ Policy Check │───▶│ Authorizer │───▶│ Forward to Tool │ │
14//! │ └──────────────┘ └──────┬───────┘ └────────┬─────────┘ │
15//! │ │ │ │
16//! │ ┌───────▼───────┐ ┌──────▼──────┐ │
17//! │ │ MandateStore │ │ Tool Server │ │
18//! │ │ (SQLite) │ └─────────────┘ │
19//! │ └───────────────┘ │
20//! └─────────────────────────────────────────────────────────────────┘
21//! ```
22
23mod authorizer;
24mod mandate_store;
25mod schema;
26
27/// One item, under `cfg(test)` only, for the divergence test in `mcp::policy::matcher`.
28///
29/// The first version of this made `mod authorizer` and `mod authorizer_internal` both
30/// `pub(crate)`, which reached the matcher by exposing the authorizer's entire internal surface
31/// — the mandate store, the consume path, the policy evaluator — in release builds, to get one
32/// function into one test. A re-export costs the crate exactly what the test needs.
33#[cfg(test)]
34pub(crate) use authorizer::glob_matches_impl;
35
36pub use authorizer::{
37 AuthorizeError, Authorizer, AuthzConfig, MandateData, MandateKind, OperationClass, PolicyError,
38 ToolCallData, DEFAULT_CLOCK_SKEW_SECONDS,
39};
40pub use mandate_store::{
41 compute_use_id, AuthzError, AuthzReceipt, ConsumeParams, MandateMetadata, MandateStore,
42};
43pub use schema::MANDATE_SCHEMA;