Skip to main content

systemprompt_models/profile/
governance.rs

1//! Governance configuration for the gateway + MCP authorization hook.
2//!
3//! Authz is **fail-closed** with an explicit-opt-in surface. Three modes:
4//!
5//! - `webhook` — production. Core POSTs every request to the configured URL;
6//!   any transport error, non-2xx, or decode failure denies the request.
7//! - `disabled` — denies every request via `DenyAllHook`. Use when authz is
8//!   intentionally inactive but you want the surface installed.
9//! - `unrestricted` — TEST/DEV ONLY. Allows every request via `AllowAllHook`.
10//!   Requires `acknowledgement` to equal the literal sentence `"I understand
11//!   this disables all authorization"`. Bootstrap errors otherwise.
12//!
13//! Absent `governance` block, absent `authz`, or any unparseable config →
14//! bootstrap installs `DenyAllHook` (everything denied) so misconfiguration
15//! never silently grants access.
16//!
17//! Example:
18//!
19//! ```yaml
20//! governance:
21//!   authz:
22//!     hook:
23//!       mode: webhook
24//!       url: http://localhost:8080/api/public/govern/authz
25//!       timeout_ms: 500
26//! ```
27
28use serde::{Deserialize, Serialize};
29
30pub const UNRESTRICTED_ACKNOWLEDGEMENT: &str = "I understand this disables all authorization";
31
32#[derive(Debug, Clone, Default, Serialize, Deserialize)]
33pub struct GovernanceConfig {
34    #[serde(default)]
35    pub authz: Option<AuthzConfig>,
36}
37
38#[derive(Debug, Clone, Serialize, Deserialize)]
39pub struct AuthzConfig {
40    pub hook: AuthzHookConfig,
41}
42
43#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
44#[serde(rename_all = "lowercase")]
45pub enum AuthzMode {
46    Webhook,
47    Disabled,
48    Unrestricted,
49}
50
51#[derive(Debug, Clone, Serialize, Deserialize)]
52pub struct AuthzHookConfig {
53    pub mode: AuthzMode,
54    #[serde(default)]
55    pub url: Option<String>,
56    #[serde(default = "default_timeout_ms")]
57    pub timeout_ms: u64,
58    #[serde(default)]
59    pub acknowledgement: Option<String>,
60}
61
62const fn default_timeout_ms() -> u64 {
63    500
64}