systemprompt_models/bridge/opencode/
policy.rs1use serde::{Deserialize, Serialize};
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
9#[serde(rename_all = "lowercase")]
10pub enum PolicyEffect {
11 Allow,
12 Deny,
13}
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
16pub enum PolicyAction {
17 #[serde(rename = "tool.use")]
18 Tool,
19 #[serde(rename = "provider.use")]
20 Provider,
21 #[serde(rename = "integration.use")]
22 Integration,
23}
24
25#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
27pub struct Policy {
28 pub effect: PolicyEffect,
29 pub action: PolicyAction,
30 pub resource: String,
31}
32
33impl Policy {
34 #[must_use]
35 pub fn allow(action: PolicyAction, resource: impl Into<String>) -> Self {
36 Self {
37 effect: PolicyEffect::Allow,
38 action,
39 resource: resource.into(),
40 }
41 }
42
43 #[must_use]
44 pub fn deny(action: PolicyAction, resource: impl Into<String>) -> Self {
45 Self {
46 effect: PolicyEffect::Deny,
47 action,
48 resource: resource.into(),
49 }
50 }
51}
52
53#[derive(Debug, Clone, Copy)]
55pub struct Lockdown<'a> {
56 pub provider: &'a str,
57 pub allowed_tools: &'a [String],
58 pub denied_tools: &'a [String],
59 pub allowed_mcp: &'a [String],
60 pub allowed_plugins: &'a [String],
61}
62
63#[must_use]
64pub fn lockdown_policies(lockdown: &Lockdown<'_>) -> Vec<Policy> {
65 let mut out = vec![
66 Policy::deny(PolicyAction::Provider, "*"),
67 Policy::allow(PolicyAction::Provider, lockdown.provider),
68 Policy::deny(PolicyAction::Integration, "mcp:*"),
69 Policy::deny(PolicyAction::Integration, "plugin:*"),
70 ];
71 out.extend(
72 lockdown
73 .allowed_plugins
74 .iter()
75 .map(|plugin| Policy::allow(PolicyAction::Integration, format!("plugin:{plugin}"))),
76 );
77 out.extend(
78 lockdown
79 .allowed_mcp
80 .iter()
81 .map(|name| Policy::allow(PolicyAction::Integration, format!("mcp:{name}"))),
82 );
83 if !lockdown.allowed_tools.is_empty() {
84 out.push(Policy::deny(PolicyAction::Tool, "*"));
85 out.extend(
86 lockdown
87 .allowed_tools
88 .iter()
89 .map(|tool| Policy::allow(PolicyAction::Tool, format!("{tool}:*"))),
90 );
91 }
92 out.extend(
93 lockdown
94 .denied_tools
95 .iter()
96 .map(|tool| Policy::deny(PolicyAction::Tool, format!("{tool}:*"))),
97 );
98 out
99}