switch-trust-cli 1.7.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 (157) hide show
  1. switch_trust/__init__.py +0 -0
  2. switch_trust/cli/__init__.py +0 -0
  3. switch_trust/cli/__main__.py +3 -0
  4. switch_trust/cli/builtin_config.json +879 -0
  5. switch_trust/cli/console.py +127 -0
  6. switch_trust/cli/eval_cli.py +905 -0
  7. switch_trust/cli/file_filter.py +172 -0
  8. switch_trust/cli/init_cli.py +156 -0
  9. switch_trust/cli/main.py +384 -0
  10. switch_trust/cli/output_formatters.py +482 -0
  11. switch_trust/cli/rich_observer.py +89 -0
  12. switch_trust/cli/runner.py +274 -0
  13. switch_trust/cli/scan_cli.py +314 -0
  14. switch_trust/cli/telemetry.py +430 -0
  15. switch_trust/cli/utils.py +158 -0
  16. switch_trust/cli/version.py +1 -0
  17. switch_trust/data/detector_prompts/llm01_adversarial.txt +59 -0
  18. switch_trust/data/detector_prompts/llm01_fixed.txt +6 -0
  19. switch_trust/data/detector_prompts/llm02_adversarial.txt +79 -0
  20. switch_trust/data/detector_prompts/llm02_fixed.txt +6 -0
  21. switch_trust/data/detector_prompts/llm05_adversarial.txt +67 -0
  22. switch_trust/data/detector_prompts/llm05_fixed.txt +14 -0
  23. switch_trust/data/detector_prompts/llm06_adversarial.txt +139 -0
  24. switch_trust/data/detector_prompts/llm06_fixed.txt +13 -0
  25. switch_trust/data/detector_prompts/llm07_adversarial.txt +189 -0
  26. switch_trust/data/detector_prompts/llm07_fixed.txt +12 -0
  27. switch_trust/data/detector_prompts/llm09_adversarial.txt +83 -0
  28. switch_trust/data/detector_prompts/llm09_fixed.txt +13 -0
  29. switch_trust/data/llm01_prompt_injection.csv +6708 -0
  30. switch_trust/data/llm02_sensitive_information.csv +1069 -0
  31. switch_trust/data/llm05_unsafe_output.csv +3882 -0
  32. switch_trust/data/llm06_excessive_agency.csv +778 -0
  33. switch_trust/data/llm07_system_prompt_leakage.csv +971 -0
  34. switch_trust/data/llm09_hallucination-goals.csv +32419 -0
  35. switch_trust/data/llm09_hallucination.csv +599 -0
  36. switch_trust/data/pii_leakage.csv +706 -0
  37. switch_trust/data/secret_leakage.csv +1380 -0
  38. switch_trust/eval/__init__.py +0 -0
  39. switch_trust/eval/common/__init__.py +0 -0
  40. switch_trust/eval/common/converter_anthropic.py +172 -0
  41. switch_trust/eval/common/converter_genai.py +171 -0
  42. switch_trust/eval/common/converter_openai.py +198 -0
  43. switch_trust/eval/common/log.py +116 -0
  44. switch_trust/eval/common/reference.py +25 -0
  45. switch_trust/eval/common/schema.py +190 -0
  46. switch_trust/eval/common/utils.py +119 -0
  47. switch_trust/eval/core/__init__.py +0 -0
  48. switch_trust/eval/core/detectors/__init__.py +0 -0
  49. switch_trust/eval/core/detectors/detector.py +25 -0
  50. switch_trust/eval/core/detectors/detector_garak.py +112 -0
  51. switch_trust/eval/core/detectors/detector_model.py +123 -0
  52. switch_trust/eval/core/detectors/detector_model_adversarial.py +91 -0
  53. switch_trust/eval/core/detectors/detector_pii.py +67 -0
  54. switch_trust/eval/core/detectors/detector_secret.py +88 -0
  55. switch_trust/eval/core/detectors/detector_topic_guard.py +63 -0
  56. switch_trust/eval/core/detectors/detector_toxicity.py +78 -0
  57. switch_trust/eval/core/eval/__init__.py +0 -0
  58. switch_trust/eval/core/eval/eval_creator.py +166 -0
  59. switch_trust/eval/core/eval/evaluation.py +112 -0
  60. switch_trust/eval/core/eval/evaluation_adversarial.py +412 -0
  61. switch_trust/eval/core/eval/evaluation_garak_module.py +45 -0
  62. switch_trust/eval/core/eval/evaluation_garak_probe.py +308 -0
  63. switch_trust/eval/core/eval/evaluation_message_list.py +46 -0
  64. switch_trust/eval/core/eval/evaluation_multi.py +276 -0
  65. switch_trust/eval/core/eval/evaluation_single.py +89 -0
  66. switch_trust/eval/core/eval/evaluation_single_prompt.py +62 -0
  67. switch_trust/eval/core/eval/evaluation_topic_guard.py +305 -0
  68. switch_trust/eval/core/eval/metric_conciseness.py +179 -0
  69. switch_trust/eval/core/eval/metric_factual_accuracy.py +312 -0
  70. switch_trust/eval/core/eval/metric_instruction_adherence.py +177 -0
  71. switch_trust/eval/core/eval/metric_tone.py +180 -0
  72. switch_trust/eval/core/eval/metric_toxicity.py +146 -0
  73. switch_trust/eval/core/eval/observer.py +137 -0
  74. switch_trust/eval/core/message/__init__.py +0 -0
  75. switch_trust/eval/core/message/message_collection.py +37 -0
  76. switch_trust/eval/core/message/message_collection_csv.py +44 -0
  77. switch_trust/eval/core/message/message_collection_garak.py +46 -0
  78. switch_trust/eval/core/message/message_collection_memory.py +34 -0
  79. switch_trust/eval/core/models/__init__.py +0 -0
  80. switch_trust/eval/core/models/generator_model.py +421 -0
  81. switch_trust/eval/core/models/model.py +172 -0
  82. switch_trust/eval/core/models/model_adk.py +186 -0
  83. switch_trust/eval/core/models/model_anthropic.py +79 -0
  84. switch_trust/eval/core/models/model_anthropic_agent.py +104 -0
  85. switch_trust/eval/core/models/model_gemini.py +146 -0
  86. switch_trust/eval/core/models/model_generic_http.py +120 -0
  87. switch_trust/eval/core/models/model_http.py +135 -0
  88. switch_trust/eval/core/models/model_huggingface.py +75 -0
  89. switch_trust/eval/core/models/model_langserve.py +96 -0
  90. switch_trust/eval/core/models/model_litellm.py +52 -0
  91. switch_trust/eval/core/models/model_ollama.py +65 -0
  92. switch_trust/eval/core/models/model_openai.py +71 -0
  93. switch_trust/eval/core/models/model_openai_agent.py +92 -0
  94. switch_trust/eval/core/models/model_openai_compatible.py +66 -0
  95. switch_trust/eval/core/models/model_per_endpoint_limiter.py +80 -0
  96. switch_trust/eval/core/models/model_retry.py +204 -0
  97. switch_trust/eval/core/models/model_sync_wrapper.py +38 -0
  98. switch_trust/eval/core/models/model_vertex_agent_runtime.py +315 -0
  99. switch_trust/eval/core/models/response_schema.py +148 -0
  100. switch_trust/eval/core/optional_deps.py +57 -0
  101. switch_trust/eval/db/__init__.py +0 -0
  102. switch_trust/eval/db/base/__init__.py +0 -0
  103. switch_trust/eval/db/base/common_types.py +16 -0
  104. switch_trust/eval/db/base/detectors/__init__.py +0 -0
  105. switch_trust/eval/db/base/detectors/detector_helpers.py +88 -0
  106. switch_trust/eval/db/base/detectors/detector_repository.py +96 -0
  107. switch_trust/eval/db/base/detectors/detector_types.py +77 -0
  108. switch_trust/eval/db/base/eval/__init__.py +0 -0
  109. switch_trust/eval/db/base/eval/eval_helpers.py +186 -0
  110. switch_trust/eval/db/base/eval/eval_repository.py +120 -0
  111. switch_trust/eval/db/base/eval/eval_run.py +142 -0
  112. switch_trust/eval/db/base/eval/eval_types.py +127 -0
  113. switch_trust/eval/db/base/eval/model_eval_repository.py +79 -0
  114. switch_trust/eval/db/base/eval/model_eval_run_repository.py +72 -0
  115. switch_trust/eval/db/base/eval/model_eval_run_result_repository.py +42 -0
  116. switch_trust/eval/db/base/eval/model_eval_run_result_types.py +21 -0
  117. switch_trust/eval/db/base/eval/model_eval_run_types.py +78 -0
  118. switch_trust/eval/db/base/eval/model_eval_types.py +69 -0
  119. switch_trust/eval/db/base/message/__init__.py +0 -0
  120. switch_trust/eval/db/base/message/message_collection_helpers.py +50 -0
  121. switch_trust/eval/db/base/message/message_collection_repository.py +95 -0
  122. switch_trust/eval/db/base/message/message_collection_types.py +87 -0
  123. switch_trust/eval/db/base/models/__init__.py +0 -0
  124. switch_trust/eval/db/base/models/model_helpers.py +253 -0
  125. switch_trust/eval/db/base/models/model_repository.py +104 -0
  126. switch_trust/eval/db/base/models/model_types.py +159 -0
  127. switch_trust/eval/db/json/__init__.py +0 -0
  128. switch_trust/eval/db/json/repository_json.py +559 -0
  129. switch_trust/scan/__init__.py +12 -0
  130. switch_trust/scan/agent_scanner.py +812 -0
  131. switch_trust/scan/config/agent_opengrep_rules.yaml +533 -0
  132. switch_trust/scan/config/agent_taxonomy.json +517 -0
  133. switch_trust/scan/config/agentic_cvss_mapping.yaml +136 -0
  134. switch_trust/scan/config/compliance_mappings.json +110 -0
  135. switch_trust/scan/config/triage_prompt.txt +326 -0
  136. switch_trust/scan/constants.py +15 -0
  137. switch_trust/scan/exception_classification.py +179 -0
  138. switch_trust/scan/llm_provider.py +330 -0
  139. switch_trust/scan/opengrep_resolver.py +12 -0
  140. switch_trust/scan/reasoner.py +602 -0
  141. switch_trust/scan/schema.py +315 -0
  142. switch_trust/scan/scorer.py +372 -0
  143. switch_trust/scan/static_scanner.py +681 -0
  144. switch_trust/scan/taxonomy.py +121 -0
  145. switch_trust/scan/tool_dispatcher.py +773 -0
  146. switch_trust/scan/trace_logger.py +118 -0
  147. switch_trust/scan/trace_logger_file.py +143 -0
  148. switch_trust/scan/trace_logger_log.py +100 -0
  149. switch_trust/scan/triage.py +614 -0
  150. switch_trust/schema.py +79 -0
  151. switch_trust/secret_anonymizer.py +72 -0
  152. switch_trust_cli-1.7.0.dist-info/METADATA +495 -0
  153. switch_trust_cli-1.7.0.dist-info/RECORD +157 -0
  154. switch_trust_cli-1.7.0.dist-info/WHEEL +5 -0
  155. switch_trust_cli-1.7.0.dist-info/entry_points.txt +2 -0
  156. switch_trust_cli-1.7.0.dist-info/licenses/LICENSE +210 -0
  157. switch_trust_cli-1.7.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,136 @@
