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. Four 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//! - `extension` — production. The hook is supplied at bootstrap by the binary
8//!   via `AppContextBuilder::with_authz_hook(...)`. Bootstrap errors if no hook
9//!   is supplied. See `internal/guides/authz.md`.
10//! - `disabled` — denies every request via `DenyAllHook`. Use when authz is
11//!   intentionally inactive but you want the surface installed.
12//! - `unrestricted` — TEST/DEV ONLY. Allows every request via `AllowAllHook`.
13//!   Requires `acknowledgement` to equal the literal sentence `"I understand
14//!   this disables all authorization"`. Bootstrap errors otherwise.
15//!
16//! Absent `governance` block, absent `authz`, or any unparseable config →
17//! bootstrap installs `DenyAllHook` (everything denied) so misconfiguration
18//! never silently grants access.
19//!
20//! Example:
21//!
22//! ```yaml
23//! governance:
24//!   authz:
25//!     hook:
26//!       mode: webhook
27//!       url: http://localhost:8080/api/public/govern/authz
28//!       timeout_ms: 500
29//! ```
30
31use serde::{Deserialize, Serialize};
32
33pub const UNRESTRICTED_ACKNOWLEDGEMENT: &str = "I understand this disables all authorization";
34
35#[derive(Debug, Clone, Default, Serialize, Deserialize, schemars::JsonSchema)]
36#[serde(deny_unknown_fields)]
37pub struct GovernanceConfig {
38    #[serde(default)]
39    pub authz: Option<AuthzConfig>,
40}
41
42#[derive(Debug, Clone, Serialize, Deserialize, schemars::JsonSchema)]
43#[serde(deny_unknown_fields)]
44pub struct AuthzConfig {
45    pub hook: AuthzHookConfig,
46}
47
48#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, schemars::JsonSchema)]
49#[serde(rename_all = "lowercase")]
50pub enum AuthzMode {
51    Webhook,
52    Extension,
53    Disabled,
54    Unrestricted,
55}
56
57#[derive(Debug, Clone, Serialize, Deserialize, schemars::JsonSchema)]
58#[serde(deny_unknown_fields)]
59pub struct AuthzHookConfig {
60    pub mode: AuthzMode,
61    #[serde(default)]
62    pub url: Option<String>,
63    #[serde(default = "default_timeout_ms")]
64    pub timeout_ms: u64,
65    #[serde(default)]
66    pub acknowledgement: Option<String>,
67}
68
69const fn default_timeout_ms() -> u64 {
70    500
71}