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, schemars::JsonSchema)]
33#[serde(deny_unknown_fields)]
34pub struct GovernanceConfig {
35    #[serde(default)]
36    pub authz: Option<AuthzConfig>,
37}
38
39#[derive(Debug, Clone, Serialize, Deserialize, schemars::JsonSchema)]
40#[serde(deny_unknown_fields)]
41pub struct AuthzConfig {
42    pub hook: AuthzHookConfig,
43}
44
45#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, schemars::JsonSchema)]
46#[serde(rename_all = "lowercase")]
47pub enum AuthzMode {
48    Webhook,
49    Disabled,
50    Unrestricted,
51}
52
53#[derive(Debug, Clone, Serialize, Deserialize, schemars::JsonSchema)]
54#[serde(deny_unknown_fields)]
55pub struct AuthzHookConfig {
56    pub mode: AuthzMode,
57    #[serde(default)]
58    pub url: Option<String>,
59    #[serde(default = "default_timeout_ms")]
60    pub timeout_ms: u64,
61    #[serde(default)]
62    pub acknowledgement: Option<String>,
63}
64
65const fn default_timeout_ms() -> u64 {
66    500
67}