flintai-cli 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. flintai/__init__.py +0 -0
  2. flintai/cli/__init__.py +0 -0
  3. flintai/cli/__main__.py +3 -0
  4. flintai/cli/builtin_config.json +911 -0
  5. flintai/cli/console.py +116 -0
  6. flintai/cli/eval_cli.py +891 -0
  7. flintai/cli/init_cli.py +144 -0
  8. flintai/cli/main.py +262 -0
  9. flintai/cli/rich_observer.py +89 -0
  10. flintai/cli/runner.py +305 -0
  11. flintai/cli/scan_cli.py +238 -0
  12. flintai/cli/utils.py +37 -0
  13. flintai/cli/version.py +1 -0
  14. flintai/data/detector_prompts/llm01_adversarial.txt +55 -0
  15. flintai/data/detector_prompts/llm01_fixed.txt +8 -0
  16. flintai/data/detector_prompts/llm02_adversarial.txt +75 -0
  17. flintai/data/detector_prompts/llm02_fixed.txt +8 -0
  18. flintai/data/detector_prompts/llm05_adversarial.txt +63 -0
  19. flintai/data/detector_prompts/llm05_fixed.txt +16 -0
  20. flintai/data/detector_prompts/llm06_adversarial.txt +135 -0
  21. flintai/data/detector_prompts/llm06_fixed.txt +15 -0
  22. flintai/data/detector_prompts/llm07_adversarial.txt +185 -0
  23. flintai/data/detector_prompts/llm07_fixed.txt +14 -0
  24. flintai/data/detector_prompts/llm09_adversarial.txt +77 -0
  25. flintai/data/detector_prompts/llm09_fixed.txt +15 -0
  26. flintai/data/llm01_prompt_injection.csv +6708 -0
  27. flintai/data/llm02_sensitive_information.csv +1069 -0
  28. flintai/data/llm05_unsafe_output.csv +3882 -0
  29. flintai/data/llm06_excessive_agency.csv +778 -0
  30. flintai/data/llm07_system_prompt_leakage.csv +971 -0
  31. flintai/data/llm09_hallucination-goals.csv +32419 -0
  32. flintai/data/llm09_hallucination.csv +599 -0
  33. flintai/data/pii_leakage.csv +706 -0
  34. flintai/data/secret_leakage.csv +1380 -0
  35. flintai/eval/__init__.py +0 -0
  36. flintai/eval/common/converter_anthropic.py +151 -0
  37. flintai/eval/common/converter_genai.py +169 -0
  38. flintai/eval/common/converter_openai.py +165 -0
  39. flintai/eval/common/log.py +96 -0
  40. flintai/eval/common/reference.py +25 -0
  41. flintai/eval/common/schema.py +192 -0
  42. flintai/eval/common/utils.py +74 -0
  43. flintai/eval/core/__init__.py +0 -0
  44. flintai/eval/core/detectors/__init__.py +1 -0
  45. flintai/eval/core/detectors/detector.py +25 -0
  46. flintai/eval/core/detectors/detector_garak.py +80 -0
  47. flintai/eval/core/detectors/detector_model.py +76 -0
  48. flintai/eval/core/detectors/detector_pii.py +64 -0
  49. flintai/eval/core/detectors/detector_secret.py +82 -0
  50. flintai/eval/core/detectors/detector_topic_guard.py +70 -0
  51. flintai/eval/core/detectors/detector_toxicity.py +70 -0
  52. flintai/eval/core/eval/__init__.py +0 -0
  53. flintai/eval/core/eval/eval_creator.py +197 -0
  54. flintai/eval/core/eval/evaluation.py +100 -0
  55. flintai/eval/core/eval/evaluation_adversarial.py +523 -0
  56. flintai/eval/core/eval/evaluation_garak_module.py +52 -0
  57. flintai/eval/core/eval/evaluation_garak_probe.py +274 -0
  58. flintai/eval/core/eval/evaluation_message_list.py +44 -0
  59. flintai/eval/core/eval/evaluation_multi.py +207 -0
  60. flintai/eval/core/eval/evaluation_single.py +79 -0
  61. flintai/eval/core/eval/evaluation_single_prompt.py +58 -0
  62. flintai/eval/core/eval/evaluation_topic_guard.py +318 -0
  63. flintai/eval/core/eval/metric_conciseness.py +181 -0
  64. flintai/eval/core/eval/metric_factual_accuracy.py +294 -0
  65. flintai/eval/core/eval/metric_instruction_adherence.py +180 -0
  66. flintai/eval/core/eval/metric_tone.py +183 -0
  67. flintai/eval/core/eval/metric_toxicity.py +147 -0
  68. flintai/eval/core/eval/observer.py +136 -0
  69. flintai/eval/core/eval/probe_adversarial.py +14 -0
  70. flintai/eval/core/message/__init__.py +0 -0
  71. flintai/eval/core/message/message_collection.py +37 -0
  72. flintai/eval/core/message/message_collection_csv.py +46 -0
  73. flintai/eval/core/message/message_collection_garak.py +52 -0
  74. flintai/eval/core/message/message_collection_memory.py +36 -0
  75. flintai/eval/core/models/__init__.py +0 -0
  76. flintai/eval/core/models/generator_model.py +88 -0
  77. flintai/eval/core/models/model.py +111 -0
  78. flintai/eval/core/models/model_adk.py +158 -0
  79. flintai/eval/core/models/model_anthropic.py +51 -0
  80. flintai/eval/core/models/model_anthropic_agent.py +92 -0
  81. flintai/eval/core/models/model_gemini.py +107 -0
  82. flintai/eval/core/models/model_generic_http.py +117 -0
  83. flintai/eval/core/models/model_huggingface.py +61 -0
  84. flintai/eval/core/models/model_langserve.py +94 -0
  85. flintai/eval/core/models/model_litellm.py +38 -0
  86. flintai/eval/core/models/model_ollama.py +50 -0
  87. flintai/eval/core/models/model_openai.py +35 -0
  88. flintai/eval/core/models/model_openai_agent.py +80 -0
  89. flintai/eval/core/models/model_openai_compatible.py +57 -0
  90. flintai/eval/core/models/model_retry.py +134 -0
  91. flintai/eval/core/models/model_sync_wrapper.py +35 -0
  92. flintai/eval/db/__init__.py +0 -0
  93. flintai/eval/db/base/__init__.py +0 -0
  94. flintai/eval/db/base/detectors/__init__.py +1 -0
  95. flintai/eval/db/base/detectors/detector_helpers.py +78 -0
  96. flintai/eval/db/base/detectors/detector_repository.py +91 -0
  97. flintai/eval/db/base/detectors/detector_types.py +77 -0
  98. flintai/eval/db/base/eval/__init__.py +1 -0
  99. flintai/eval/db/base/eval/eval_helpers.py +227 -0
  100. flintai/eval/db/base/eval/eval_repository.py +115 -0
  101. flintai/eval/db/base/eval/eval_run.py +139 -0
  102. flintai/eval/db/base/eval/eval_types.py +129 -0
  103. flintai/eval/db/base/eval/model_eval_repository.py +78 -0
  104. flintai/eval/db/base/eval/model_eval_run_repository.py +70 -0
  105. flintai/eval/db/base/eval/model_eval_run_result_repository.py +40 -0
  106. flintai/eval/db/base/eval/model_eval_run_result_types.py +21 -0
  107. flintai/eval/db/base/eval/model_eval_run_types.py +84 -0
  108. flintai/eval/db/base/eval/model_eval_types.py +71 -0
  109. flintai/eval/db/base/message/__init__.py +0 -0
  110. flintai/eval/db/base/message/message_collection_helpers.py +61 -0
  111. flintai/eval/db/base/message/message_collection_repository.py +92 -0
  112. flintai/eval/db/base/message/message_collection_types.py +89 -0
  113. flintai/eval/db/base/models/__init__.py +0 -0
  114. flintai/eval/db/base/models/model_helpers.py +172 -0
  115. flintai/eval/db/base/models/model_repository.py +95 -0
  116. flintai/eval/db/base/models/model_types.py +156 -0
  117. flintai/eval/db/json/__init__.py +0 -0
  118. flintai/eval/db/json/repository_json.py +603 -0
  119. flintai/scan/__init__.py +0 -0
  120. flintai/scan/agent_scanner.py +797 -0
  121. flintai/scan/config/agent_opengrep_rules.yaml +533 -0
  122. flintai/scan/config/agent_taxonomy.json +481 -0
  123. flintai/scan/config/agentic_cvss_mapping.yaml +136 -0
  124. flintai/scan/config/compliance_mappings.json +110 -0
  125. flintai/scan/config/triage_prompt.txt +335 -0
  126. flintai/scan/constants.py +15 -0
  127. flintai/scan/file_filter.py +156 -0
  128. flintai/scan/llm_provider.py +197 -0
  129. flintai/scan/opengrep_resolver.py +12 -0
  130. flintai/scan/reasoner.py +552 -0
  131. flintai/scan/schema.py +337 -0
  132. flintai/scan/scorer.py +371 -0
  133. flintai/scan/secret_anonymizer.py +72 -0
  134. flintai/scan/static_scanner.py +542 -0
  135. flintai/scan/taxonomy.py +75 -0
  136. flintai/scan/tool_dispatcher.py +754 -0
  137. flintai/scan/trace_logger.py +118 -0
  138. flintai/scan/trace_logger_file.py +143 -0
  139. flintai/scan/trace_logger_log.py +100 -0
  140. flintai/scan/triage.py +496 -0
  141. flintai/schema.py +58 -0
  142. flintai_cli-1.0.0.dist-info/METADATA +442 -0
  143. flintai_cli-1.0.0.dist-info/RECORD +147 -0
  144. flintai_cli-1.0.0.dist-info/WHEEL +5 -0
  145. flintai_cli-1.0.0.dist-info/entry_points.txt +2 -0
  146. flintai_cli-1.0.0.dist-info/licenses/LICENSE +210 -0
  147. flintai_cli-1.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,533 @@
