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}