1use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5
6#[derive(Debug, Clone, Serialize, Deserialize, Default)]
10pub struct ToolContext {
11 pub name: String,
13 #[serde(skip_serializing_if = "Option::is_none")]
15 pub arguments: Option<HashMap<String, serde_json::Value>>,
16 #[serde(skip_serializing_if = "Option::is_none")]
18 pub server_id: Option<String>,
19 #[serde(skip_serializing_if = "Option::is_none")]
21 pub is_builtin: Option<bool>,
22 #[serde(skip_serializing_if = "Option::is_none")]
24 pub description: Option<String>,
25}
26
27#[derive(Debug, Clone, Serialize, Deserialize, Default)]
29pub struct ModelContext {
30 #[serde(skip_serializing_if = "Option::is_none")]
31 pub provider: Option<String>,
32 #[serde(skip_serializing_if = "Option::is_none")]
33 pub model: Option<String>,
34 #[serde(skip_serializing_if = "Option::is_none")]
35 pub temperature: Option<f64>,
36 #[serde(skip_serializing_if = "Option::is_none")]
37 pub tokens_used: Option<i64>,
38 #[serde(skip_serializing_if = "Option::is_none")]
39 pub max_tokens: Option<i64>,
40}
41
42#[derive(Debug, Clone, Serialize, Deserialize, Default)]
44pub struct FileContext {
45 pub path: String,
47 pub operation: String,
49 #[serde(skip_serializing_if = "Option::is_none")]
50 pub size: Option<i64>,
51 #[serde(skip_serializing_if = "Option::is_none")]
52 pub mime_type: Option<String>,
53}
54
55#[derive(Debug, Clone, Serialize, Deserialize, Default)]
57pub struct McpContext {
58 #[serde(skip_serializing_if = "Option::is_none")]
59 pub server_name: Option<String>,
60 #[serde(skip_serializing_if = "Option::is_none")]
61 pub server_url: Option<String>,
62 #[serde(skip_serializing_if = "Option::is_none")]
63 pub transport: Option<String>,
64 #[serde(skip_serializing_if = "Option::is_none")]
65 pub verified: Option<bool>,
66 #[serde(skip_serializing_if = "Option::is_none")]
67 pub capabilities: Option<Vec<String>>,
68}
69
70#[derive(Debug, Clone, Serialize, Default)]
74pub struct ShieldRequest {
75 pub content: String,
77 pub content_type: String,
79 pub action: String,
82
83 #[serde(skip_serializing_if = "Option::is_none")]
85 pub tool: Option<ToolContext>,
86 #[serde(skip_serializing_if = "Option::is_none")]
87 pub model: Option<ModelContext>,
88 #[serde(skip_serializing_if = "Option::is_none")]
89 pub file: Option<FileContext>,
90 #[serde(skip_serializing_if = "Option::is_none")]
91 pub mcp: Option<McpContext>,
92
93 #[serde(skip_serializing_if = "Option::is_none")]
95 pub session_id: Option<String>,
96
97 #[serde(skip_serializing_if = "Option::is_none")]
100 pub mode: Option<String>,
101 #[serde(skip_serializing_if = "Option::is_none")]
103 pub detectors: Option<Vec<String>>,
104 #[serde(skip_serializing_if = "Option::is_none")]
106 pub metadata: Option<HashMap<String, serde_json::Value>>,
107 #[serde(skip_serializing_if = "Option::is_none")]
109 pub contexts: Option<Vec<String>>,
110 #[serde(skip_serializing_if = "Option::is_none")]
112 pub early_exit: Option<bool>,
113 #[serde(skip_serializing_if = "Option::is_none")]
115 pub explain: Option<bool>,
116 #[serde(skip_serializing_if = "Option::is_none")]
118 pub product: Option<String>,
119}
120
121#[derive(Debug, Clone, Deserialize)]
125pub struct DeterminingPolicy {
126 pub rule_id: String,
127 pub policy_id: String,
128 pub policy_name: String,
129 pub effect: String,
130 pub mode: String,
131 #[serde(default)]
132 pub annotations: HashMap<String, serde_json::Value>,
133}
134
135#[derive(Debug, Clone, Deserialize)]
137pub struct DetectorResult {
138 pub name: String,
139 pub tier: String,
140 pub latency_ms: Option<i64>,
141 #[serde(default)]
142 pub context: HashMap<String, serde_json::Value>,
143 pub status: String,
144 pub error: Option<String>,
145}
146
147#[derive(Debug, Clone, Deserialize)]
149pub struct SessionDelta {
150 pub turn_count: i32,
151 pub cumulative_risk: f64,
152 pub tokens_used_delta: Option<i64>,
153 pub new_action: Option<String>,
154}
155
156#[derive(Debug, Clone, Deserialize)]
158pub struct RootCause {
159 pub summary: String,
160 pub detector: String,
161 #[serde(default)]
162 pub labels: HashMap<String, serde_json::Value>,
163 #[serde(default)]
164 pub triggering_context: HashMap<String, serde_json::Value>,
165 #[serde(default)]
166 pub evidence: HashMap<String, serde_json::Value>,
167 #[serde(default)]
168 pub triggered_policies: Vec<String>,
169}
170
171#[derive(Debug, Clone, Deserialize)]
173pub struct ShieldResponse {
174 pub decision: String,
176 pub actual_decision: Option<String>,
178 pub mode_overridden: Option<bool>,
180 pub effective_mode: Option<String>,
182 pub alerted: Option<bool>,
184 pub reason: Option<String>,
186 pub audit_id: Option<String>,
188 pub request_id: Option<String>,
190 pub timestamp: String,
192 #[serde(default)]
194 pub determining_policies: Vec<DeterminingPolicy>,
195 #[serde(default)]
197 pub detectors: Vec<DetectorResult>,
198 #[serde(default)]
200 pub context: HashMap<String, serde_json::Value>,
201 #[serde(default)]
203 pub projected_context: HashMap<String, serde_json::Value>,
204 pub latency_ms: Option<i64>,
206 pub eval_latency_ms: Option<i64>,
208 #[serde(default)]
210 pub tiers_evaluated: Vec<String>,
211 #[serde(default)]
213 pub tiers_skipped: Vec<String>,
214 pub session_delta: Option<SessionDelta>,
216 #[serde(default)]
218 pub root_causes: Vec<RootCause>,
219}
220
221impl ShieldResponse {
222 pub fn allowed(&self) -> bool {
224 self.decision == "allow"
225 }
226
227 pub fn denied(&self) -> bool {
229 self.decision == "deny"
230 }
231}
232
233#[derive(Debug, Clone, Deserialize)]
237pub struct TokenResponse {
238 pub access_token: String,
239 pub token_type: String,
240 pub expires_in: u64,
241 #[serde(default)]
242 pub account_id: String,
243 #[serde(default)]
244 pub gateway_id: String,
245 #[serde(default)]
246 pub project_id: String,
247}
248
249#[derive(Debug, Clone, Deserialize)]
253pub struct HealthResponse {
254 pub status: String,
256 #[serde(default)]
258 pub detectors: HashMap<String, String>,
259 pub evaluator: Option<String>,
261}
262
263#[derive(Debug, Clone, Deserialize)]
265pub struct DetectorInfo {
266 pub name: String,
267 pub version: Option<String>,
268 pub tier: Option<String>,
269 pub status: Option<String>,
270}
271
272#[derive(Debug, Clone, Deserialize)]
274pub struct ListDetectorsResponse {
275 pub detectors: Vec<DetectorInfo>,
276 pub count: u32,
277}