Skip to main content

systemprompt_security/policy/
registry.rs

1//! Inventory-based registration for governance policies.
2//!
3//! Companion to [`crate::authz::AuthzHookRegistration`]: policies register a
4//! factory at static-init time and [`super::GovernanceEngine::from_config`]
5//! resolves configured ids against the collected set. The four built-in
6//! policies in [`super::builtin`] self-register here; extensions add their own
7//! via [`crate::register_governance_policy!`] and enable them from the same
8//! `governance.policies` YAML sequence.
9//!
10//! Copyright (c) systemprompt.io — Business Source License 1.1.
11//! See <https://systemprompt.io> for licensing details.
12
13use serde_yaml::Value as YamlValue;
14
15use super::types::GovernancePolicy;
16
17/// Constructs one policy instance from its raw YAML config entry.
18///
19/// Runs once per [`super::GovernanceEngine::from_config`] call and must not
20/// block; a factory receives `YamlValue::Null` when the policy is absent from
21/// config. A rejected entry is an error the engine refuses to start on.
22pub type PolicyFactory =
23    fn(&YamlValue) -> Result<Box<dyn GovernancePolicy>, PolicyConfigurationError>;
24
25/// Why a policy factory rejected its YAML entry.
26#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
27#[error("{0}")]
28pub struct PolicyConfigurationError(pub String);
29
30/// One inventory submission per policy. `id` is the stable referent used in
31/// `governance.policies` YAML and in `governance_decisions.policy`.
32#[derive(Debug, Clone, Copy)]
33pub struct PolicyRegistration {
34    pub id: &'static str,
35    pub factory: PolicyFactory,
36}
37
38inventory::collect!(PolicyRegistration);
39
40#[doc(hidden)]
41pub use inventory;
42
43#[macro_export]
44macro_rules! register_governance_policy {
45    ($id:expr, $factory:expr) => {
46        $crate::policy::registry::inventory::submit! {
47            $crate::policy::PolicyRegistration {
48                id: $id,
49                factory: $factory,
50            }
51        }
52    };
53}