pub use {
praxis_policy_apl_cmf, praxis_policy_apl_core, praxis_policy_apl_runtime, praxis_policy_core,
};
pub use praxis_policy_apl_core::step::PdpFactory;
pub use praxis_policy_apl_runtime::{
AplOptions, DispatchCache, MemorySessionStore, SessionStore, SessionStoreFactory, register_apl,
};
pub use praxis_policy_core::engine::PolicyEngine;
pub use praxis_policy_core::factory::{PluginFactory, PluginInstance};
pub use praxis_policy_core::prelude;
#[cfg(feature = "cedar")]
pub use praxis_policy_pdp_cedar_direct::CedarDirectPdpFactory;
#[cfg(feature = "cel")]
pub use praxis_policy_pdp_cel::CelPdpFactory;
#[cfg(feature = "opa")]
pub use praxis_policy_pdp_opa::OpaPdpFactory;
#[cfg(feature = "oauth")]
pub use praxis_policy_plugin_delegator_oauth::{KIND as OAUTH_KIND, OAuthDelegatorFactory};
#[cfg(feature = "elicitation-ciba")]
pub use praxis_policy_plugin_elicitation_ciba::{CibaApproverFactory, KIND as CIBA_KIND};
#[cfg(feature = "jwt")]
pub use praxis_policy_plugin_identity_jwt::{JwtIdentityFactory, KIND as JWT_KIND};
#[cfg(feature = "valkey")]
pub use praxis_policy_session_valkey::{
KIND as VALKEY_KIND, ValkeyConfig, ValkeySessionStoreFactory,
};
#[cfg(feature = "_builtin")]
macro_rules! register_builtins {
( $( feature $feat:literal => $krate:ident :: $factory:ident ),* $(,)? ) => {
#[allow(unused_variables)]
pub fn register_builtin_plugins(mgr: &std::sync::Arc<PolicyEngine>) {
$(
#[cfg(feature = $feat)]
mgr.register_factory($krate::KIND, Box::new($krate::$factory));
)*
}
};
}
#[cfg(feature = "_builtin")]
register_builtins! {
feature "jwt" => praxis_policy_plugin_identity_jwt::JwtIdentityFactory,
feature "oauth" => praxis_policy_plugin_delegator_oauth::OAuthDelegatorFactory,
feature "elicitation-ciba" => praxis_policy_plugin_elicitation_ciba::CibaApproverFactory,
}
#[cfg(feature = "_builtin")]
#[allow(unused_mut, clippy::vec_init_then_push)]
pub fn builtin_pdp_factories() -> Vec<std::sync::Arc<dyn PdpFactory>> {
let mut factories: Vec<std::sync::Arc<dyn PdpFactory>> = Vec::new();
#[cfg(feature = "cedar")]
factories.push(std::sync::Arc::new(CedarDirectPdpFactory::new()));
#[cfg(feature = "cel")]
factories.push(std::sync::Arc::new(CelPdpFactory::new()));
#[cfg(feature = "opa")]
factories.push(std::sync::Arc::new(OpaPdpFactory::new()));
factories
}
#[cfg(feature = "_builtin")]
#[allow(unused_mut, clippy::vec_init_then_push)]
pub fn builtin_session_store_factories() -> Vec<std::sync::Arc<dyn SessionStoreFactory>> {
let mut factories: Vec<std::sync::Arc<dyn SessionStoreFactory>> = Vec::new();
#[cfg(feature = "valkey")]
factories.push(std::sync::Arc::new(ValkeySessionStoreFactory::new()));
factories
}
#[cfg(feature = "_builtin")]
pub fn install_builtins(mgr: &std::sync::Arc<PolicyEngine>) {
register_builtin_plugins(mgr);
let mut opts = AplOptions::in_process();
opts.pdp_factories = builtin_pdp_factories();
opts.session_store_factories = builtin_session_store_factories();
let _visitor = register_apl(mgr, opts);
}
#[cfg(all(test, feature = "_builtin"))]
mod tests {
use super::*;
use std::sync::Arc;
#[test]
fn install_builtins_runs_without_panic() {
let mgr = Arc::new(PolicyEngine::default());
install_builtins(&mgr);
}
#[test]
fn pdp_factories_track_enabled_features() {
let expected = usize::from(cfg!(feature = "cedar"))
+ usize::from(cfg!(feature = "cel"))
+ usize::from(cfg!(feature = "opa"));
assert_eq!(
builtin_pdp_factories().len(),
expected,
"one PDP factory per enabled feature",
);
}
#[test]
fn session_store_factories_track_enabled_features() {
let expected = usize::from(cfg!(feature = "valkey"));
assert_eq!(
builtin_session_store_factories().len(),
expected,
"one session-store factory per enabled feature",
);
}
fn load_error_for_kind(kind: &str) -> String {
let mgr = Arc::new(PolicyEngine::default());
install_builtins(&mgr);
let yaml =
format!("plugins:\n - name: probe\n kind: {kind}\n hooks: [identity.resolve]\n");
match mgr.load_config_yaml(&yaml) {
Ok(()) => String::new(),
Err(e) => format!("{e}"),
}
}
#[test]
fn every_enabled_builtin_resolves_its_kind() {
let expected = [
(cfg!(feature = "jwt"), "identity/jwt"),
(cfg!(feature = "oauth"), "delegator/oauth"),
(cfg!(feature = "elicitation-ciba"), "elicitation/ciba"),
];
for (enabled, kind) in expected {
if !enabled {
continue;
}
let err = load_error_for_kind(kind);
assert!(
!err.contains("no factory registered"),
"{kind} is enabled, so its factory must be registered; got: {err}"
);
}
}
#[test]
fn the_reference_plugins_are_not_registered_by_the_umbrella() {
for kind in ["validator/pii-scan", "audit/logger"] {
let err = load_error_for_kind(kind);
assert!(
err.contains("no factory registered"),
"{kind} must not be bundled; got: {err}"
);
assert!(
err.contains(kind),
"the error must name the unresolved kind: {err}"
);
}
}
}