1use serde::Serialize;
5
6#[derive(Debug, Clone, Serialize)]
7pub struct OwaspMapping {
8 pub owasp_id: &'static str,
9 pub owasp_title: &'static str,
10 pub risk_description: &'static str,
11 pub lean_ctx_mitigations: Vec<Mitigation>,
12 pub coverage: Coverage,
13}
14
15#[derive(Debug, Clone, Serialize)]
16pub struct Mitigation {
17 pub feature: &'static str,
18 pub module: &'static str,
19 pub description: &'static str,
20}
21
22#[derive(Debug, Clone, Copy, Serialize, PartialEq)]
23pub enum Coverage {
24 Full,
25 Partial,
26}
27
28pub fn alignment() -> Vec<OwaspMapping> {
29 vec![
30 OwaspMapping {
31 owasp_id: "OWASP-AGENT-01",
32 owasp_title: "Excessive Agency",
33 risk_description: "Agent performs actions beyond intended scope or without proper authorization",
34 lean_ctx_mitigations: vec![
35 Mitigation {
36 feature: "Capability System",
37 module: "core/capabilities.rs",
38 description: "Fine-grained capability declarations per tool (fs:read, fs:write, exec, net)",
39 },
40 Mitigation {
41 feature: "Role Guard",
42 module: "server/role_guard.rs",
43 description: "5 built-in roles with tool allowlists and shell policy",
44 },
45 Mitigation {
46 feature: "Shell Allowlist",
47 module: "core/shell_allowlist.rs",
48 description: "Opt-in command allowlist restricting which binaries agents can execute",
49 },
50 Mitigation {
51 feature: "Context Budget",
52 module: "core/agent_budget.rs",
53 description: "Per-agent token budgets preventing resource exhaustion",
54 },
55 ],
56 coverage: Coverage::Full,
57 },
58 OwaspMapping {
59 owasp_id: "OWASP-AGENT-02",
60 owasp_title: "Prompt Injection",
61 risk_description: "Malicious instructions injected via data processed by the agent",
62 lean_ctx_mitigations: vec![
63 Mitigation {
64 feature: "Context Compression",
65 module: "core/terse/",
66 description: "Deterministic compression reduces attack surface in injected content",
67 },
68 Mitigation {
69 feature: "Secret Detection",
70 module: "core/secret_detection.rs",
71 description: "Pre-read scanning detects and optionally redacts sensitive patterns",
72 },
73 Mitigation {
74 feature: "I/O Boundary",
75 module: "core/io_boundary.rs",
76 description: "Content filtering and secret-like path blocking before agent consumption",
77 },
78 ],
79 coverage: Coverage::Partial,
80 },
81 OwaspMapping {
82 owasp_id: "OWASP-AGENT-03",
83 owasp_title: "Sensitive Information Disclosure",
84 risk_description: "Agent exposes confidential data through outputs or tool interactions",
85 lean_ctx_mitigations: vec![
86 Mitigation {
87 feature: "PathJail",
88 module: "core/pathjail.rs",
89 description: "Filesystem jail prevents reads outside project root",
90 },
91 Mitigation {
92 feature: "I/O Boundary",
93 module: "core/io_boundary.rs",
94 description: "Secret-like path detection (.env, .ssh, credentials)",
95 },
96 Mitigation {
97 feature: "Secret Detection",
98 module: "core/secret_detection.rs",
99 description: "Regex-based detection of API keys, tokens, passwords in file content",
100 },
101 Mitigation {
102 feature: "Proxy Header Allowlist",
103 module: "proxy/forward.rs",
104 description: "Prevents leaking Set-Cookie and other sensitive headers",
105 },
106 Mitigation {
107 feature: "Memory Boundary",
108 module: "core/memory_boundary.rs",
109 description: "Cross-project access control with audit trail",
110 },
111 ],
112 coverage: Coverage::Full,
113 },
114 OwaspMapping {
115 owasp_id: "OWASP-AGENT-04",
116 owasp_title: "Denial of Service",
117 risk_description: "Agent overwhelms system resources or causes service disruption",
118 lean_ctx_mitigations: vec![
119 Mitigation {
120 feature: "Rate Limiter",
121 module: "core/a2a/rate_limiter.rs",
122 description: "Per-agent per-tool rate limiting",
123 },
124 Mitigation {
125 feature: "Memory Guard",
126 module: "core/config/memory.rs",
127 description: "RAM usage caps and idle cleanup",
128 },
129 Mitigation {
130 feature: "Budget Tracker",
131 module: "core/agent_budget.rs",
132 description: "Token budget enforcement with hard limits",
133 },
134 Mitigation {
135 feature: "Loop Detection",
136 module: "config loop_detection",
137 description: "Detects and throttles repetitive tool call patterns",
138 },
139 Mitigation {
140 feature: "Tool Timeout",
141 module: "engine/mod.rs",
142 description: "120s timeout on tool execution prevents indefinite hangs",
143 },
144 ],
145 coverage: Coverage::Full,
146 },
147 OwaspMapping {
148 owasp_id: "OWASP-AGENT-05",
149 owasp_title: "Supply Chain Vulnerabilities",
150 risk_description: "Compromised tools, plugins, or dependencies affect agent behavior",
151 lean_ctx_mitigations: vec![
152 Mitigation {
153 feature: "Signed Handoff Bundles",
154 module: "core/handoff_transfer_bundle.rs",
155 description: "Ed25519 signatures verify integrity and provenance of transferred data",
156 },
157 Mitigation {
158 feature: "Audit Trail",
159 module: "core/audit_trail.rs",
160 description: "SHA-256 chained append-only log of all tool calls and security events",
161 },
162 Mitigation {
163 feature: "Agent Identity",
164 module: "core/agent_identity.rs",
165 description: "Per-agent Ed25519 keypairs for cryptographic identity",
166 },
167 ],
168 coverage: Coverage::Partial,
169 },
170 OwaspMapping {
171 owasp_id: "OWASP-AGENT-06",
172 owasp_title: "Insufficient Logging and Monitoring",
173 risk_description: "Lack of visibility into agent actions and security events",
174 lean_ctx_mitigations: vec![
175 Mitigation {
176 feature: "Audit Trail",
177 module: "core/audit_trail.rs",
178 description: "Every tool call logged with agent ID, role, input hash, output tokens",
179 },
180 Mitigation {
181 feature: "Compliance Reports",
182 module: "cli/audit_report.rs",
183 description: "CLI command to generate aggregated compliance reports",
184 },
185 Mitigation {
186 feature: "Context OS Events",
187 module: "core/context_os.rs",
188 description: "Real-time event bus with SSE streaming for dashboard",
189 },
190 Mitigation {
191 feature: "Proxy Metrics",
192 module: "core/proxy_metrics.rs",
193 description: "Atomic counters for requests, tokens saved, bytes compressed",
194 },
195 ],
196 coverage: Coverage::Full,
197 },
198 OwaspMapping {
199 owasp_id: "OWASP-AGENT-07",
200 owasp_title: "Insecure Code Execution",
201 risk_description: "Agent executes arbitrary or unsafe code without proper sandboxing",
202 lean_ctx_mitigations: vec![
203 Mitigation {
204 feature: "Sandbox Level 0",
205 module: "core/sandbox.rs",
206 description: "Subprocess isolation with env_clear and timeout",
207 },
208 Mitigation {
209 feature: "Sandbox Level 1 (macOS)",
210 module: "core/sandbox_seatbelt.rs",
211 description: "OS-level Seatbelt profiles restricting filesystem and network",
212 },
213 Mitigation {
214 feature: "Sandbox Level 1 (Linux)",
215 module: "core/sandbox_landlock.rs",
216 description: "Landlock LSM restricting filesystem access",
217 },
218 Mitigation {
219 feature: "Command Blocklist",
220 module: "tools ctx_shell",
221 description: "Dangerous command patterns blocked before execution",
222 },
223 ],
224 coverage: Coverage::Full,
225 },
226 OwaspMapping {
227 owasp_id: "OWASP-AGENT-08",
228 owasp_title: "Broken Access Control",
229 risk_description: "Agent accesses resources or performs actions beyond its permissions",
230 lean_ctx_mitigations: vec![
231 Mitigation {
232 feature: "RBAC",
233 module: "core/roles.rs",
234 description: "5 built-in roles (viewer, coder, admin, ci, restricted) with granular policies",
235 },
236 Mitigation {
237 feature: "Capability System",
238 module: "core/capabilities.rs",
239 description: "Tool-level capability requirements checked against role grants",
240 },
241 Mitigation {
242 feature: "PathJail",
243 module: "core/pathjail.rs",
244 description: "All path arguments jailed to project root",
245 },
246 Mitigation {
247 feature: "Boundary Policy",
248 module: "core/memory_boundary.rs",
249 description: "Cross-project access control configurable per policy",
250 },
251 ],
252 coverage: Coverage::Full,
253 },
254 OwaspMapping {
255 owasp_id: "OWASP-AGENT-09",
256 owasp_title: "Improper Multi-Agent Orchestration",
257 risk_description: "Coordination failures between agents lead to conflicts or data corruption",
258 lean_ctx_mitigations: vec![
259 Mitigation {
260 feature: "Per-Agent Ledger",
261 module: "core/context_ledger.rs",
262 description: "Isolated context tracking per agent, preventing cross-contamination",
263 },
264 Mitigation {
265 feature: "Agent Registry",
266 module: "core/agents.rs",
267 description: "HTTP-backed registration with heartbeat and auto-deregistration",
268 },
269 Mitigation {
270 feature: "TaskStore File Locks",
271 module: "core/a2a/task.rs",
272 description: "Advisory file locks prevent lost updates from concurrent access",
273 },
274 Mitigation {
275 feature: "Atomic Writes",
276 module: "core/context_ledger.rs",
277 description: "Crash-safe temp+rename writes for all JSON stores",
278 },
279 ],
280 coverage: Coverage::Full,
281 },
282 OwaspMapping {
283 owasp_id: "OWASP-AGENT-10",
284 owasp_title: "Insufficient Governance",
285 risk_description: "Lack of organizational policies and controls over agent behavior",
286 lean_ctx_mitigations: vec![
287 Mitigation {
288 feature: "Policy Engine",
289 module: "core/context_policies.rs",
290 description: "Declarative policies with agent, content, and time-based conditions",
291 },
292 Mitigation {
293 feature: "Compliance Reports",
294 module: "cli/audit_report.rs",
295 description: "Aggregated reports: reads, compressions, denials, budget usage",
296 },
297 Mitigation {
298 feature: "Auto-Reroot Protection",
299 module: "tools/server_paths.rs",
300 description: "Opt-in control over project root changes, audited",
301 },
302 Mitigation {
303 feature: "Config-Driven",
304 module: "core/config/mod.rs",
305 description: "All security features configurable via config.toml",
306 },
307 ],
308 coverage: Coverage::Full,
309 },
310 ]
311}
312
313pub fn summary() -> String {
315 let mappings = alignment();
316 let mut out = String::from("OWASP Top 10 for Agentic Applications — lean-ctx Alignment\n");
317 out.push_str(&"=".repeat(60));
318 out.push('\n');
319 for m in &mappings {
320 let icon = match m.coverage {
321 Coverage::Full => "●",
322 Coverage::Partial => "◐",
323 };
324 out.push_str(&format!(
325 "\n{icon} {} — {}\n Mitigations: {}\n",
326 m.owasp_id,
327 m.owasp_title,
328 m.lean_ctx_mitigations
329 .iter()
330 .map(|m| m.feature)
331 .collect::<Vec<_>>()
332 .join(", ")
333 ));
334 }
335 let full = mappings
336 .iter()
337 .filter(|m| m.coverage == Coverage::Full)
338 .count();
339 let partial = mappings
340 .iter()
341 .filter(|m| m.coverage == Coverage::Partial)
342 .count();
343 out.push_str(&format!(
344 "\nCoverage: {full}/10 Full, {partial}/10 Partial\n"
345 ));
346 out
347}
348
349#[cfg(test)]
350mod tests {
351 use super::*;
352
353 #[test]
354 fn alignment_covers_all_ten() {
355 let a = alignment();
356 assert_eq!(a.len(), 10);
357 for (i, m) in a.iter().enumerate() {
358 assert_eq!(m.owasp_id, format!("OWASP-AGENT-{:02}", i + 1));
359 assert!(!m.lean_ctx_mitigations.is_empty());
360 }
361 }
362
363 #[test]
364 fn summary_contains_all_ids() {
365 let s = summary();
366 for i in 1..=10 {
367 assert!(s.contains(&format!("OWASP-AGENT-{i:02}")));
368 }
369 }
370}