chio-wasm-guards 0.1.2

WASM guard runtime for Chio -- load and execute .wasm guard modules with fuel metering
//! WASM Guard Runtime for Chio.
//!
//! This crate allows operators to author guards in any language that compiles
//! to WebAssembly (Rust, AssemblyScript, Go, C) and load them into the Chio
//! kernel at runtime via `chio.yaml` configuration.
//!
//! # Dual-mode support
//!
//! The host transparently supports two WASM formats:
//!
//! - **Core modules** (raw ABI): traditional modules that export `evaluate(ptr, len) -> i32`.
//!   These are loaded through `WasmtimeBackend` with host-provided functions.
//! - **Component Model components** (WIT-based): modules compiled against the
//!   `chio:guard@0.1.0` WIT interface. These are loaded through `ComponentBackend`
//!   with type-safe bindings generated by `wasmtime::component::bindgen!`.
//!
//! Format detection happens automatically at load time via [`detect_wasm_format`].
//! The [`create_backend`] factory inspects binary magic bytes and routes to the
//! correct backend. Callers do not need to know which format a `.wasm` file uses.
//!
//! # Core module ABI
//!
//! Each core `.wasm` guard module exports a single function:
//!
//! ```text
//! evaluate(request_ptr: i32, request_len: i32) -> i32
//! ```
//!
//! The host serializes the guard request as JSON into guest memory, calls
//! `evaluate`, and interprets the return value:
//!
//! - `0` = Allow
//! - `1` = Deny (guard-specific reason returned through shared memory)
//! - any negative value = error (fail-closed)
//!
//! Fuel metering limits CPU consumption. When fuel runs out the guard is
//! treated as denied (fail-closed).
//!
//! # Feature flags
//!
//! - **`wasmtime-runtime`**: Enables the `wasmtime`-backed runtime. Without
//!   this feature only the trait-based abstractions are available, which is
//!   useful for testing or providing alternative backends.

#![cfg_attr(test, allow(clippy::expect_used, clippy::unwrap_used))]

#[cfg(loom)]
pub const LOOM_MODEL_ONLY: () = ();

#[cfg(not(loom))]
pub mod abi;
#[cfg(not(loom))]
pub mod blocklist;
#[cfg(not(loom))]
pub mod bundle_store;
#[cfg(all(not(loom), feature = "wasmtime-runtime"))]
pub mod component;
#[cfg(not(loom))]
pub mod config;
#[cfg(not(loom))]
pub mod epoch;
#[cfg(not(loom))]
pub mod error;
#[cfg(all(not(loom), feature = "wasmtime-runtime"))]
pub mod host;
#[cfg(not(loom))]
pub mod hot_reload;
#[cfg(not(loom))]
pub mod incident;
#[cfg(not(loom))]
pub mod manifest;
#[cfg(not(loom))]
pub mod metrics;
#[cfg(not(loom))]
pub mod observability;
#[cfg(not(loom))]
pub mod placeholders;
#[cfg(not(loom))]
pub mod runtime;
#[cfg(all(not(loom), feature = "wasmtime-runtime"))]
pub mod wiring;

// libFuzzer entry-point module, enabled only when the `fuzz` feature is
// turned on by the standalone `chio-fuzz` workspace at `../../fuzz`.
#[cfg(all(not(loom), feature = "fuzz"))]
pub mod fuzz;

