sentinel_config/agents.rs
1//! Agent configuration types
2//!
3//! This module contains configuration types for external processing agents
4//! (WAF, auth, rate limiting, custom logic).
5
6use serde::{Deserialize, Serialize};
7use std::path::PathBuf;
8use validator::Validate;
9
10use sentinel_common::types::CircuitBreakerConfig;
11
12use crate::routes::FailureMode;
13
14// ============================================================================
15// Body Streaming Mode
16// ============================================================================
17
18/// Body streaming mode for agent processing
19///
20/// Controls how request/response bodies are sent to agents:
21/// - `Buffer`: Collect entire body before sending (default, backwards compatible)
22/// - `Stream`: Send chunks as they arrive (lower latency, lower memory)
23/// - `Hybrid`: Buffer small bodies, stream large ones
24#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
25#[serde(rename_all = "snake_case")]
26#[derive(Default)]
27pub enum BodyStreamingMode {
28 /// Buffer entire body before sending to agent (default)
29 ///
30 /// - Simpler agent implementation
31 /// - Higher memory usage for large bodies
32 /// - Agent sees complete body for decisions
33 #[default]
34 Buffer,
35
36 /// Stream body chunks as they arrive
37 ///
38 /// - Lower latency and memory usage
39 /// - Agent must handle partial data
40 /// - Supports progressive decisions
41 Stream,
42
43 /// Hybrid: buffer up to threshold, then stream
44 ///
45 /// - Best of both worlds for mixed workloads
46 /// - Small bodies buffered for simplicity
47 /// - Large bodies streamed for efficiency
48 Hybrid {
49 /// Buffer threshold in bytes (default: 64KB)
50 #[serde(default = "default_hybrid_threshold")]
51 buffer_threshold: usize,
52 },
53}
54
55fn default_hybrid_threshold() -> usize {
56 64 * 1024 // 64KB
57}
58
59// ============================================================================
60// Agent Configuration
61// ============================================================================
62
63/// Agent configuration
64#[derive(Debug, Clone, Serialize, Deserialize, Validate)]
65pub struct AgentConfig {
66 /// Unique agent identifier
67 pub id: String,
68
69 /// Agent type
70 #[serde(rename = "type")]
71 pub agent_type: AgentType,
72
73 /// Transport configuration
74 pub transport: AgentTransport,
75
76 /// Events this agent handles
77 pub events: Vec<AgentEvent>,
78
79 /// Timeout for agent calls
80 #[serde(default = "default_agent_timeout")]
81 pub timeout_ms: u64,
82
83 /// Failure mode when agent is unavailable
84 #[serde(default)]
85 pub failure_mode: FailureMode,
86
87 /// Circuit breaker configuration
88 #[serde(default)]
89 pub circuit_breaker: Option<CircuitBreakerConfig>,
90
91 /// Maximum request body to send
92 pub max_request_body_bytes: Option<usize>,
93
94 /// Maximum response body to send
95 pub max_response_body_bytes: Option<usize>,
96
97 /// Request body streaming mode
98 ///
99 /// Controls how request bodies are sent to this agent:
100 /// - `buffer`: Collect entire body before sending (default)
101 /// - `stream`: Send chunks as they arrive
102 /// - `hybrid`: Buffer small bodies, stream large ones
103 #[serde(default)]
104 pub request_body_mode: BodyStreamingMode,
105
106 /// Response body streaming mode
107 ///
108 /// Controls how response bodies are sent to this agent.
109 /// Same options as request_body_mode.
110 #[serde(default)]
111 pub response_body_mode: BodyStreamingMode,
112
113 /// Timeout per body chunk when streaming (milliseconds)
114 ///
115 /// Only applies when using `stream` or `hybrid` mode.
116 /// Default: 5000ms (5 seconds)
117 #[serde(default = "default_chunk_timeout")]
118 pub chunk_timeout_ms: u64,
119
120 /// Agent-specific configuration
121 ///
122 /// This configuration is passed to the agent via the Configure event
123 /// when the agent connects. The structure depends on the agent type.
124 #[serde(default, skip_serializing_if = "Option::is_none")]
125 pub config: Option<serde_json::Value>,
126
127 /// Maximum concurrent calls to this agent
128 ///
129 /// Limits the number of simultaneous requests that can be processed by this agent.
130 /// This provides per-agent queue isolation to prevent a slow agent from affecting
131 /// other agents (noisy neighbor problem).
132 ///
133 /// Default: 100 concurrent calls per agent
134 #[serde(default = "default_max_concurrent_calls")]
135 pub max_concurrent_calls: usize,
136}
137
138fn default_chunk_timeout() -> u64 {
139 5000 // 5 seconds
140}
141
142fn default_max_concurrent_calls() -> usize {
143 100 // Per-agent concurrency limit
144}
145
146// ============================================================================
147// Agent Type
148// ============================================================================
149
150/// Agent type
151#[derive(Debug, Clone, Serialize, Deserialize)]
152#[serde(rename_all = "snake_case")]
153pub enum AgentType {
154 Waf,
155 Auth,
156 RateLimit,
157 Custom(String),
158}
159
160// ============================================================================
161// Agent Transport
162// ============================================================================
163
164/// Agent transport configuration
165#[derive(Debug, Clone, Serialize, Deserialize)]
166#[serde(rename_all = "snake_case")]
167pub enum AgentTransport {
168 /// Unix domain socket
169 UnixSocket { path: PathBuf },
170
171 /// gRPC over TCP
172 Grpc {
173 address: String,
174 tls: Option<AgentTlsConfig>,
175 },
176
177 /// HTTP REST API
178 Http {
179 url: String,
180 tls: Option<AgentTlsConfig>,
181 },
182}
183
184/// Agent TLS configuration
185#[derive(Debug, Clone, Serialize, Deserialize)]
186pub struct AgentTlsConfig {
187 /// Skip certificate verification
188 #[serde(default)]
189 pub insecure_skip_verify: bool,
190
191 /// CA certificate
192 pub ca_cert: Option<PathBuf>,
193
194 /// Client certificate for mTLS
195 pub client_cert: Option<PathBuf>,
196
197 /// Client key for mTLS
198 pub client_key: Option<PathBuf>,
199}
200
201// ============================================================================
202// Agent Events
203// ============================================================================
204
205/// Agent events
206#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
207#[serde(rename_all = "snake_case")]
208pub enum AgentEvent {
209 RequestHeaders,
210 RequestBody,
211 ResponseHeaders,
212 ResponseBody,
213 Log,
214 /// WebSocket frame inspection (after upgrade)
215 WebSocketFrame,
216}
217
218// ============================================================================
219// Default Value Functions
220// ============================================================================
221
222fn default_agent_timeout() -> u64 {
223 1000
224}