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
128fn default_chunk_timeout() -> u64 {
129 5000 // 5 seconds
130}
131
132// ============================================================================
133// Agent Type
134// ============================================================================
135
136/// Agent type
137#[derive(Debug, Clone, Serialize, Deserialize)]
138#[serde(rename_all = "snake_case")]
139pub enum AgentType {
140 Waf,
141 Auth,
142 RateLimit,
143 Custom(String),
144}
145
146// ============================================================================
147// Agent Transport
148// ============================================================================
149
150/// Agent transport configuration
151#[derive(Debug, Clone, Serialize, Deserialize)]
152#[serde(rename_all = "snake_case")]
153pub enum AgentTransport {
154 /// Unix domain socket
155 UnixSocket { path: PathBuf },
156
157 /// gRPC over TCP
158 Grpc {
159 address: String,
160 tls: Option<AgentTlsConfig>,
161 },
162
163 /// HTTP REST API
164 Http {
165 url: String,
166 tls: Option<AgentTlsConfig>,
167 },
168}
169
170/// Agent TLS configuration
171#[derive(Debug, Clone, Serialize, Deserialize)]
172pub struct AgentTlsConfig {
173 /// Skip certificate verification
174 #[serde(default)]
175 pub insecure_skip_verify: bool,
176
177 /// CA certificate
178 pub ca_cert: Option<PathBuf>,
179
180 /// Client certificate for mTLS
181 pub client_cert: Option<PathBuf>,
182
183 /// Client key for mTLS
184 pub client_key: Option<PathBuf>,
185}
186
187// ============================================================================
188// Agent Events
189// ============================================================================
190
191/// Agent events
192#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
193#[serde(rename_all = "snake_case")]
194pub enum AgentEvent {
195 RequestHeaders,
196 RequestBody,
197 ResponseHeaders,
198 ResponseBody,
199 Log,
200 /// WebSocket frame inspection (after upgrade)
201 WebSocketFrame,
202}
203
204// ============================================================================
205// Default Value Functions
206// ============================================================================
207
208fn default_agent_timeout() -> u64 {
209 1000
210}