#[cfg(not(loom))]
pub use abi::{GuardRequest, GuardVerdict, WasmGuardAbi};
#[cfg(not(loom))]
pub use blocklist::{
    normalize_digest, BlocklistError, GuardDigestBlocklist, E_GUARD_DIGEST_BLOCKLISTED,
};
#[cfg(not(loom))]
pub use bundle_store::{BundleError, BundleStore, InMemoryBundleStore};
#[cfg(all(not(loom), feature = "wasmtime-runtime"))]
pub use component::ComponentBackend;
#[cfg(not(loom))]
pub use config::WasmGuardConfig;
#[cfg(not(loom))]
pub use epoch::EpochId;
#[cfg(not(loom))]
pub use error::WasmGuardError;
#[cfg(all(not(loom), feature = "wasmtime-runtime"))]
pub use host::WasmHostState;
#[cfg(not(loom))]
pub use hot_reload::{
    CanaryCorpus, CanaryFixture, DebouncedReload, Engine, HotReloadError, RegistryDigestPoller,
    ReloadBackendFactory, ReloadTrigger, ReloadTriggerSource, ReloadWatchdog, WatchdogConfig,
    CANARY_FIXTURE_COUNT,
};
#[cfg(not(loom))]
pub use incident::{EvalTrace, IncidentError, IncidentWriter, ReloadIncident};
#[cfg(not(loom))]
pub use manifest::{
    load_signature_sidecar, signature_sidecar_path, signed_module_message, verify_guard_signature,
    verify_signed_module, write_signature_sidecar, GuardManifest, SignedWasmModule,
    MANIFEST_FILENAME, SIGNATURE_SUFFIX, SUPPORTED_ABI_VERSIONS,
};
#[cfg(not(loom))]
pub use metrics::{
    classify_deny_reason_class, epoch_label, guard_id_label_from_digest,
    register_guard_metric_families, register_guard_pool_metric_families, tenant_id_label,
    GuardMetricRegistrationError, GuardMetricRegistry, GuardPoolMetrics, GuardPoolMetricsSnapshot,
    MetricFamilyDescriptor, MetricFamilyKind, EVAL_DURATION_BUCKETS_SECONDS,
    E_GUARD_METRIC_CARDINALITY_EXCEEDED, GUARD_METRIC_FAMILIES, GUARD_POOL_METRIC_FAMILIES,
    HOST_CALL_DURATION_BUCKETS_SECONDS, HOST_FN_LABEL_VALUES, LABEL_EPOCH, LABEL_GUARD_ID,
    LABEL_HOST_FN, LABEL_OUTCOME, LABEL_REASON, LABEL_REASON_CLASS, LABEL_TENANT_ID, LABEL_VERDICT,
    MAX_GUARD_METRIC_CARDINALITY, METRIC_CHIO_GUARD_DENY_TOTAL,
    METRIC_CHIO_GUARD_EVAL_DURATION_SECONDS, METRIC_CHIO_GUARD_FUEL_CONSUMED_TOTAL,
    METRIC_CHIO_GUARD_HOST_CALL_DURATION_SECONDS, METRIC_CHIO_GUARD_MODULE_BYTES,
    METRIC_CHIO_GUARD_POOL_CHECKOUT_TOTAL, METRIC_CHIO_GUARD_POOL_EVICT_TOTAL,
    METRIC_CHIO_GUARD_POOL_WARM_SIZE, METRIC_CHIO_GUARD_RELOAD_TOTAL,
    METRIC_CHIO_GUARD_VERDICT_TOTAL, METRIC_CHIO_OTEL_INGRESS_DROP_TOTAL,
    METRIC_CHIO_OTEL_SINK_DROP_TOTAL, METRIC_CHIO_SIGNING_QUEUE_BLOCK_TOTAL, OVERFLOW_TENANT_ID,
    REASON_CLASS_LABEL_VALUES, REASON_CLASS_MALFORMED, REASON_CLASS_OTHER,
    RELOAD_OUTCOME_LABEL_VALUES, RUNTIME_METRIC_FAMILIES, UNKNOWN_TENANT_ID, VERDICT_LABEL_VALUES,
};
#[cfg(not(loom))]
pub use observability::{
    guard_digest_or_unknown, guard_evaluate_span, guard_fetch_blob_span, guard_host_call_span,
    guard_reload_span, guard_verify_span, DEFAULT_GUARD_VERSION, HOST_FETCH_BLOB, HOST_GET_CONFIG,
    HOST_GET_TIME_UNIX_SECS, HOST_LOG, RELOAD_APPLIED, RELOAD_CANARY_FAILED, RELOAD_ROLLED_BACK,
    SPAN_GUARD_EVALUATE, SPAN_GUARD_FETCH_BLOB, SPAN_GUARD_HOST_CALL, SPAN_GUARD_RELOAD,
    SPAN_GUARD_VERIFY, UNKNOWN_GUARD_DIGEST, VERDICT_ALLOW, VERDICT_DENY, VERDICT_ERROR,
    VERDICT_REWRITE, VERIFY_MODE_ED25519, VERIFY_RESULT_FAIL, VERIFY_RESULT_OK,
};
#[cfg(not(loom))]
pub use placeholders::{
    resolve_placeholders, resolve_placeholders_in_json, PlaceholderEnv, PlaceholderError,
    ProcessEnv,
};
#[cfg(all(not(loom), feature = "wasmtime-runtime"))]
pub use runtime::wasmtime_backend::{
    create_backend, detect_wasm_format, load_guards_from_policy, load_signed_guard, LoadError,
    PolicyCustomGuard, PolicyCustomGuards, PolicyModuleSource, WasmFormat, WasmGuardHandle,
    KNOWN_HOST_FUNCTIONS,
};
#[cfg(not(loom))]
pub use runtime::{backend::WasmGuardRuntime, guard::WasmGuard, module::LoadedModule};
#[cfg(all(not(loom), feature = "wasmtime-runtime"))]
pub use wiring::{build_guard_pipeline, load_wasm_guards};