Skip to main content

Crate cpex

Crate cpex 

Source
Expand description

CPEX is a policy enforcement runtime for AI agents.

It is a deterministic reference monitor between an agent and every capability it invokes: tools, prompts, resources, inference providers, and A2A methods. Each operation runs through a policy-defined pipeline that can resolve identity, make an authorization decision (delegated to an engine like Cedar, CEL or OPA), exchange and reduce credentials before a downstream call, track information flow across calls, and audit. You write that policy declaratively in APL, the configuration that defines each operation’s pipeline; CPEX evaluates and enforces it at the boundary, against state the model cannot observe or forge.

§This crate

cpex is the host facade over the praxis-policy engine (PPE). It re-exports the whole public surface of praxis_policy, built with every stable builtin and the bundled hyper HTTP transport, so a host depends on this one crate. Every item documented on praxis_policy is reachable here under the same name: PolicyEngine, install_builtins, prelude, AplOptions, the builtin factory types, HyperTransport and install_default_http_transport.

Two CPEX-only additions sit on top: the host module, which holds the wiring the C FFI and the Python wheel share (host::install_host_defaults, host::secret_error_kind, the host::REMOVED_HOOKS table and the inbound identity check), and the out-of-process Python plugin host, behind the python-host feature.

§Usage

use std::sync::Arc;
use cpex::PolicyEngine;

let engine = Arc::new(PolicyEngine::default());
// Register every builtin factory and install the APL config visitor
// (in-process defaults) in one call:
cpex::install_builtins(&engine);
// Builtins that call out over HTTP (JWKS, token exchange, CIBA, Vault)
// need a transport. The bundled one refuses private destinations.
cpex::install_default_http_transport(&engine);
// ... then load a config that references the builtin `kind`s.

§Features

Every stable PPE builtin is always compiled in. The PII scanner and audit logger are not builtins: they are reference plugins a host registers itself.

python-host pulls cpex-hosts-python, which runs existing Python CPEX plugins out-of-process (one cached virtualenv and one worker.py subprocess per plugin), and re-exports IsolatedVenvFactory and ISOLATED_VENV_KIND here. There is no install_* helper for it: register the factory yourself, because the kind is one host serving arbitrarily many Python plugins.

ⓘ
use std::sync::Arc;
use cpex::{IsolatedVenvFactory, PolicyEngine, ISOLATED_VENV_KIND};

let engine = Arc::new(PolicyEngine::default());
engine.register_factory(ISOLATED_VENV_KIND, Box::new(IsolatedVenvFactory));
engine.load_config_yaml(yaml)?;
// `initialize()` builds each venv and launches its worker. A cold pip
// install is measured in minutes, so do it at startup, not on demand.
engine.initialize().await?;

Re-exports§

pub use ppe as praxis_policy;
pub use cpex_hosts_python;

Modules§

host
Host wiring shared by the CPEX language bindings.
http_hyper
A default HttpTransport on hyper, for hosts that inject none.
praxis_policy_apl_cmf
Flattens typed extensions into the attribute vocabulary policies are written against.
praxis_policy_apl_core
APL — Authorization Policy Language.
praxis_policy_apl_runtime
Connects the APL evaluator to the plugin runtime.
praxis_policy_core
The plugin runtime: engine, executor, hook registry, and config parser.

Structs§

ApiKeyIdentityFactory
Factory for kind: identity/api-key plugins.
AplOptions
Configuration for register_apl. All runtime collaborators APL needs to do its work are funneled through here so the call site reads as a single block instead of a multi-step builder.
CedarDirectPdpFactory
Factory for CedarDirectResolver. Reports kind() = "cedar-direct"; builds resolvers from the unified-config block via CedarDirectResolver::from_config.
CelPdpFactory
Factory for CelResolver. Reports kind() = "cel"; builds resolvers from the unified-config block via CelResolver::from_config.
CibaApproverFactory
Factory for kind: elicitation/ciba plugins. Instantiates a CibaApprover from the config: block and registers it on the elicit hook.
DispatchCache
Host-owned dispatch cache. Construct once, share via Arc<DispatchCache> across all CmfPluginInvoker::for_request calls so plans built for one request can be reused by the next.
HyperTransport
A HttpTransport backed by hyper with rustls.
IsolatedVenvFactory
Creates out-of-process Python plugins from isolated_venv config entries.
JwtIdentityFactory
Factory for kind: identity/jwt plugins. Instantiates a JwtIdentityResolver from the config: block and registers it on the identity.resolve hook.
MemorySessionStore
In-process SessionStore backed by a HashMap of HashSets. Suitable for tests, single-process deployments, and as the default when no distributed store is configured. Cloning the store via Arc shares state across all consumers.
OAuthDelegatorFactory
Factory for kind: delegator/oauth plugins. Instantiates an OAuthDelegator from the config: block and registers it on the token.delegate hook.
OpaPdpFactory
Factory for OpaResolver. Reports kind() = "opa"; builds resolvers from the unified-config block via OpaResolver::from_config.
PluginInstance
The two types a host needs to accept a plugin it did not compile in: PolicyEngine::register_factory takes a Box<dyn PluginFactory>, and PluginInstance is what that factory returns.
PolicyEngine
Owns registered plugins and dispatches hook invocations to them.
ProviderFailure
What a host needs to give the engine its secrets.
ProviderHealth
What a host needs to give the engine its secrets.
RefreshReport
What a host needs to give the engine its secrets.
SecretProviderRegistry
What a host needs to give the engine its secrets.
SecretRef
What a host needs to give the engine its secrets.
SecretSnapshot
What a host needs to give the engine its secrets.
ValkeyConfig
Parsed global.session_store config for kind: valkey.
ValkeySessionStoreFactory
Factory the host registers via AplOptions.session_store_factories.
VaultDelegatorFactory
Factory that constructs a VaultDelegator from its plugin configuration.
VaultSecretProviderFactory
Builds a Vault KV v2 SecretProvider.