1
+ rules:
2
+
3
+ # ═══════════════════════════════════════════════════════════════════════════
4
+ # ASI01: Agent Goal Hijack
5
+ # ═══════════════════════════════════════════════════════════════════════════
6
+
7
+ - id: llm-input-fstring
8
+ pattern-either:
9
+ - pattern: |
10
+ $X = f"...$USER_INPUT..."
11
+ ...
12
+ $AGENT.run($X)
13
+ - pattern: |
14
+ $X = f"...$USER_INPUT..."
15
+ ...
16
+ $CHAIN.invoke($X)
17
+ message: "User input interpolated into LLM prompt via f-string — direct prompt injection risk"
18
+ severity: ERROR
19
+ languages: [python]
20
+ metadata:
21
+ category: asi01_agent_goal_hijack
22
+ subcategory: direct_prompt_injection
23
+
24
+ - id: openai-agent-no-input-guardrails
25
+ patterns:
26
+ - pattern: Agent(name=$N, instructions=$I, ...)
27
+ - pattern-not: Agent(..., input_guardrails=$G, ...)
28
+ message: "OpenAI Agent without input_guardrails — no prompt injection protection"
29
+ severity: WARNING
30
+ languages: [python]
31
+ metadata:
32
+ category: asi01_agent_goal_hijack
33
+ subcategory: direct_prompt_injection
34
+
35
+ - id: adk-agent-no-instruction
36
+ patterns:
37
+ - pattern: Agent(name=$N, model=$M, ...)
38
+ - pattern-not: Agent(..., instruction=$I, ...)
39
+ message: "ADK Agent without instruction parameter — agent behavior is unconstrained"
40
+ severity: WARNING
41
+ languages: [python]
42
+ metadata:
43
+ category: asi01_agent_goal_hijack
44
+ subcategory: goal_manipulation_via_rag
45
+
46
+ - id: claude-options-no-system-prompt
47
+ patterns:
48
+ - pattern: ClaudeAgentOptions(...)
49
+ - pattern-not: ClaudeAgentOptions(..., system_prompt=$S, ...)
50
+ message: "ClaudeAgentOptions without system_prompt — agent behavior is unconstrained"
51
+ severity: WARNING
52
+ languages: [python]
53
+ metadata:
54
+ category: asi01_agent_goal_hijack
55
+ subcategory: goal_manipulation_via_rag
56
+
57
+ - id: claude-subagent-no-prompt
58
+ patterns:
59
+ - pattern: AgentDefinition(...)
60
+ - pattern-not: AgentDefinition(..., prompt=$P, ...)
61
+ message: "Claude AgentDefinition without prompt — sub-agent behavior is unconstrained"
62
+ severity: WARNING
63
+ languages: [python]
64
+ metadata:
65
+ category: asi01_agent_goal_hijack
66
+ subcategory: goal_manipulation_via_rag
67
+
68
+ # ═══════════════════════════════════════════════════════════════════════════
69
+ # ASI02: Tool Misuse and Exploitation
70
+ # ═══════════════════════════════════════════════════════════════════════════
71
+
72
+ - id: anthropic-tool-choice-any
73
+ patterns:
74
+ - pattern: |
75
+ $CLIENT.messages.create(..., tool_choice={"type": "any"}, ...)
76
+ message: "Anthropic tool_choice set to 'any' — forces tool use on every turn, may bypass safety checks"
77
+ severity: WARNING
78
+ languages: [python]
79
+ metadata:
80
+ category: asi02_tool_misuse
81
+ subcategory: excessive_tool_permissions
82
+
83
+ # ═══════════════════════════════════════════════════════════════════════════
84
+ # ASI03: Identity and Privilege Abuse
85
+ # ═══════════════════════════════════════════════════════════════════════════
86
+
87
+ - id: hardcoded-api-key
88
+ patterns:
89
+ - pattern: $VAR = "$KEY"
90
+ - metavariable-regex:
91
+ metavariable: $VAR
92
+ regex: ".*(api_key|API_KEY|secret|token|password|passwd|pwd).*"
93
+ - metavariable-regex:
94
+ metavariable: $KEY
95
+ regex: '^[A-Za-z0-9_-]{20,}$'
96
+ message: "Potential hardcoded API key or secret"
97
+ severity: ERROR
98
+ languages: [python]
99
+ metadata:
100
+ category: asi03_identity_privilege_abuse
101
+ subcategory: hardcoded_credentials
102
+
103
+ - id: no-tls-server
104
+ pattern-either:
105
+ - pattern: app.run(debug=True)
106
+ - pattern: uvicorn.run($APP, host="0.0.0.0", ...)
107
+ message: "Agent server running without explicit TLS — exposed HTTP endpoint risk"
108
+ severity: WARNING
109
+ languages: [python]
110
+ metadata:
111
+ category: asi03_identity_privilege_abuse
112
+ subcategory: missing_auth_on_endpoint
113
+
114
+ - id: server-binding-all-interfaces
115
+ pattern-either:
116
+ - pattern: mcp.run(transport="http", host="0.0.0.0", ...)
117
+ - pattern: uvicorn.run($APP, host="0.0.0.0", ...)
118
+ - pattern: app.run(host="0.0.0.0", ...)
119
+ message: "Server binding to 0.0.0.0 — exposed on all network interfaces, no access restriction"
120
+ severity: ERROR
121
+ languages: [python]
122
+ metadata:
123
+ category: asi03_identity_privilege_abuse
124
+ subcategory: missing_auth_on_endpoint
125
+
126
+ # ═══════════════════════════════════════════════════════════════════════════
127
+ # ASI04: Agentic Supply Chain Vulnerabilities
128
+ # ═══════════════════════════════════════════════════════════════════════════
129
+
130
+ - id: unpinned-requirements
131
+ pattern-regex: '^(crewai|autogen|langchain|openai|anthropic)\s*(>=|~=|\^|[^=!<>])'
132
+ message: "Unpinned AI framework dependency — supply chain attack risk"
133
+ severity: WARNING
134
+ languages: [generic]
135
+ metadata:
136
+ category: asi04_supply_chain
137
+ subcategory: unpinned_dependencies
138
+
139
+ # ═══════════════════════════════════════════════════════════════════════════
140
+ # ASI05: Unexpected Code Execution
141
+ # ═══════════════════════════════════════════════════════════════════════════
142
+
143
+ - id: subprocess-shell-true
144
+ pattern-either:
145
+ - pattern: subprocess.call(..., shell=True, ...)
146
+ - pattern: subprocess.run(..., shell=True, ...)
147
+ - pattern: subprocess.Popen(..., shell=True, ...)
148
+ message: "subprocess called with shell=True — command injection risk if input is LLM-controlled"
149
+ severity: ERROR
150
+ languages: [python]
151
+ metadata:
152
+ category: asi05_unexpected_code_execution
153
+ subcategory: arbitrary_code_execution
154
+
155
+ - id: os-system-call
156
+ patterns:
157
+ - pattern: os.system($X)
158
+ message: "os.system() call — high command injection risk in agent tool context"
159
+ severity: ERROR
160
+ languages: [python]
161
+ metadata:
162
+ category: asi05_unexpected_code_execution
163
+ subcategory: arbitrary_code_execution
164
+
165
+ - id: eval-call
166
+ patterns:
167
+ - pattern: eval($X)
168
+ message: "eval() call — arbitrary code execution if input originates from LLM or user"
169
+ severity: ERROR
170
+ languages: [python]
171
+ metadata:
172
+ category: asi05_unexpected_code_execution
173
+ subcategory: arbitrary_code_execution
174
+
175
+ - id: autogen-code-execution-enabled
176
+ patterns:
177
+ - pattern: UserProxyAgent(..., code_execution_config={...}, ...)
178
+ message: "AutoGen agent has code execution enabled — arbitrary code execution risk if agent is compromised"
179
+ severity: ERROR
180
+ languages: [python]
181
+ metadata:
182
+ category: asi05_unexpected_code_execution
183
+ subcategory: arbitrary_code_execution
184
+
185
+ - id: adk-agent-code-executor
186
+ patterns:
187
+ - pattern: Agent(..., code_executor=$X, ...)
188
+ message: "ADK Agent with code_executor enabled — arbitrary code execution risk if agent is compromised"
189
+ severity: ERROR
190
+ languages: [python]
191
+ metadata:
192
+ category: asi05_unexpected_code_execution
193
+ subcategory: arbitrary_code_execution
194
+
195
+ - id: claude-options-bash-tool
196
+ patterns:
197
+ - pattern: ClaudeAgentOptions(..., allowed_tools=[..., "Bash", ...], ...)
198
+ message: "Claude Agent SDK with Bash tool allowed — arbitrary command execution risk"
199
+ severity: WARNING
200
+ languages: [python]
201
+ metadata:
202
+ category: asi05_unexpected_code_execution
203
+ subcategory: arbitrary_code_execution
204
+
205
+ - id: claude-subagent-bash-tool
206
+ patterns:
207
+ - pattern: AgentDefinition(..., tools=[..., "Bash", ...], ...)
208
+ message: "Claude sub-agent with Bash tool — delegated arbitrary command execution"
209
+ severity: WARNING
210
+ languages: [python]
211
+ metadata:
212
+ category: asi05_unexpected_code_execution
213
+ subcategory: arbitrary_code_execution
214
+
215
+ - id: unsafe-yaml-load
216
+ pattern-either:
217
+ - pattern: yaml.load($DATA)
218
+ - pattern: yaml.load($DATA, Loader=yaml.Loader)
219
+ message: "yaml.load() without SafeLoader — arbitrary code execution via deserialization"
220
+ severity: ERROR
221
+ languages: [python]
222
+ metadata:
223
+ category: asi05_unexpected_code_execution
224
+ subcategory: unsafe_deserialization
225
+
226
+ - id: pickle-load
227
+ pattern-either:
228
+ - pattern: pickle.loads($DATA)
229
+ - pattern: pickle.load($FILE)
230
+ message: "pickle.loads/load() — unsafe deserialization, enables arbitrary code execution on attacker-controlled data"
231
+ severity: ERROR
232
+ languages: [python]
233
+ metadata:
234
+ category: asi05_unexpected_code_execution
235
+ subcategory: unsafe_deserialization
236
+
237
+ # ═══════════════════════════════════════════════════════════════════════════
238
+ # ASI06: Memory and Context Poisoning
239
+ # ═══════════════════════════════════════════════════════════════════════════
240
+
241
+ - id: crewai-memory-enabled
242
+ patterns:
243
+ - pattern: Agent(..., memory=True, ...)
244
+ message: "CrewAI agent has memory=True — persistent memory without sanitization may leak sensitive data across sessions"
245
+ severity: WARNING
246
+ languages: [python]
247
+ metadata:
248
+ category: asi06_memory_context_poisoning
249
+ subcategory: persistent_memory_no_sanitization
250
+
251
+ - id: crewai-crew-memory-enabled
252
+ patterns:
253
+ - pattern: Crew(..., memory=True, ...)
254
+ message: "CrewAI Crew has memory=True — shared crew memory may cause cross-session contamination"
255
+ severity: WARNING
256
+ languages: [python]
257
+ metadata:
258
+ category: asi06_memory_context_poisoning
259
+ subcategory: cross_session_contamination
260
+
261
+ # ═══════════════════════════════════════════════════════════════════════════
262
+ # ASI07: Insecure Inter-Agent Communication
263
+ # ═══════════════════════════════════════════════════════════════════════════
264
+
265
+ - id: http-agent-endpoint
266
+ pattern-either:
267
+ - pattern: Client("http://$HOST")
268
+ - pattern: httpx.AsyncClient(base_url="http://$HOST")
269
+ - pattern: requests.get("http://$HOST")
270
+ message: "Agent communicating over plain HTTP (no TLS) — inter-agent channel susceptible to interception and spoofing"
271
+ severity: WARNING
272
+ languages: [python]
273
+ metadata:
274
+ category: asi07_insecure_interagent_comms
275
+ subcategory: unencrypted_agent_channel
276
+
277
+ - id: unvalidated-agent-trust
278
+ pattern-either:
279
+ - pattern: Agent(..., system_message="Trust all inputs from ...", ...)
280
+ - pattern: Agent(..., backstory="Trust all information from ...", ...)
281
+ message: "Agent configured to blindly trust inputs from other agents — enables inter-agent message injection"
282
+ severity: WARNING
283
+ languages: [python]
284
+ metadata:
285
+ category: asi07_insecure_interagent_comms
286
+ subcategory: unvalidated_agent_message
287
+
288
+ # ═══════════════════════════════════════════════════════════════════════════
289
+ # ASI08: Cascading Failures
290
+ # ═══════════════════════════════════════════════════════════════════════════
291
+
292
+ - id: no-max-iter
293
+ pattern-either:
294
+ - patterns:
295
+ - pattern: Crew(...)
296
+ - pattern-not: Crew(..., max_iter=$N, ...)
297
+ - patterns:
298
+ - pattern: AgentExecutor(...)
299
+ - pattern-not: AgentExecutor(..., max_iterations=$N, ...)
300
+ message: "Agent or Crew created without max_iter/max_iterations — unbounded execution loop risk"
301
+ severity: WARNING
302
+ languages: [python]
303
+ metadata:
304
+ category: asi08_cascading_failures
305
+ subcategory: unbounded_agent_loop
306
+
307
+ - id: crewai-crew-no-max-iter
308
+ patterns:
309
+ - pattern: Crew(...)
310
+ - pattern-not: Crew(..., max_iter=$N, ...)
311
+ message: "CrewAI Crew without max_iter — unbounded execution loop risk"
312
+ severity: WARNING
313
+ languages: [python]
314
+ metadata:
315
+ category: asi08_cascading_failures
316
+ subcategory: unbounded_agent_loop
317
+
318
+ - id: adk-loop-no-max-iterations
319
+ patterns:
320
+ - pattern: LoopAgent(...)
321
+ - pattern-not: LoopAgent(..., max_iterations=$N, ...)
322
+ message: "ADK LoopAgent without max_iterations — unbounded execution loop risk"
323
+ severity: WARNING
324
+ languages: [python]
325
+ metadata:
326
+ category: asi08_cascading_failures
327
+ subcategory: unbounded_agent_loop
328
+
329
+ - id: openai-runner-no-max-turns
330
+ patterns:
331
+ - pattern: Runner.run(...)
332
+ - pattern-not: Runner.run(..., max_turns=$N, ...)
333
+ message: "OpenAI Runner.run() without explicit max_turns — default may allow excessive iterations"
334
+ severity: WARNING
335
+ languages: [python]
336
+ metadata:
337
+ category: asi08_cascading_failures
338
+ subcategory: unbounded_agent_loop
339
+
340
+ - id: anthropic-tool-loop-no-limit
341
+ pattern: |
342
+ while $RESP.stop_reason == "tool_use":
343
+ ...
344
+ message: "Anthropic tool-calling loop without iteration limit — infinite loop risk"
345
+ severity: ERROR
346
+ languages: [python]
347
+ metadata:
348
+ category: asi08_cascading_failures
349
+ subcategory: unbounded_agent_loop
350
+
351
+ - id: anthropic-no-max-tokens
352
+ patterns:
353
+ - pattern: $CLIENT.messages.create(...)
354
+ - pattern-not: $CLIENT.messages.create(..., max_tokens=$N, ...)
355
+ message: "Anthropic messages.create() without max_tokens — unbounded token spend"
356
+ severity: WARNING
357
+ languages: [python]
358
+ metadata:
359
+ category: asi08_cascading_failures
360
+ subcategory: unbounded_agent_loop
361
+
362
+ - id: langchain-agent-no-max-iterations
363
+ patterns:
364
+ - pattern: AgentExecutor(...)
365
+ - pattern-not: AgentExecutor(..., max_iterations=$N, ...)
366
+ message: "LangChain AgentExecutor without max_iterations — unbounded agent loop risk"
367
+ severity: WARNING
368
+ languages: [python]
369
+ metadata:
370
+ category: asi08_cascading_failures
371
+ subcategory: unbounded_agent_loop
372
+
373
+ - id: langgraph-no-recursion-limit
374
+ pattern-either:
375
+ - pattern: $GRAPH.invoke($INPUT)
376
+ - pattern: $GRAPH.invoke($INPUT, config=$CFG)
377
+ message: "LangGraph invoke() without explicit recursion_limit in config — default 25 may allow excessive loops"
378
+ severity: INFO
379
+ languages: [python]
380
+ metadata:
381
+ category: asi08_cascading_failures
382
+ subcategory: unbounded_agent_loop
383
+
384
+ - id: claude-query-no-max-turns
385
+ patterns:
386
+ - pattern: query(..., options=$O, ...)
387
+ - pattern-not: query(..., options=ClaudeAgentOptions(..., max_turns=$N, ...), ...)
388
+ message: "Claude Agent SDK query() without max_turns — unbounded reasoning loop risk"
389
+ severity: WARNING
390
+ languages: [python]
391
+ metadata:
392
+ category: asi08_cascading_failures
393
+ subcategory: unbounded_agent_loop
394
+
395
+ - id: claude-client-no-max-turns
396
+ patterns:
397
+ - pattern: ClaudeSDKClient(options=$O, ...)
398
+ - pattern-not: ClaudeSDKClient(options=ClaudeAgentOptions(..., max_turns=$N, ...), ...)
399
+ message: "Claude Agent SDK client without max_turns — unbounded reasoning loop risk"
400
+ severity: WARNING
401
+ languages: [python]
402
+ metadata:
403
+ category: asi08_cascading_failures
404
+ subcategory: unbounded_agent_loop
405
+
406
+ - id: autogen-groupchat-no-max-round
407
+ patterns:
408
+ - pattern: GroupChat(...)
409
+ - pattern-not: GroupChat(..., max_round=$N, ...)
410
+ message: "AutoGen GroupChat without max_round — unbounded conversation loop risk"
411
+ severity: WARNING
412
+ languages: [python]
413
+ metadata:
414
+ category: asi08_cascading_failures
415
+ subcategory: unbounded_agent_loop
416
+
417
+ - id: autogen-roundrobin-no-termination
418
+ patterns:
419
+ - pattern: RoundRobinGroupChat(...)
420
+ - pattern-not: RoundRobinGroupChat(..., termination_condition=$T, ...)
421
+ message: "AutoGen RoundRobinGroupChat without termination_condition — unbounded loop risk"
422
+ severity: WARNING
423
+ languages: [python]
424
+ metadata:
425
+ category: asi08_cascading_failures
426
+ subcategory: unbounded_agent_loop
427
+
428
+ # ═══════════════════════════════════════════════════════════════════════════
429
+ # ASI09: Human-Agent Trust Exploitation
430
+ # ═══════════════════════════════════════════════════════════════════════════
431
+
432
+ - id: autogen-human-input-never
433
+ patterns:
434
+ - pattern: UserProxyAgent(..., human_input_mode="NEVER", ...)
435
+ message: "AutoGen UserProxyAgent with human_input_mode=NEVER — no human oversight for sensitive operations"
436
+ severity: WARNING
437
+ languages: [python]
438
+ metadata:
439
+ category: asi09_human_agent_trust_exploitation
440
+ subcategory: no_human_in_the_loop
441
+
442
+ - id: no-confirmation-gate
443
+ pattern-either:
444
+ - pattern: $DB.delete($TABLE)
445
+ - pattern: $OBJ.drop($TABLE)
446
+ - pattern: shutil.rmtree($PATH)
447
+ - pattern: os.remove($PATH)
448
+ message: "Destructive operation (delete/drop/remove) with no human confirmation gate — ASI09 risk"
449
+ severity: WARNING
450
+ languages: [python]
451
+ metadata:
452
+ category: asi09_human_agent_trust_exploitation
453
+ subcategory: missing_action_confirmation
454
+
455
+ - id: langgraph-react-no-interrupt
456
+ patterns:
457
+ - pattern: create_react_agent(...)
458
+ - pattern-not: create_react_agent(..., interrupt_before=$I, ...)
459
+ - pattern-not: create_react_agent(..., interrupt_after=$I, ...)
460
+ message: "LangGraph create_react_agent without interrupt_before/after — no human approval gate"
461
+ severity: WARNING
462
+ languages: [python]
463
+ metadata:
464
+ category: asi09_human_agent_trust_exploitation
465
+ subcategory: missing_action_confirmation
466
+
467
+ # ═══════════════════════════════════════════════════════════════════════════
468
+ # ASI10: Rogue Agents
469
+ # ═══════════════════════════════════════════════════════════════════════════
470
+
471
+ - id: crewai-allow-delegation-true
472
+ patterns:
473
+ - pattern: Agent(..., allow_delegation=True, ...)
474
+ message: "CrewAI agent has allow_delegation=True — enables unchecked task delegation to other agents"
475
+ severity: WARNING
476
+ languages: [python]
477
+ metadata:
478
+ category: asi10_rogue_agents
479
+ subcategory: unchecked_agent_delegation
480
+
481
+ - id: adk-agent-unchecked-delegation
482
+ patterns:
483
+ - pattern: Agent(..., sub_agents=$X, ...)
484
+ - pattern-not: Agent(..., before_agent_callback=$CB, ...)
485
+ - pattern-not: Agent(..., after_agent_callback=$CB, ...)
486
+ message: "ADK Agent delegates to sub_agents without before/after_agent_callback guardrails"
487
+ severity: WARNING
488
+ languages: [python]
489
+ metadata:
490
+ category: asi10_rogue_agents
491
+ subcategory: unchecked_agent_delegation
492
+
493
+ - id: openai-agent-unchecked-handoffs
494
+ patterns:
495
+ - pattern: Agent(..., handoffs=$H, ...)
496
+ - pattern-not: Agent(..., input_guardrails=$G, ...)
497
+ message: "OpenAI Agent with handoffs but no input_guardrails — delegation chain without validation"
498
+ severity: WARNING
499
+ languages: [python]
500
+ metadata:
501
+ category: asi10_rogue_agents
502
+ subcategory: unchecked_agent_delegation
503
+
504
+ - id: openai-agent-no-output-guardrails
505
+ patterns:
506
+ - pattern: Agent(name=$N, instructions=$I, ...)
507
+ - pattern-not: Agent(..., output_guardrails=$G, ...)
508
+ message: "OpenAI Agent without output_guardrails — unfiltered agent output to users"
509
+ severity: WARNING
510
+ languages: [python]
511
+ metadata:
512
+ category: asi10_rogue_agents
513
+ subcategory: missing_behavioral_guardrails
514
+
515
+ - id: missing-agent-monitoring
516
+ patterns:
517
+ - pattern: Agent(..., verbose=False, ...)
518
+ message: "Agent created with verbose=False and no alternative observability — rogue behavior undetectable"
519
+ severity: INFO
520
+ languages: [python]
521
+ metadata:
522
+ category: asi10_rogue_agents
523
+ subcategory: missing_agent_monitoring
524
+
525
+ - id: crewai-agent-verbose-false
526
+ patterns:
527
+ - pattern: Agent(..., verbose=False, ...)
528
+ message: "CrewAI agent with verbose=False — rogue behavior may go undetected"
529
+ severity: INFO
530
+ languages: [python]
531
+ metadata:
532
+ category: asi10_rogue_agents
533
+ subcategory: missing_agent_monitoring