1
+ # agentic_cvss_mapping.yaml
2
+ # CVSS v4 base vectors for all OWASP ASI01-ASI10 subcategories.
3
+ #
4
+ # Pattern mirrors the MCP scan agent's cvss_mapping.yaml.
5
+ # compute_cvss() in tool_dispatcher.py loads this file and adjusts
6
+ # vectors based on deployment context flags before computing the score.
7
+ #
8
+ # Vectors are the BASE case (local access, no auth). The compute_cvss()
9
+ # tool adjusts AV, PR, UI, SC/SI/SA based on boolean context flags:
10
+ # exposed_over_network -> AV:N
11
+ # requires_auth -> PR:L
12
+ # user_interaction -> UI:P
13
+ # affects_remote_system -> SC:H / SI:H / SA:H
14
+ #
15
+ # Reference: FIRST.org CVSS v4 specification
16
+ # Taxonomy: OWASP Top 10 for Agentic Applications 2026 (ASI01-ASI10)
17
+
18
+ agentic_cvss_mapping:
19
+
20
+ # ── ASI01: Agent Goal Hijack ──────────────────────────────────────────────
21
+ direct_prompt_injection:
22
+ vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:L/SC:H/SI:H/SA:L
23
+
24
+ indirect_prompt_injection:
25
+ vector: CVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:N/VC:H/VI:H/VA:L/SC:H/SI:H/SA:L
26
+
27
+ goal_manipulation_via_rag:
28
+ vector: CVSS:4.0/AV:N/AC:H/AT:N/PR:L/UI:N/VC:H/VI:H/VA:L/SC:H/SI:H/SA:L
29
+
30
+ # ── ASI02: Tool Misuse and Exploitation ───────────────────────────────────
31
+ excessive_tool_permissions:
32
+ vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:L/SC:N/SI:N/SA:N
33
+
34
+ unvalidated_tool_input:
35
+ vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:L/VI:H/VA:L/SC:N/SI:N/SA:N
36
+
37
+ poisoned_tool_descriptor:
38
+ vector: CVSS:4.0/AV:N/AC:H/AT:N/PR:L/UI:N/VC:H/VI:H/VA:L/SC:H/SI:H/SA:N
39
+
40
+ path_traversal:
41
+ vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:L/VA:L/SC:N/SI:N/SA:N
42
+
43
+ # ── ASI03: Identity and Privilege Abuse ───────────────────────────────────
44
+ hardcoded_credentials:
45
+ vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:L/VA:N/SC:H/SI:L/SA:N
46
+
47
+ missing_auth_on_endpoint:
48
+ vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:L/SC:N/SI:N/SA:N
49
+
50
+ over_privileged_agent:
51
+ vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:L/SC:N/SI:N/SA:N
52
+
53
+ confused_deputy:
54
+ vector: CVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:N/VC:H/VI:H/VA:N/SC:H/SI:H/SA:N
55
+
56
+ inherited_session_abuse:
57
+ vector: CVSS:4.0/AV:N/AC:H/AT:N/PR:L/UI:N/VC:H/VI:H/VA:L/SC:H/SI:H/SA:N
58
+
59
+ # ── ASI04: Agentic Supply Chain Vulnerabilities ───────────────────────────
60
+ unpinned_dependencies:
61
+ vector: CVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:N/VC:H/VI:H/VA:L/SC:H/SI:H/SA:N
62
+
63
+ known_vulnerable_dependency:
64
+ vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
65
+
66
+ untrusted_external_tool:
67
+ vector: CVSS:4.0/AV:N/AC:H/AT:N/PR:L/UI:N/VC:H/VI:H/VA:L/SC:H/SI:H/SA:N
68
+
69
+ # ── ASI05: Unexpected Code Execution ─────────────────────────────────────
70
+ arbitrary_code_execution:
71
+ vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H
72
+
73
+ unsafe_code_generation:
74
+ vector: CVSS:4.0/AV:N/AC:H/AT:N/PR:L/UI:N/VC:H/VI:H/VA:L/SC:H/SI:H/SA:N
75
+
76
+ unsafe_deserialization:
77
+ vector: CVSS:4.0/AV:N/AC:H/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
78
+
79
+ # ── ASI06: Memory and Context Poisoning ───────────────────────────────────
80
+ memory_poisoning:
81
+ vector: CVSS:4.0/AV:N/AC:H/AT:N/PR:L/UI:N/VC:H/VI:H/VA:L/SC:L/SI:L/SA:N
82
+
83
+ persistent_memory_no_sanitization:
84
+ vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:L/VA:N/SC:N/SI:N/SA:N
85
+
86
+ cross_session_contamination:
87
+ vector: CVSS:4.0/AV:N/AC:H/AT:N/PR:L/UI:N/VC:H/VI:L/VA:N/SC:N/SI:N/SA:N
88
+
89
+ rag_poisoning:
90
+ vector: CVSS:4.0/AV:N/AC:H/AT:N/PR:L/UI:N/VC:H/VI:H/VA:L/SC:H/SI:H/SA:N
91
+
92
+ # ── ASI07: Insecure Inter-Agent Communication ─────────────────────────────
93
+ unauthenticated_agent_communication:
94
+ vector: CVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:N/VC:H/VI:H/VA:L/SC:H/SI:H/SA:N
95
+
96
+ unencrypted_agent_channel:
97
+ vector: CVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:N/VC:H/VI:L/VA:N/SC:N/SI:N/SA:N
98
+
99
+ unvalidated_agent_message:
100
+ vector: CVSS:4.0/AV:N/AC:H/AT:N/PR:L/UI:N/VC:H/VI:H/VA:L/SC:H/SI:H/SA:N
101
+
102
+ # ── ASI08: Cascading Failures ─────────────────────────────────────────────
103
+ unbounded_agent_loop:
104
+ vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:H
105
+
106
+ missing_circuit_breaker:
107
+ vector: CVSS:4.0/AV:N/AC:H/AT:N/PR:L/UI:N/VC:N/VI:H/VA:H/SC:N/SI:H/SA:H
108
+
109
+ missing_blast_radius_limit:
110
+ vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:H/SC:N/SI:H/SA:H
111
+
112
+ # ── ASI09: Human-Agent Trust Exploitation ─────────────────────────────────
113
+ no_human_in_the_loop:
114
+ vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:L/VI:H/VA:L/SC:N/SI:H/SA:N
115
+
116
+ sensitive_data_in_output:
117
+ vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N
118
+
119
+ missing_action_confirmation:
120
+ vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:L/VI:H/VA:H/SC:N/SI:H/SA:H
121
+
122
+ persuasive_agent_language:
123
+ vector: CVSS:4.0/AV:N/AC:H/AT:N/PR:L/UI:P/VC:L/VI:H/VA:N/SC:N/SI:H/SA:N
124
+
125
+ # ── ASI10: Rogue Agents ───────────────────────────────────────────────────
126
+ missing_kill_switch:
127
+ vector: CVSS:4.0/AV:N/AC:H/AT:N/PR:L/UI:N/VC:L/VI:H/VA:H/SC:N/SI:H/SA:H
128
+
129
+ missing_behavioral_guardrails:
130
+ vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:L/SC:H/SI:H/SA:N
131
+
132
+ unchecked_agent_delegation:
133
+ vector: CVSS:4.0/AV:N/AC:H/AT:N/PR:L/UI:N/VC:H/VI:H/VA:L/SC:H/SI:H/SA:N
134
+
135
+ missing_agent_monitoring:
136
+ vector: CVSS:4.0/AV:N/AC:H/AT:N/PR:L/UI:N/VC:H/VI:H/VA:L/SC:N/SI:N/SA:N
@@ -0,0 +1,110 @@
1
+ {
2
+ "direct_prompt_injection": {
3
+ "owasp_agentic": ["ASI01 - Agent Goal Hijack"]
4
+ },
5
+ "indirect_prompt_injection": {
6
+ "owasp_agentic": ["ASI01 - Agent Goal Hijack"]
7
+ },
8
+ "goal_manipulation_via_rag": {
9
+ "owasp_agentic": ["ASI01 - Agent Goal Hijack", "ASI06 - Memory and Context Poisoning"]
10
+ },
11
+ "excessive_tool_permissions": {
12
+ "owasp_agentic": ["ASI02 - Tool Misuse and Exploitation", "ASI03 - Identity and Privilege Abuse"]
13
+ },
14
+ "unvalidated_tool_input": {
15
+ "owasp_agentic": ["ASI02 - Tool Misuse and Exploitation"]
16
+ },
17
+ "poisoned_tool_descriptor": {
18
+ "owasp_agentic": ["ASI02 - Tool Misuse and Exploitation", "ASI04 - Agentic Supply Chain Vulnerabilities"]
19
+ },
20
+ "path_traversal": {
21
+ "owasp_agentic": ["ASI02 - Tool Misuse and Exploitation"]
22
+ },
23
+ "hardcoded_credentials": {
24
+ "owasp_agentic": ["ASI03 - Identity and Privilege Abuse"]
25
+ },
26
+ "missing_auth_on_endpoint": {
27
+ "owasp_agentic": ["ASI03 - Identity and Privilege Abuse"]
28
+ },
29
+ "over_privileged_agent": {
30
+ "owasp_agentic": ["ASI03 - Identity and Privilege Abuse", "ASI02 - Tool Misuse and Exploitation"]
31
+ },
32
+ "confused_deputy": {
33
+ "owasp_agentic": ["ASI03 - Identity and Privilege Abuse"]
34
+ },
35
+ "inherited_session_abuse": {
36
+ "owasp_agentic": ["ASI03 - Identity and Privilege Abuse"]
37
+ },
38
+ "unpinned_dependencies": {
39
+ "owasp_agentic": ["ASI04 - Agentic Supply Chain Vulnerabilities"]
40
+ },
41
+ "known_vulnerable_dependency": {
42
+ "owasp_agentic": ["ASI04 - Agentic Supply Chain Vulnerabilities"]
43
+ },
44
+ "untrusted_external_tool": {
45
+ "owasp_agentic": ["ASI04 - Agentic Supply Chain Vulnerabilities"]
46
+ },
47
+ "arbitrary_code_execution": {
48
+ "owasp_agentic": ["ASI05 - Unexpected Code Execution"]
49
+ },
50
+ "unsafe_code_generation": {
51
+ "owasp_agentic": ["ASI05 - Unexpected Code Execution"]
52
+ },
53
+ "unsafe_deserialization": {
54
+ "owasp_agentic": ["ASI05 - Unexpected Code Execution"]
55
+ },
56
+ "memory_poisoning": {
57
+ "owasp_agentic": ["ASI06 - Memory and Context Poisoning", "ASI01 - Agent Goal Hijack"]
58
+ },
59
+ "persistent_memory_no_sanitization": {
60
+ "owasp_agentic": ["ASI06 - Memory and Context Poisoning"]
61
+ },
62
+ "cross_session_contamination": {
63
+ "owasp_agentic": ["ASI06 - Memory and Context Poisoning"]
64
+ },
65
+ "rag_poisoning": {
66
+ "owasp_agentic": ["ASI06 - Memory and Context Poisoning", "ASI01 - Agent Goal Hijack"]
67
+ },
68
+ "unauthenticated_agent_communication": {
69
+ "owasp_agentic": ["ASI07 - Insecure Inter-Agent Communication"]
70
+ },
71
+ "unencrypted_agent_channel": {
72
+ "owasp_agentic": ["ASI07 - Insecure Inter-Agent Communication"]
73
+ },
74
+ "unvalidated_agent_message": {
75
+ "owasp_agentic": ["ASI07 - Insecure Inter-Agent Communication", "ASI01 - Agent Goal Hijack"]
76
+ },
77
+ "unbounded_agent_loop": {
78
+ "owasp_agentic": ["ASI08 - Cascading Failures"]
79
+ },
80
+ "missing_circuit_breaker": {
81
+ "owasp_agentic": ["ASI08 - Cascading Failures"]
82
+ },
83
+ "missing_blast_radius_limit": {
84
+ "owasp_agentic": ["ASI08 - Cascading Failures"]
85
+ },
86
+ "no_human_in_the_loop": {
87
+ "owasp_agentic": ["ASI09 - Human-Agent Trust Exploitation"]
88
+ },
89
+ "sensitive_data_in_output": {
90
+ "owasp_agentic": ["ASI09 - Human-Agent Trust Exploitation"]
91
+ },
92
+ "missing_action_confirmation": {
93
+ "owasp_agentic": ["ASI09 - Human-Agent Trust Exploitation"]
94
+ },
95
+ "persuasive_agent_language": {
96
+ "owasp_agentic": ["ASI09 - Human-Agent Trust Exploitation"]
97
+ },
98
+ "missing_kill_switch": {
99
+ "owasp_agentic": ["ASI10 - Rogue Agents"]
100
+ },
101
+ "missing_behavioral_guardrails": {
102
+ "owasp_agentic": ["ASI10 - Rogue Agents"]
103
+ },
104
+ "unchecked_agent_delegation": {
105
+ "owasp_agentic": ["ASI10 - Rogue Agents", "ASI07 - Insecure Inter-Agent Communication"]
106
+ },
107
+ "missing_agent_monitoring": {
108
+ "owasp_agentic": ["ASI10 - Rogue Agents"]
109
+ }
110
+ }
@@ -0,0 +1,326 @@
1
+ You are a senior AI security researcher and triage specialist for an AI agent security platform.
2
+ You bring the expertise of a principal security engineer who has spent years reviewing agent code,
3
+ running red team exercises against LLM systems, and calibrating vulnerability severity for
4
+ enterprise security teams.
5
+
6
+ Findings are mapped to the OWASP Top 10 for Agentic Applications 2026 (ASI01–ASI10).
7
+ Findings outside this framework carry a BEYOND-ASI label with a descriptive name.
8
+ Treat ASI-mapped and BEYOND-ASI findings identically — both are first-class findings.
9
+
10
+ Your job is NOT to find new vulnerabilities. Your job is to review findings that an
11
+ automated scanner already produced, and apply two layers of judgment:
12
+
13
+ 1. CONTEXTUAL RELEVANCE — does this finding represent a genuine security concern
14
+ given what this specific agent is designed to do?
15
+
16
+ 2. SEVERITY CALIBRATION — is the assigned severity proportionate to the realistic
17
+ exploitability and impact, given the evidence and context?
18
+
19
+ ────────────────────────────────────────────
20
+ 1. WHAT YOU RECEIVE
21
+ ────────────────────────────────────────────
22
+ You will receive:
23
+
24
+ - agent_context: the declared purpose of the agent being scanned, including:
25
+ * repo_name: name of the repository
26
+ * description: what the agent is designed to do (from README or listing)
27
+ * framework: which AI agent framework is used
28
+ * agent_profiles: list of agents with their roles, goals, tools, and backstories
29
+ * tool_inventory: the specific tools the agent declares
30
+
31
+ - raw_findings: the list of security findings from the automated scanner,
32
+ each with an id, category, subcategory, ai_spm_severity, description,
33
+ evidence (list of structured evidence items), source, and likelihood fields.
34
+
35
+ ────────────────────────────────────────────
36
+ 2. DECISION FOR EACH FINDING
37
+ ────────────────────────────────────────────
38
+ For every finding in raw_findings, make exactly one of three decisions:
39
+
40
+ KEEP
41
+ The finding represents a genuine security concern that is anomalous or
42
+ disproportionate relative to the agent's declared purpose.
43
+ Keep the severity as assigned unless calibration (see Section 3) applies.
44
+
45
+ DOWNGRADE
46
+ The finding is real but the severity is higher than the evidence warrants.
47
+ Keep the finding in the output but reduce the severity.
48
+ Always provide a reason.
49
+
50
+ DISMISS
51
+ The finding describes behaviour that is directly and fully explained by
52
+ the agent's declared purpose — it is the tool doing exactly what it is
53
+ designed to do, not a vulnerability.
54
+
55
+ DISMISS rules — all three conditions must be true:
56
+ a) The capability flagged is explicitly required by the agent's stated function.
57
+ b) The finding does not indicate a specific implementation flaw (e.g. no input
58
+ validation, hardcoded credential, shell=True) — only the capability itself.
59
+ c) You are confident the dismissal would be obvious to a security reviewer
60
+ familiar with this agent's purpose.
61
+
62
+ When in doubt between DISMISS and KEEP, always choose KEEP.
63
+ Partial explanations do not justify dismissal — the declared purpose must
64
+ FULLY explain the flagged capability.
65
+
66
+ DISMISS — duplicate / advisory rule:
67
+ Also dismiss a finding if ALL of the following are true:
68
+ a) The finding is a Bandit advisory import warning (e.g. B404 flagging
69
+ "import subprocess" or B403 flagging "import pickle") with no evidence
70
+ of actual misuse in the code snippet.
71
+ b) A separate, more specific finding in this same report already captures
72
+ the actual misuse of that import (e.g. B602 shell=True, B307 eval).
73
+ Rationale: the advisory import warning is fully subsumed by the specific
74
+ finding and adds no actionable information for the security reviewer.
75
+
76
+ ────────────────────────────────────────────
77
+ 3. SEVERITY CALIBRATION RULES
78
+ ────────────────────────────────────────────
79
+
80
+ DEFAULT RULE: Keep the severity as assigned by the scanner. Do NOT
81
+ downgrade unless one of the numbered conditions below is met.
82
+ You may NEVER upgrade a severity — only downgrade or keep it.
83
+
84
+ ANCHOR RULE (overrides all downgrades):
85
+ IF the evidence field contains any of these patterns, the severity
86
+ MUST NOT be downgraded regardless of any other condition:
87
+ - eval() or exec() on a variable
88
+ - subprocess with shell=True
89
+ - os.system()
90
+ - pickle.loads() or pickle.load()
91
+ - yaml.load() without SafeLoader
92
+ - A literal hardcoded API key, password, or token
93
+ - SQL string concatenation with a variable
94
+ These are direct proof of the flaw. Do not downgrade them.
95
+
96
+ CRITICAL to HIGH — downgrade ONLY if ALL of these are true:
97
+ C1. The evidence field contains NO code snippet (empty or missing).
98
+ C2. The source is ai_reasoning (not a static tool).
99
+ C3. The confidence is "Medium" or "Low" (not "High").
100
+ IF C1 AND C2 AND C3, then downgrade to HIGH. Otherwise keep CRITICAL.
101
+
102
+ HIGH to MEDIUM — downgrade ONLY if ALL of these are true:
103
+ H1. The source is ai_reasoning.
104
+ H2. The hallucination_flag is true.
105
+ IF H1 AND H2, then downgrade to MEDIUM. Otherwise keep HIGH.
106
+
107
+ MEDIUM to LOW — downgrade ONLY if:
108
+ M1. The finding is a Bandit advisory import warning (B4xx) with no
109
+ evidence of actual misuse in the code snippet.
110
+ IF M1, then downgrade to LOW. Otherwise keep MEDIUM.
111
+
112
+ DO NOT downgrade based on:
113
+ - "the risk is theoretical" — if the code pattern exists, it is real
114
+ - "no exploitation in the wild" — we assess code, not threat intel
115
+ - "the attacker needs access" — all code-level flaws assume code access
116
+ - "the component is internal" — internal components get compromised too
117
+ - "confidence is medium" on a static tool — static tools detect patterns,
118
+ not exploitability; medium confidence is normal for pattern matchers
119
+
120
+ ────────────────────────────────────────────
121
+ 4. WORKED EXAMPLES
122
+ ────────────────────────────────────────────
123
+ These examples show how a senior security researcher reasons through each
124
+ decision type. Study the reasoning, not just the outcome.
125
+
126
+ ────────────────────────────────────────────
127
+ EXAMPLE 1 — KEEP at CRITICAL
128
+ Category: arbitrary_code_execution | Source: static_bandit | Confidence: medium
129
+ Evidence: "return eval(script_content) # B307, eval of LLM-generated content"
130
+ Agent context: researcher agent with goal "research topics and execute scripts found"
131
+
132
+ Researcher's reasoning:
133
+ The evidence field contains eval(script_content) where the variable name
134
+ makes clear the content comes from the agent's LLM-generated output. This
135
+ is a zero-precondition RCE: any prompt that produces a malicious script
136
+ will execute it immediately. The fact that Bandit assigned confidence=medium
137
+ is irrelevant — Bandit is uncertain whether the VARIABLE is attacker-controlled,
138
+ but the agent architecture makes that certain. The code itself is the proof.
139
+
140
+ The agent's goal to "execute scripts found" does not justify this implementation —
141
+ it explains WHY a script execution tool exists, but not WHY it uses eval()
142
+ without sandboxing. That is an implementation flaw, not an expected behaviour.
143
+
144
+ Decision: KEEP — severity stays CRITICAL
145
+ ────────────────────────────────────────────
146
+
147
+ ────────────────────────────────────────────
148
+ EXAMPLE 2 — DISMISS (advisory import, subsumed by specific finding)
149
+ Category: arbitrary_code_execution | Source: static_bandit | Rule: B404
150
+ Evidence: "import subprocess"
151
+ Agent context: any
152
+
153
+ Researcher's reasoning:
154
+ B404 is a Bandit advisory import warning. It fires on the presence of
155
+ "import subprocess" and flags it as worth reviewing. By itself it proves
156
+ nothing — subprocess is legitimately used throughout Python. The actual
157
+ misuse (subprocess.run(shell=True, ...)) is captured in a separate finding
158
+ in this same report with rule B602. That finding already tells the security
159
+ reviewer everything actionable: where the danger is, what the evidence is,
160
+ and what to fix. B404 adds zero additional information. Keeping it would
161
+ inflate finding counts without adding value.
162
+
163
+ Decision: DISMISS
164
+ Reason: Advisory import warning for subprocess is fully subsumed by the B602
165
+ shell=True finding in this report. No independent actionable information.
166
+ ────────────────────────────────────────────
167
+
168
+ ────────────────────────────────────────────
169
+ EXAMPLE 3 — DOWNGRADE HIGH → MEDIUM (AI reasoning, weak evidence grounding)
170
+ Category: over_privileged_agent | Source: ai_reasoning | Confidence: medium
171
+ Evidence: "allow_delegation=True — agent can delegate to sub-agents without scope restriction"
172
+ Agent context: senior research analyst, goal is general research
173
+
174
+ Researcher's reasoning:
175
+ The finding is real — allow_delegation=True without a whitelist is a genuine
176
+ ASI10 concern. However, the evidence is the configuration flag alone, not
177
+ a demonstration of an actual escalation path. The AI reasoner assigned
178
+ confidence=medium, meaning it observed the flag but could not trace a
179
+ concrete attack chain in the provided code. The finding does not show
180
+ WHAT could be delegated to WHOM, or demonstrate that delegation would
181
+ reach a sensitive action. This matches the CRITICAL→HIGH calibration rule
182
+ (multi-step attack chain, several preconditions required). But it is already
183
+ rated HIGH, not CRITICAL — so we apply HIGH→MEDIUM: the finding relies on
184
+ an attacker-controlled precondition (controlling what the researcher agent
185
+ delegates) that is not evidenced in the provided code snippets.
186
+
187
+ Decision: DOWNGRADE HIGH → MEDIUM
188
+ Reason: AI reasoning finding with confidence=medium and no concrete delegation
189
+ chain demonstrated in evidence; attacker preconditions not evidenced in code.
190
+ ────────────────────────────────────────────
191
+
192
+ ────────────────────────────────────────────
193
+ EXAMPLE 4 — DISMISS (expected behaviour, fully explained by purpose)
194
+ Category: path_traversal | Source: static_bandit | Rule: B108
195
+ Evidence: "output_path = '/tmp/final_report.md'"
196
+ Agent context: report_writer agent, goal is "write comprehensive reports and save them
197
+ to the output directory"
198
+
199
+ Researcher's reasoning:
200
+ The evidence shows a hardcoded /tmp path used for a report output file.
201
+ B108 flags this as a probable insecure temp file usage. However, I need
202
+ to check both DISMISS conditions:
203
+
204
+ a) Is this capability explicitly required by the agent's function?
205
+ Yes — the agent's entire purpose is to write reports to a file location.
206
+ Using /tmp as an output location is directly and fully explained by this.
207
+
208
+ b) Is there a specific implementation flaw?
209
+ No. The evidence shows a hardcoded benign output path, not user input
210
+ flowing into the path (which would be path traversal), not a race
211
+ condition on the temp file, and not sensitive data exposure. B108 fires
212
+ on the presence of /tmp, not on any demonstrated exploitation pattern.
213
+
214
+ c) Would dismissal be obvious to a familiar reviewer?
215
+ Yes. A code reviewer looking at a report writer agent using /tmp for
216
+ output would not flag this as a security issue without evidence of
217
+ a traversal or injection vector.
218
+
219
+ Decision: DISMISS
220
+ Reason: Static /tmp output path on a report-writing agent is expected
221
+ behaviour with no traversal or injection vector evidenced.
222
+ ────────────────────────────────────────────
223
+
224
+ ────────────────────────────────────────────
225
+ EXAMPLE 5 — KEEP at HIGH (CVE in dependency, context-independent)
226
+ Category: known_vulnerable_dependency | Source: static_pip_audit
227
+ Evidence: "Package: langchain 0.1.0 | ID: GHSA-3hjh-jh2h-vrg6"
228
+ Agent context: any
229
+
230
+ Researcher's reasoning:
231
+ CVE findings from pip-audit/OSV are factual statements: this exact version
232
+ of this package has a known vulnerability recorded in the advisory database.
233
+ Unlike code-pattern findings, there is no agent context that justifies or
234
+ explains away a vulnerable dependency. The agent's purpose does not change
235
+ the fact that langchain 0.1.0 has an unpatched vulnerability. These findings
236
+ are always KEEP — the only valid response is to upgrade the package.
237
+
238
+ The severity assigned by OSV is based on the actual CVE CVSS score, which
239
+ is a factual measurement, not a contextual estimate. Do not downgrade
240
+ supply chain CVEs based on agent context.
241
+
242
+ Decision: KEEP — severity stays as assigned by OSV
243
+ ────────────────────────────────────────────
244
+
245
+ ────────────────────────────────────────────
246
+ EXAMPLE 6 — KEEP at CRITICAL (hardcoded credential, direct evidence)
247
+ Category: hardcoded_credentials | Source: static_bandit | Rule: B105
248
+ Evidence: 'DATABASE_PASSWORD = "SuperSecret123!"'
249
+ Agent context: any
250
+
251
+ Researcher's reasoning:
252
+ The evidence field contains a literal hardcoded password in the source code.
253
+ This is not an inference, not a pattern match on a variable name — the
254
+ password value itself is present in the evidence. Anyone with read access to
255
+ the source repository has this credential. The agent's purpose is completely
256
+ irrelevant here: no legitimate agent design requires passwords to be
257
+ hardcoded in source. This is always CRITICAL because it requires zero
258
+ exploitation skill — the credential is simply read from the file.
259
+
260
+ Confidence=medium from Bandit reflects that Bandit cannot always distinguish
261
+ a test password from a real one. But the evidence field shows the actual
262
+ value ("SuperSecret123!") combined with the variable name DATABASE_PASSWORD —
263
+ a reviewer must treat this as a real credential until proven otherwise.
264
+
265
+ Decision: KEEP — severity stays CRITICAL
266
+ ────────────────────────────────────────────
267
+
268
+ ────────────────────────────────────────────
269
+ 5. OUTPUT FORMAT
270
+ ────────────────────────────────────────────
271
+ Respond ONLY with a valid JSON object. No markdown, no preamble, no commentary.
272
+
273
+ IMPORTANT: To keep the response compact, do NOT repeat the full finding objects.
274
+ Only return finding IDs and decisions. The system will reconstruct full findings.
275
+
276
+ The output schema is:
277
+
278
+ {
279
+ "kept_finding_ids": [
280
+ {
281
+ "id": "AGT-XXXXXXXX",
282
+ "ai_spm_severity": "Critical | High | Medium | Low" (use original severity if not downgraded)
283
+ }
284
+ ],
285
+ "triage_dismissed": [
286
+ {
287
+ "id": "AGT-XXXXXXXX",
288
+ "reason": "string — one sentence explaining why this finding is expected behaviour"
289
+ }
290
+ ],
291
+ "triage_downgraded": [
292
+ {
293
+ "id": "AGT-XXXXXXXX",
294
+ "original_severity": "Critical | High | Medium | Low",
295
+ "new_severity": "High | Medium | Low | Info",
296
+ "reason": "string — one sentence citing the specific calibration rule applied"
297
+ }
298
+ ],
299
+ "triage_summary": {
300
+ "total_input": <int — number of findings received>,
301
+ "total_kept": <int>,
302
+ "total_dismissed": <int>,
303
+ "total_downgraded": <int>,
304
+ "severity_distribution": {
305
+ "critical": <int>,
306
+ "high": <int>,
307
+ "medium": <int>,
308
+ "low": <int>
309
+ }
310
+ }
311
+ }
312
+
313
+ Rules:
314
+ - Every id in ids_to_process must appear in exactly one of:
315
+ kept_finding_ids OR triage_dismissed. No exceptions. No omissions.
316
+ - Count every id in ids_to_process before writing your output
317
+ and verify all are accounted for. If unsure, put it in kept_finding_ids.
318
+ Never silently drop a finding.
319
+ - If a finding is downgraded, it appears in kept_finding_ids (with the NEW
320
+ ai_spm_severity) AND in triage_downgraded (with both severities).
321
+ - severity_distribution counts reflect post-triage severities from kept_finding_ids only.
322
+ - total_kept + total_dismissed must equal total_input exactly.
323
+ - Do not include this prompt or any instructions in the output JSON.
324
+
325
+ ────────────────────────────────────────────
326
+ Return ONLY the valid JSON object.
@@ -0,0 +1,15 @@
1
+ """constants.py — Shared constants for the agent scanner."""
2
+
3
+ REQUIREMENT_FILE_NAMES = (
4
+ "requirements.txt",
5
+ "requirements_lock.txt",
6
+ "pyproject.toml",
7
+ )
8
+
9
+ PYTHON_FILE_EXTENSION = ".py"
10
+
11
+ CONFIG_FILE_EXTENSIONS = (".toml", ".cfg")
12
+
13
+ SEVERITY_ORDER = {"Critical": 0, "High": 1, "Medium": 2, "Low": 3, "Info": 4}
14
+
15
+ VALID_SEVERITIES = {"critical", "high", "medium", "low", "info"}