Enums§

SecretError
What a host needs to give the engine its secrets.
SecretsHealth
What a host needs to give the engine its secrets.

Constants§

API_KEY_KIND
The plugin kind: string operators write in PPE YAML.
CIBA_KIND
The plugin kind: string operators write in PPE YAML to declare a CIBA elicitation handler.
ISOLATED_VENV_KIND
kind: string operators write in CPEX YAML to declare a Python plugin that runs out-of-process in its own virtualenv.
JWT_KIND
The plugin kind: string operators write in PPE YAML to declare a JWT identity resolver.
OAUTH_KIND
The plugin kind: string operators write in PPE YAML to declare an OAuth RFC 8693 token-exchange delegator.
VALKEY_KIND
The kind: discriminator this factory builds. Part of the public surface — it is the string operators write in their config.
VAULT_DELEGATOR_KIND
The kind: value operators write in PPE YAML to select this plugin.
VAULT_SECRET_KIND
The kind: this factory registers as.

Traits§

PdpFactory
Build a PdpResolver from a unified-config block. Implemented per PDP backend (cedar-direct, opa, …) and registered with the praxis-policy-apl-runtime visitor so unified-config YAML can declare PDPs without the host pre-constructing them in code.
PluginFactory
The two types a host needs to accept a plugin it did not compile in: PolicyEngine::register_factory takes a Box<dyn PluginFactory>, and PluginInstance is what that factory returns.
SecretProvider
What a host needs to give the engine its secrets.
SecretProviderFactory
What a host needs to give the engine its secrets.
SessionStore
Pluggable session-state backend. Implementations must be Send + Sync — the same store is shared across all concurrent requests.
SessionStoreFactory
Factory the visitor consults when it encounters a global.session_store block in the unified config. Mirrors praxis_policy_apl_core::step::PdpFactory: each factory advertises a kind() string matching the YAML block’s kind: field, and build turns the block into a live store. Registered up front via crate::AplOptions::session_store_factories; the visitor selects the active store from config during its global-config walk, before any route handler captures the store.

Functions§

builtin_pdp_factories
The enabled PDP factories, ready to drop into AplOptions::pdp_factories. A route’s cedar:, cel: or opa: step selects which one runs.
builtin_session_store_factories
The enabled session-store factories, ready to drop into AplOptions::session_store_factories. A global.session_store: { kind: ... } config block selects one; absent that, the in-process MemorySessionStore default stays active.
install_builtins
Register every enabled plugin factory and install the APL config visitor on mgr with in-process defaults (a MemorySessionStore and the default baseline capabilities). The enabled PDP and session-store factories are wired in, so a later config load can reference any of them by kind.
install_builtins_with_default_http_transport
Register the enabled builtins and use hyper when the host has not already installed an HTTP transport.
install_default_http_transport
Install the bundled hyper transport so plugins can perform outbound HTTP.
register_apl
Build an AplConfigVisitor from the supplied options and register it on the engine. Returns the Arc<AplConfigVisitor> so the caller can stash it for later inspection (or call register_pdp on it after the fact for late-bound resolvers) — but in the typical case the return value is dropped and the visitor lives inside the engine’s visitor list.
register_builtin_plugins
Register every enabled by-kind plugin factory on mgr: identity (jwt), delegators (oauth), and elicitation approvers (elicitation-ciba). Call before loading a config so the engine can instantiate plugins whose YAML kind: matches.
register_vault_secret_provider
Register this backend on registry.
registry_with_vault
A registry with env, file, and vault.