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.
- Guide and concepts: https://contextforge-org.github.io/cpex/
- Source and issues: https://github.com/contextforge-org/cpex
§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
HttpTransporton 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§
- ApiKey
Identity Factory - Factory for
kind: identity/api-keyplugins. - 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. - Cedar
Direct PdpFactory - Factory for
CedarDirectResolver. Reportskind() = "cedar-direct"; builds resolvers from the unified-config block viaCedarDirectResolver::from_config. - CelPdp
Factory - Factory for
CelResolver. Reportskind() = "cel"; builds resolvers from the unified-config block viaCelResolver::from_config. - Ciba
Approver Factory - Factory for
kind: elicitation/cibaplugins. Instantiates aCibaApproverfrom theconfig:block and registers it on theelicithook. - Dispatch
Cache - Host-owned dispatch cache. Construct once, share via
Arc<DispatchCache>across allCmfPluginInvoker::for_requestcalls so plans built for one request can be reused by the next. - Hyper
Transport - A
HttpTransportbacked by hyper with rustls. - Isolated
Venv Factory - Creates out-of-process Python plugins from
isolated_venvconfig entries. - JwtIdentity
Factory - Factory for
kind: identity/jwtplugins. Instantiates aJwtIdentityResolverfrom theconfig:block and registers it on theidentity.resolvehook. - Memory
Session Store - In-process
SessionStorebacked by aHashMapofHashSets. Suitable for tests, single-process deployments, and as the default when no distributed store is configured. Cloning the store viaArcshares state across all consumers. - OAuth
Delegator Factory - Factory for
kind: delegator/oauthplugins. Instantiates anOAuthDelegatorfrom theconfig:block and registers it on thetoken.delegatehook. - OpaPdp
Factory - Factory for
OpaResolver. Reportskind() = "opa"; builds resolvers from the unified-config block viaOpaResolver::from_config. - Plugin
Instance - The two types a host needs to accept a plugin it did not compile in:
PolicyEngine::register_factorytakes aBox<dyn PluginFactory>, andPluginInstanceis what that factory returns. - Policy
Engine - Owns registered plugins and dispatches hook invocations to them.
- Provider
Failure - What a host needs to give the engine its secrets.
- Provider
Health - What a host needs to give the engine its secrets.
- Refresh
Report - What a host needs to give the engine its secrets.
- Secret
Provider Registry - What a host needs to give the engine its secrets.
- Secret
Ref - What a host needs to give the engine its secrets.
- Secret
Snapshot - What a host needs to give the engine its secrets.
- Valkey
Config - Parsed
global.session_storeconfig forkind: valkey. - Valkey
Session Store Factory - Factory the host registers via
AplOptions.session_store_factories. - Vault
Delegator Factory - Factory that constructs a
VaultDelegatorfrom its plugin configuration. - Vault
Secret Provider Factory - Builds a Vault KV v2
SecretProvider.
Enums§
- Secret
Error - What a host needs to give the engine its secrets.
- Secrets
Health - 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
PdpResolverfrom 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. - Plugin
Factory - The two types a host needs to accept a plugin it did not compile in:
PolicyEngine::register_factorytakes aBox<dyn PluginFactory>, andPluginInstanceis what that factory returns. - Secret
Provider - What a host needs to give the engine its secrets.
- Secret
Provider Factory - What a host needs to give the engine its secrets.
- Session
Store - Pluggable session-state backend. Implementations must be
Send + Sync— the same store is shared across all concurrent requests. - Session
Store Factory - Factory the visitor consults when it encounters a
global.session_storeblock in the unified config. Mirrorspraxis_policy_apl_core::step::PdpFactory: each factory advertises akind()string matching the YAML block’skind:field, andbuildturns the block into a live store. Registered up front viacrate::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’scedar:,cel:oropa:step selects which one runs. - builtin_
session_ store_ factories - The enabled session-store factories, ready to drop into
AplOptions::session_store_factories. Aglobal.session_store: { kind: ... }config block selects one; absent that, the in-processMemorySessionStoredefault stays active. - install_
builtins - Register every enabled plugin factory and install the APL config visitor on
mgrwith in-process defaults (aMemorySessionStoreand the default baseline capabilities). The enabled PDP and session-store factories are wired in, so a later config load can reference any of them bykind. - 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
AplConfigVisitorfrom the supplied options and register it on the engine. Returns theArc<AplConfigVisitor>so the caller can stash it for later inspection (or callregister_pdpon 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 YAMLkind:matches. - register_
vault_ secret_ provider - Register this backend on
registry. - registry_
with_ vault - A registry with
env,file, andvault.