ventra 1.0.1__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 (813) hide show
  1. app/__init__.py +8 -0
  2. app/config.py +88 -0
  3. app/config_store.py +147 -0
  4. app/evidence.py +243 -0
  5. app/export_jobs.py +486 -0
  6. app/host_check.py +70 -0
  7. app/main.py +1575 -0
  8. app/rbac/__init__.py +60 -0
  9. app/run_service.py +593 -0
  10. app/run_store.py +245 -0
  11. app/store.py +2372 -0
  12. collector/__init__.py +34 -0
  13. collector/__main__.py +51 -0
  14. collector/_artifacts/aws/detections/detective.yaml +25 -0
  15. collector/_artifacts/aws/detections/guardduty.yaml +29 -0
  16. collector/_artifacts/aws/detections/inspector2.yaml +25 -0
  17. collector/_artifacts/aws/detections/macie.yaml +26 -0
  18. collector/_artifacts/aws/detections/securityhub.yaml +26 -0
  19. collector/_artifacts/aws/identity/account.yaml +27 -0
  20. collector/_artifacts/aws/identity/iam.yaml +47 -0
  21. collector/_artifacts/aws/identity/kms.yaml +27 -0
  22. collector/_artifacts/aws/identity/secrets.yaml +25 -0
  23. collector/_artifacts/aws/management-plane/cloudtrail.yaml +36 -0
  24. collector/_artifacts/aws/management-plane/cloudwatch.yaml +41 -0
  25. collector/_artifacts/aws/management-plane/config.yaml +26 -0
  26. collector/_artifacts/aws/management-plane/log_posture.yaml +31 -0
  27. collector/_artifacts/aws/network/apigateway.yaml +25 -0
  28. collector/_artifacts/aws/network/cloudfront.yaml +28 -0
  29. collector/_artifacts/aws/network/elb_alb.yaml +28 -0
  30. collector/_artifacts/aws/network/route53_resolver.yaml +29 -0
  31. collector/_artifacts/aws/network/vpc_flow.yaml +52 -0
  32. collector/_artifacts/aws/network/waf.yaml +27 -0
  33. collector/_artifacts/aws/workloads/ec2.yaml +32 -0
  34. collector/_artifacts/aws/workloads/eks_audit.yaml +26 -0
  35. collector/_artifacts/aws/workloads/lambda.yaml +26 -0
  36. collector/_artifacts/aws/workloads/lambda_logs.yaml +26 -0
  37. collector/_artifacts/aws/workloads/rds.yaml +25 -0
  38. collector/_artifacts/aws/workloads/s3.yaml +31 -0
  39. collector/_artifacts/aws/workloads/s3_access.yaml +28 -0
  40. collector/_artifacts/azure/detections/defender.yaml +25 -0
  41. collector/_artifacts/azure/identity/entra_audit.yaml +26 -0
  42. collector/_artifacts/azure/identity/entra_directory.yaml +27 -0
  43. collector/_artifacts/azure/identity/entra_signin.yaml +25 -0
  44. collector/_artifacts/azure/identity/oauth_consent.yaml +25 -0
  45. collector/_artifacts/azure/identity/rbac.yaml +25 -0
  46. collector/_artifacts/azure/identity/subscription.yaml +25 -0
  47. collector/_artifacts/azure/management-plane/activity_log.yaml +25 -0
  48. collector/_artifacts/azure/management-plane/diag_posture.yaml +26 -0
  49. collector/_artifacts/azure/management-plane/resource_graph.yaml +24 -0
  50. collector/_artifacts/azure/network/app_gateway.yaml +26 -0
  51. collector/_artifacts/azure/network/azure_firewall.yaml +26 -0
  52. collector/_artifacts/azure/network/dns.yaml +28 -0
  53. collector/_artifacts/azure/network/front_door.yaml +27 -0
  54. collector/_artifacts/azure/network/nsg_flow.yaml +25 -0
  55. collector/_artifacts/azure/network/vnet_flow.yaml +26 -0
  56. collector/_artifacts/azure/workloads/aks_audit.yaml +26 -0
  57. collector/_artifacts/azure/workloads/key_vault.yaml +26 -0
  58. collector/_artifacts/azure/workloads/storage_access.yaml +26 -0
  59. collector/_artifacts/gcp/data_storage/bigquery_audit.yaml +25 -0
  60. collector/_artifacts/gcp/data_storage/cloud_sql.yaml +24 -0
  61. collector/_artifacts/gcp/data_storage/secret_manager.yaml +25 -0
  62. collector/_artifacts/gcp/detections/cloud_monitoring.yaml +25 -0
  63. collector/_artifacts/gcp/detections/scc_findings.yaml +24 -0
  64. collector/_artifacts/gcp/identity/iam_policy.yaml +30 -0
  65. collector/_artifacts/gcp/identity/login_events.yaml +25 -0
  66. collector/_artifacts/gcp/identity/project.yaml +24 -0
  67. collector/_artifacts/gcp/management-plane/cloud_audit_admin.yaml +24 -0
  68. collector/_artifacts/gcp/management-plane/cloud_audit_data.yaml +26 -0
  69. collector/_artifacts/gcp/management-plane/cloud_audit_system.yaml +24 -0
  70. collector/_artifacts/gcp/management-plane/logging_posture.yaml +27 -0
  71. collector/_artifacts/gcp/network/api_gateway.yaml +24 -0
  72. collector/_artifacts/gcp/network/cloud_armor.yaml +25 -0
  73. collector/_artifacts/gcp/network/cloud_cdn.yaml +24 -0
  74. collector/_artifacts/gcp/network/cloud_dns.yaml +24 -0
  75. collector/_artifacts/gcp/network/cloud_nat.yaml +24 -0
  76. collector/_artifacts/gcp/network/firewall_logs.yaml +24 -0
  77. collector/_artifacts/gcp/network/load_balancer.yaml +24 -0
  78. collector/_artifacts/gcp/network/network_posture.yaml +29 -0
  79. collector/_artifacts/gcp/network/vpc_flow.yaml +25 -0
  80. collector/_artifacts/gcp/workloads/cloud_functions.yaml +24 -0
  81. collector/_artifacts/gcp/workloads/gce.yaml +26 -0
  82. collector/_artifacts/gcp/workloads/gke_audit.yaml +25 -0
  83. collector/_artifacts/gcp/workloads/storage_access.yaml +25 -0
  84. collector/_artifacts/gcp/workloads/vm_logs.yaml +24 -0
  85. collector/_artifacts/kubernetes/audit/k8s_apiserver_audit.yaml +30 -0
  86. collector/_artifacts/kubernetes/audit/k8s_audit_posture.yaml +24 -0
  87. collector/_artifacts/kubernetes/events/k8s_events.yaml +34 -0
  88. collector/_artifacts/kubernetes/network/k8s_cni_logs.yaml +22 -0
  89. collector/_artifacts/kubernetes/node/k8s_container_logs.yaml +25 -0
  90. collector/_artifacts/kubernetes/node/k8s_etcd.yaml +37 -0
  91. collector/_artifacts/kubernetes/node/k8s_kubelet_logs.yaml +24 -0
  92. collector/_artifacts/kubernetes/node/k8s_runtime_logs.yaml +29 -0
  93. collector/_artifacts/kubernetes/state/k8s_cluster_state.yaml +51 -0
  94. collector/_artifacts/kubernetes/state/k8s_rbac.yaml +27 -0
  95. collector/_artifacts/packs/baseline-ir-aws.yaml +11 -0
  96. collector/_artifacts/packs/baseline-ir-azure.yaml +20 -0
  97. collector/_artifacts/packs/baseline-ir-gcp.yaml +31 -0
  98. collector/_artifacts/packs/baseline-ir-kubernetes.yaml +18 -0
  99. collector/_console_static/404/index.html +1 -0
  100. collector/_console_static/404.html +1 -0
  101. collector/_console_static/_next/static/MtMFfGcEnM98E78OauMI0/_buildManifest.js +1 -0
  102. collector/_console_static/_next/static/MtMFfGcEnM98E78OauMI0/_ssgManifest.js +1 -0
  103. collector/_console_static/_next/static/chunks/1255-0947d73a7b5cc8f1.js +1 -0
  104. collector/_console_static/_next/static/chunks/1266-103fab4de22eef44.js +1 -0
  105. collector/_console_static/_next/static/chunks/1461-a2e332e00c52d6d0.js +1 -0
  106. collector/_console_static/_next/static/chunks/1468-e6d31bced036f7f3.js +1 -0
  107. collector/_console_static/_next/static/chunks/1601-20d8f2e10e1bd9cd.js +1 -0
  108. collector/_console_static/_next/static/chunks/2146-186c87be914470b7.js +1 -0
  109. collector/_console_static/_next/static/chunks/2619-04bc32f026a0d946.js +1 -0
  110. collector/_console_static/_next/static/chunks/3007-1a62fdd6aea1c4ca.js +1 -0
  111. collector/_console_static/_next/static/chunks/3510-a72d6ab06034fc56.js +1 -0
  112. collector/_console_static/_next/static/chunks/3728-98fd2ba4e7d635b1.js +1 -0
  113. collector/_console_static/_next/static/chunks/3941-e2240f6908b2ad35.js +1 -0
  114. collector/_console_static/_next/static/chunks/4748-07689affc96b2fe8.js +1 -0
  115. collector/_console_static/_next/static/chunks/4bd1b696-100b9d70ed4e49c1.js +1 -0
  116. collector/_console_static/_next/static/chunks/5147-7ebb875daf2e6bf2.js +1 -0
  117. collector/_console_static/_next/static/chunks/5239-09682fb347c4abaf.js +1 -0
  118. collector/_console_static/_next/static/chunks/549-6880f7361258a1b8.js +1 -0
  119. collector/_console_static/_next/static/chunks/5854-298f1ef2c6686ae6.js +1 -0
  120. collector/_console_static/_next/static/chunks/641-a5f2fef4bdebe348.js +1 -0
  121. collector/_console_static/_next/static/chunks/6944-863cf476fca75059.js +1 -0
  122. collector/_console_static/_next/static/chunks/7490-3e1cd1b34217dcd9.js +1 -0
  123. collector/_console_static/_next/static/chunks/8400-2a314fd4cb643bf9.js +1 -0
  124. collector/_console_static/_next/static/chunks/8780-a222f415a2bcef40.js +1 -0
  125. collector/_console_static/_next/static/chunks/92-f8cbc3ff974e4a52.js +1 -0
  126. collector/_console_static/_next/static/chunks/9346-05757e302343e5ed.js +1 -0
  127. collector/_console_static/_next/static/chunks/9455-c8997e5d0baa3c3e.js +1 -0
  128. collector/_console_static/_next/static/chunks/9957-fb2904da27189f18.js +1 -0
  129. collector/_console_static/_next/static/chunks/app/(app)/acquire/page-edef9794fd2e9479.js +1 -0
  130. collector/_console_static/_next/static/chunks/app/(app)/cases/[caseId]/cloudtrail/page-cf0e66e4ccea2e6b.js +1 -0
  131. collector/_console_static/_next/static/chunks/app/(app)/cases/[caseId]/cloudwatch/page-7918deb8fe178aac.js +1 -0
  132. collector/_console_static/_next/static/chunks/app/(app)/cases/[caseId]/collection/page-fd92b7ea856e4ada.js +1 -0
  133. collector/_console_static/_next/static/chunks/app/(app)/cases/[caseId]/data-access/page-6c18cffcbeead99b.js +1 -0
  134. collector/_console_static/_next/static/chunks/app/(app)/cases/[caseId]/files/page-0218775b330fca1c.js +1 -0
  135. collector/_console_static/_next/static/chunks/app/(app)/cases/[caseId]/identity/page-b0e1f100f755e700.js +1 -0
  136. collector/_console_static/_next/static/chunks/app/(app)/cases/[caseId]/kubernetes-audit/page-2cd7f2f3a940d7cb.js +1 -0
  137. collector/_console_static/_next/static/chunks/app/(app)/cases/[caseId]/layout-6a639a258737efeb.js +1 -0
  138. collector/_console_static/_next/static/chunks/app/(app)/cases/[caseId]/network/page-78db9bcb7b5195d0.js +1 -0
  139. collector/_console_static/_next/static/chunks/app/(app)/cases/[caseId]/overview/page-0dba5b2cec8f67bc.js +1 -0
  140. collector/_console_static/_next/static/chunks/app/(app)/cases/[caseId]/page-fd9f1e9324107213.js +1 -0
  141. collector/_console_static/_next/static/chunks/app/(app)/cases/[caseId]/report/page-24e5da3193e7deb0.js +1 -0
  142. collector/_console_static/_next/static/chunks/app/(app)/cases/[caseId]/resources/page-1541a4757830de28.js +1 -0
  143. collector/_console_static/_next/static/chunks/app/(app)/cases/[caseId]/search/page-c5ffabb83b5f11c1.js +1 -0
  144. collector/_console_static/_next/static/chunks/app/(app)/cases/[caseId]/settings/page-d4f8bb2a7fc52650.js +1 -0
  145. collector/_console_static/_next/static/chunks/app/(app)/cases/[caseId]/web/page-e15dfeaadd3becc0.js +1 -0
  146. collector/_console_static/_next/static/chunks/app/(app)/cases/page-bce0fc72e62e7477.js +1 -0
  147. collector/_console_static/_next/static/chunks/app/(app)/collection-kits/page-7c8e3a5105c914da.js +1 -0
  148. collector/_console_static/_next/static/chunks/app/(app)/config/acquire/page-676aa2404d64c047.js +1 -0
  149. collector/_console_static/_next/static/chunks/app/(app)/config/collection/page-c40279b8885b509a.js +1 -0
  150. collector/_console_static/_next/static/chunks/app/(app)/config/connections/page-d4f8bb2a7fc52650.js +1 -0
  151. collector/_console_static/_next/static/chunks/app/(app)/config/log-backends/page-d4f8bb2a7fc52650.js +1 -0
  152. collector/_console_static/_next/static/chunks/app/(app)/config/profiles/page-d4f8bb2a7fc52650.js +1 -0
  153. collector/_console_static/_next/static/chunks/app/(app)/config/providers/page-818855b2f0fb77aa.js +1 -0
  154. collector/_console_static/_next/static/chunks/app/(app)/docs/[provider]/[section]/layout-d4f8bb2a7fc52650.js +1 -0
  155. collector/_console_static/_next/static/chunks/app/(app)/docs/[provider]/[section]/page-38831a7ddd1cea3e.js +1 -0
  156. collector/_console_static/_next/static/chunks/app/(app)/docs/[provider]/collectors/[collector]/layout-d4f8bb2a7fc52650.js +1 -0
  157. collector/_console_static/_next/static/chunks/app/(app)/docs/[provider]/collectors/[collector]/page-17a41a4b5d8c046c.js +1 -0
  158. collector/_console_static/_next/static/chunks/app/(app)/docs/[provider]/layout-1ca683015f4ff55b.js +1 -0
  159. collector/_console_static/_next/static/chunks/app/(app)/docs/[provider]/page-d4f8bb2a7fc52650.js +1 -0
  160. collector/_console_static/_next/static/chunks/app/(app)/docs/page-d4f8bb2a7fc52650.js +1 -0
  161. collector/_console_static/_next/static/chunks/app/(app)/export/page-714c75a583c9c6b9.js +1 -0
  162. collector/_console_static/_next/static/chunks/app/(app)/layout-50b162154ff6dcb2.js +1 -0
  163. collector/_console_static/_next/static/chunks/app/(app)/runs/[runId]/layout-d4f8bb2a7fc52650.js +1 -0
  164. collector/_console_static/_next/static/chunks/app/(app)/runs/[runId]/page-a7e8f34c3afd21ab.js +1 -0
  165. collector/_console_static/_next/static/chunks/app/(app)/runs/new/page-d4f8bb2a7fc52650.js +1 -0
  166. collector/_console_static/_next/static/chunks/app/(app)/runs/page-d4f8bb2a7fc52650.js +1 -0
  167. collector/_console_static/_next/static/chunks/app/(app)/settings/page-347f0ee57bb85823.js +1 -0
  168. collector/_console_static/_next/static/chunks/app/_not-found/page-bd13c288a670cf32.js +1 -0
  169. collector/_console_static/_next/static/chunks/app/layout-4515ba368d27a1a1.js +1 -0
  170. collector/_console_static/_next/static/chunks/app/page-d4f8bb2a7fc52650.js +1 -0
  171. collector/_console_static/_next/static/chunks/c15bf2b0-bfa95b308e62c6cc.js +1 -0
  172. collector/_console_static/_next/static/chunks/framework-5991737ec854c1b5.js +1 -0
  173. collector/_console_static/_next/static/chunks/main-4e71f9d188d19f9d.js +1 -0
  174. collector/_console_static/_next/static/chunks/main-app-2b75a469bce105eb.js +1 -0
  175. collector/_console_static/_next/static/chunks/pages/_app-4b3fb5e477a0267f.js +1 -0
  176. collector/_console_static/_next/static/chunks/pages/_error-c970d8b55ace1b48.js +1 -0
  177. collector/_console_static/_next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
  178. collector/_console_static/_next/static/chunks/webpack-9a54ed35a2898709.js +1 -0
  179. collector/_console_static/_next/static/css/ec2686d88207223d.css +3 -0
  180. collector/_console_static/_next/static/css/f9729d2dd4e50ad2.css +1 -0
  181. collector/_console_static/_next/static/media/e91e1ff17da97c42-s.p.woff2 +0 -0
  182. collector/_console_static/_next/static/media/f5cb94a89b585f0b.p.woff2 +0 -0
  183. collector/_console_static/acquire/index.html +1 -0
  184. collector/_console_static/acquire/index.txt +26 -0
  185. collector/_console_static/cases/_/cloudtrail/index.html +1 -0
  186. collector/_console_static/cases/_/cloudtrail/index.txt +27 -0
  187. collector/_console_static/cases/_/cloudwatch/index.html +1 -0
  188. collector/_console_static/cases/_/cloudwatch/index.txt +27 -0
  189. collector/_console_static/cases/_/collection/index.html +1 -0
  190. collector/_console_static/cases/_/collection/index.txt +27 -0
  191. collector/_console_static/cases/_/data-access/index.html +1 -0
  192. collector/_console_static/cases/_/data-access/index.txt +27 -0
  193. collector/_console_static/cases/_/files/index.html +1 -0
  194. collector/_console_static/cases/_/files/index.txt +27 -0
  195. collector/_console_static/cases/_/identity/index.html +1 -0
  196. collector/_console_static/cases/_/identity/index.txt +27 -0
  197. collector/_console_static/cases/_/index.html +1 -0
  198. collector/_console_static/cases/_/index.txt +27 -0
  199. collector/_console_static/cases/_/kubernetes-audit/index.html +1 -0
  200. collector/_console_static/cases/_/kubernetes-audit/index.txt +27 -0
  201. collector/_console_static/cases/_/network/index.html +1 -0
  202. collector/_console_static/cases/_/network/index.txt +27 -0
  203. collector/_console_static/cases/_/overview/index.html +1 -0
  204. collector/_console_static/cases/_/overview/index.txt +27 -0
  205. collector/_console_static/cases/_/report/index.html +1 -0
  206. collector/_console_static/cases/_/report/index.txt +27 -0
  207. collector/_console_static/cases/_/resources/index.html +1 -0
  208. collector/_console_static/cases/_/resources/index.txt +27 -0
  209. collector/_console_static/cases/_/search/index.html +1 -0
  210. collector/_console_static/cases/_/search/index.txt +27 -0
  211. collector/_console_static/cases/_/settings/index.html +1 -0
  212. collector/_console_static/cases/_/settings/index.txt +24 -0
  213. collector/_console_static/cases/_/web/index.html +1 -0
  214. collector/_console_static/cases/_/web/index.txt +27 -0
  215. collector/_console_static/cases/index.html +1 -0
  216. collector/_console_static/cases/index.txt +26 -0
  217. collector/_console_static/collection-kits/index.html +1 -0
  218. collector/_console_static/collection-kits/index.txt +26 -0
  219. collector/_console_static/config/acquire/index.html +1 -0
  220. collector/_console_static/config/acquire/index.txt +26 -0
  221. collector/_console_static/config/collection/index.html +1 -0
  222. collector/_console_static/config/collection/index.txt +26 -0
  223. collector/_console_static/config/connections/index.html +1 -0
  224. collector/_console_static/config/connections/index.txt +23 -0
  225. collector/_console_static/config/log-backends/index.html +1 -0
  226. collector/_console_static/config/log-backends/index.txt +23 -0
  227. collector/_console_static/config/profiles/index.html +1 -0
  228. collector/_console_static/config/profiles/index.txt +23 -0
  229. collector/_console_static/config/providers/index.html +1 -0
  230. collector/_console_static/config/providers/index.txt +26 -0
  231. collector/_console_static/docs/aws/authentication/index.html +1 -0
  232. collector/_console_static/docs/aws/authentication/index.txt +27 -0
  233. collector/_console_static/docs/aws/collectors/_/index.html +1 -0
  234. collector/_console_static/docs/aws/collectors/_/index.txt +27 -0
  235. collector/_console_static/docs/aws/collectors/account/index.html +1 -0
  236. collector/_console_static/docs/aws/collectors/account/index.txt +27 -0
  237. collector/_console_static/docs/aws/collectors/apigateway/index.html +1 -0
  238. collector/_console_static/docs/aws/collectors/apigateway/index.txt +27 -0
  239. collector/_console_static/docs/aws/collectors/cloudfront/index.html +1 -0
  240. collector/_console_static/docs/aws/collectors/cloudfront/index.txt +27 -0
  241. collector/_console_static/docs/aws/collectors/cloudtrail/index.html +1 -0
  242. collector/_console_static/docs/aws/collectors/cloudtrail/index.txt +27 -0
  243. collector/_console_static/docs/aws/collectors/cloudwatch/index.html +1 -0
  244. collector/_console_static/docs/aws/collectors/cloudwatch/index.txt +27 -0
  245. collector/_console_static/docs/aws/collectors/config/index.html +1 -0
  246. collector/_console_static/docs/aws/collectors/config/index.txt +27 -0
  247. collector/_console_static/docs/aws/collectors/detective/index.html +1 -0
  248. collector/_console_static/docs/aws/collectors/detective/index.txt +27 -0
  249. collector/_console_static/docs/aws/collectors/ec2/index.html +1 -0
  250. collector/_console_static/docs/aws/collectors/ec2/index.txt +27 -0
  251. collector/_console_static/docs/aws/collectors/eks_audit/index.html +1 -0
  252. collector/_console_static/docs/aws/collectors/eks_audit/index.txt +27 -0
  253. collector/_console_static/docs/aws/collectors/elb_alb/index.html +1 -0
  254. collector/_console_static/docs/aws/collectors/elb_alb/index.txt +27 -0
  255. collector/_console_static/docs/aws/collectors/guardduty/index.html +1 -0
  256. collector/_console_static/docs/aws/collectors/guardduty/index.txt +27 -0
  257. collector/_console_static/docs/aws/collectors/iam/index.html +1 -0
  258. collector/_console_static/docs/aws/collectors/iam/index.txt +27 -0
  259. collector/_console_static/docs/aws/collectors/index.html +1 -0
  260. collector/_console_static/docs/aws/collectors/index.txt +27 -0
  261. collector/_console_static/docs/aws/collectors/inspector2/index.html +1 -0
  262. collector/_console_static/docs/aws/collectors/inspector2/index.txt +27 -0
  263. collector/_console_static/docs/aws/collectors/kms/index.html +1 -0
  264. collector/_console_static/docs/aws/collectors/kms/index.txt +27 -0
  265. collector/_console_static/docs/aws/collectors/lambda/index.html +1 -0
  266. collector/_console_static/docs/aws/collectors/lambda/index.txt +27 -0
  267. collector/_console_static/docs/aws/collectors/lambda_logs/index.html +1 -0
  268. collector/_console_static/docs/aws/collectors/lambda_logs/index.txt +27 -0
  269. collector/_console_static/docs/aws/collectors/log_posture/index.html +1 -0
  270. collector/_console_static/docs/aws/collectors/log_posture/index.txt +27 -0
  271. collector/_console_static/docs/aws/collectors/macie/index.html +1 -0
  272. collector/_console_static/docs/aws/collectors/macie/index.txt +27 -0
  273. collector/_console_static/docs/aws/collectors/rds/index.html +1 -0
  274. collector/_console_static/docs/aws/collectors/rds/index.txt +27 -0
  275. collector/_console_static/docs/aws/collectors/route53_resolver/index.html +1 -0
  276. collector/_console_static/docs/aws/collectors/route53_resolver/index.txt +27 -0
  277. collector/_console_static/docs/aws/collectors/s3/index.html +1 -0
  278. collector/_console_static/docs/aws/collectors/s3/index.txt +27 -0
  279. collector/_console_static/docs/aws/collectors/s3_access/index.html +1 -0
  280. collector/_console_static/docs/aws/collectors/s3_access/index.txt +27 -0
  281. collector/_console_static/docs/aws/collectors/secrets/index.html +1 -0
  282. collector/_console_static/docs/aws/collectors/secrets/index.txt +27 -0
  283. collector/_console_static/docs/aws/collectors/securityhub/index.html +1 -0
  284. collector/_console_static/docs/aws/collectors/securityhub/index.txt +27 -0
  285. collector/_console_static/docs/aws/collectors/vpc_flow/index.html +1 -0
  286. collector/_console_static/docs/aws/collectors/vpc_flow/index.txt +27 -0
  287. collector/_console_static/docs/aws/collectors/waf/index.html +1 -0
  288. collector/_console_static/docs/aws/collectors/waf/index.txt +27 -0
  289. collector/_console_static/docs/aws/connections/index.html +1 -0
  290. collector/_console_static/docs/aws/connections/index.txt +27 -0
  291. collector/_console_static/docs/aws/index.html +1 -0
  292. collector/_console_static/docs/aws/index.txt +24 -0
  293. collector/_console_static/docs/aws/permissions/index.html +1 -0
  294. collector/_console_static/docs/aws/permissions/index.txt +27 -0
  295. collector/_console_static/docs/azure/authentication/index.html +1 -0
  296. collector/_console_static/docs/azure/authentication/index.txt +27 -0
  297. collector/_console_static/docs/azure/collectors/_/index.html +1 -0
  298. collector/_console_static/docs/azure/collectors/_/index.txt +27 -0
  299. collector/_console_static/docs/azure/collectors/activity_log/index.html +1 -0
  300. collector/_console_static/docs/azure/collectors/activity_log/index.txt +27 -0
  301. collector/_console_static/docs/azure/collectors/aks_audit/index.html +1 -0
  302. collector/_console_static/docs/azure/collectors/aks_audit/index.txt +27 -0
  303. collector/_console_static/docs/azure/collectors/app_gateway/index.html +1 -0
  304. collector/_console_static/docs/azure/collectors/app_gateway/index.txt +27 -0
  305. collector/_console_static/docs/azure/collectors/azure_firewall/index.html +1 -0
  306. collector/_console_static/docs/azure/collectors/azure_firewall/index.txt +27 -0
  307. collector/_console_static/docs/azure/collectors/defender/index.html +1 -0
  308. collector/_console_static/docs/azure/collectors/defender/index.txt +27 -0
  309. collector/_console_static/docs/azure/collectors/diag_posture/index.html +1 -0
  310. collector/_console_static/docs/azure/collectors/diag_posture/index.txt +27 -0
  311. collector/_console_static/docs/azure/collectors/dns/index.html +1 -0
  312. collector/_console_static/docs/azure/collectors/dns/index.txt +27 -0
  313. collector/_console_static/docs/azure/collectors/entra_audit/index.html +1 -0
  314. collector/_console_static/docs/azure/collectors/entra_audit/index.txt +27 -0
  315. collector/_console_static/docs/azure/collectors/entra_directory/index.html +1 -0
  316. collector/_console_static/docs/azure/collectors/entra_directory/index.txt +27 -0
  317. collector/_console_static/docs/azure/collectors/entra_signin/index.html +1 -0
  318. collector/_console_static/docs/azure/collectors/entra_signin/index.txt +27 -0
  319. collector/_console_static/docs/azure/collectors/front_door/index.html +1 -0
  320. collector/_console_static/docs/azure/collectors/front_door/index.txt +27 -0
  321. collector/_console_static/docs/azure/collectors/index.html +1 -0
  322. collector/_console_static/docs/azure/collectors/index.txt +27 -0
  323. collector/_console_static/docs/azure/collectors/key_vault/index.html +1 -0
  324. collector/_console_static/docs/azure/collectors/key_vault/index.txt +27 -0
  325. collector/_console_static/docs/azure/collectors/nsg_flow/index.html +1 -0
  326. collector/_console_static/docs/azure/collectors/nsg_flow/index.txt +27 -0
  327. collector/_console_static/docs/azure/collectors/oauth_consent/index.html +1 -0
  328. collector/_console_static/docs/azure/collectors/oauth_consent/index.txt +27 -0
  329. collector/_console_static/docs/azure/collectors/rbac/index.html +1 -0
  330. collector/_console_static/docs/azure/collectors/rbac/index.txt +27 -0
  331. collector/_console_static/docs/azure/collectors/resource_graph/index.html +1 -0
  332. collector/_console_static/docs/azure/collectors/resource_graph/index.txt +27 -0
  333. collector/_console_static/docs/azure/collectors/storage_access/index.html +1 -0
  334. collector/_console_static/docs/azure/collectors/storage_access/index.txt +27 -0
  335. collector/_console_static/docs/azure/collectors/subscription/index.html +1 -0
  336. collector/_console_static/docs/azure/collectors/subscription/index.txt +27 -0
  337. collector/_console_static/docs/azure/collectors/vnet_flow/index.html +1 -0
  338. collector/_console_static/docs/azure/collectors/vnet_flow/index.txt +27 -0
  339. collector/_console_static/docs/azure/connections/index.html +1 -0
  340. collector/_console_static/docs/azure/connections/index.txt +27 -0
  341. collector/_console_static/docs/azure/index.html +1 -0
  342. collector/_console_static/docs/azure/index.txt +24 -0
  343. collector/_console_static/docs/azure/permissions/index.html +1 -0
  344. collector/_console_static/docs/azure/permissions/index.txt +27 -0
  345. collector/_console_static/docs/deployment/aws/cloudformation/ventra-collector-iam.yaml +219 -0
  346. collector/_console_static/docs/deployment/aws/terraform/main.tf +265 -0
  347. collector/_console_static/docs/deployment/azure/terraform/main.tf +96 -0
  348. collector/_console_static/docs/deployment/gcp/terraform/main.tf +96 -0
  349. collector/_console_static/docs/gcp/authentication/index.html +1 -0
  350. collector/_console_static/docs/gcp/authentication/index.txt +27 -0
  351. collector/_console_static/docs/gcp/collectors/_/index.html +1 -0
  352. collector/_console_static/docs/gcp/collectors/_/index.txt +27 -0
  353. collector/_console_static/docs/gcp/collectors/api_gateway/index.html +1 -0
  354. collector/_console_static/docs/gcp/collectors/api_gateway/index.txt +27 -0
  355. collector/_console_static/docs/gcp/collectors/bigquery_audit/index.html +1 -0
  356. collector/_console_static/docs/gcp/collectors/bigquery_audit/index.txt +27 -0
  357. collector/_console_static/docs/gcp/collectors/cloud_armor/index.html +1 -0
  358. collector/_console_static/docs/gcp/collectors/cloud_armor/index.txt +27 -0
  359. collector/_console_static/docs/gcp/collectors/cloud_audit_admin/index.html +1 -0
  360. collector/_console_static/docs/gcp/collectors/cloud_audit_admin/index.txt +27 -0
  361. collector/_console_static/docs/gcp/collectors/cloud_audit_data/index.html +1 -0
  362. collector/_console_static/docs/gcp/collectors/cloud_audit_data/index.txt +27 -0
  363. collector/_console_static/docs/gcp/collectors/cloud_audit_system/index.html +1 -0
  364. collector/_console_static/docs/gcp/collectors/cloud_audit_system/index.txt +27 -0
  365. collector/_console_static/docs/gcp/collectors/cloud_cdn/index.html +1 -0
  366. collector/_console_static/docs/gcp/collectors/cloud_cdn/index.txt +27 -0
  367. collector/_console_static/docs/gcp/collectors/cloud_dns/index.html +1 -0
  368. collector/_console_static/docs/gcp/collectors/cloud_dns/index.txt +27 -0
  369. collector/_console_static/docs/gcp/collectors/cloud_functions/index.html +1 -0
  370. collector/_console_static/docs/gcp/collectors/cloud_functions/index.txt +27 -0
  371. collector/_console_static/docs/gcp/collectors/cloud_monitoring/index.html +1 -0
  372. collector/_console_static/docs/gcp/collectors/cloud_monitoring/index.txt +27 -0
  373. collector/_console_static/docs/gcp/collectors/cloud_nat/index.html +1 -0
  374. collector/_console_static/docs/gcp/collectors/cloud_nat/index.txt +27 -0
  375. collector/_console_static/docs/gcp/collectors/cloud_sql/index.html +1 -0
  376. collector/_console_static/docs/gcp/collectors/cloud_sql/index.txt +27 -0
  377. collector/_console_static/docs/gcp/collectors/firewall_logs/index.html +1 -0
  378. collector/_console_static/docs/gcp/collectors/firewall_logs/index.txt +27 -0
  379. collector/_console_static/docs/gcp/collectors/gce/index.html +1 -0
  380. collector/_console_static/docs/gcp/collectors/gce/index.txt +27 -0
  381. collector/_console_static/docs/gcp/collectors/gke_audit/index.html +1 -0
  382. collector/_console_static/docs/gcp/collectors/gke_audit/index.txt +27 -0
  383. collector/_console_static/docs/gcp/collectors/iam_policy/index.html +1 -0
  384. collector/_console_static/docs/gcp/collectors/iam_policy/index.txt +27 -0
  385. collector/_console_static/docs/gcp/collectors/index.html +1 -0
  386. collector/_console_static/docs/gcp/collectors/index.txt +27 -0
  387. collector/_console_static/docs/gcp/collectors/load_balancer/index.html +1 -0
  388. collector/_console_static/docs/gcp/collectors/load_balancer/index.txt +27 -0
  389. collector/_console_static/docs/gcp/collectors/logging_posture/index.html +1 -0
  390. collector/_console_static/docs/gcp/collectors/logging_posture/index.txt +27 -0
  391. collector/_console_static/docs/gcp/collectors/login_events/index.html +1 -0
  392. collector/_console_static/docs/gcp/collectors/login_events/index.txt +27 -0
  393. collector/_console_static/docs/gcp/collectors/network_posture/index.html +1 -0
  394. collector/_console_static/docs/gcp/collectors/network_posture/index.txt +27 -0
  395. collector/_console_static/docs/gcp/collectors/project/index.html +1 -0
  396. collector/_console_static/docs/gcp/collectors/project/index.txt +27 -0
  397. collector/_console_static/docs/gcp/collectors/scc_findings/index.html +1 -0
  398. collector/_console_static/docs/gcp/collectors/scc_findings/index.txt +27 -0
  399. collector/_console_static/docs/gcp/collectors/secret_manager/index.html +1 -0
  400. collector/_console_static/docs/gcp/collectors/secret_manager/index.txt +27 -0
  401. collector/_console_static/docs/gcp/collectors/storage_access/index.html +1 -0
  402. collector/_console_static/docs/gcp/collectors/storage_access/index.txt +27 -0
  403. collector/_console_static/docs/gcp/collectors/vm_logs/index.html +1 -0
  404. collector/_console_static/docs/gcp/collectors/vm_logs/index.txt +27 -0
  405. collector/_console_static/docs/gcp/collectors/vpc_flow/index.html +1 -0
  406. collector/_console_static/docs/gcp/collectors/vpc_flow/index.txt +27 -0
  407. collector/_console_static/docs/gcp/connections/index.html +1 -0
  408. collector/_console_static/docs/gcp/connections/index.txt +27 -0
  409. collector/_console_static/docs/gcp/index.html +1 -0
  410. collector/_console_static/docs/gcp/index.txt +24 -0
  411. collector/_console_static/docs/gcp/permissions/index.html +1 -0
  412. collector/_console_static/docs/gcp/permissions/index.txt +27 -0
  413. collector/_console_static/docs/iam-policies/aws-collector-permissions.txt +182 -0
  414. collector/_console_static/docs/iam-policies/aws-collector-readonly.json +201 -0
  415. collector/_console_static/docs/iam-policies/azure-collector-graph.json +35 -0
  416. collector/_console_static/docs/iam-policies/azure-collector-readonly.json +45 -0
  417. collector/_console_static/docs/iam-policies/gcp-collector-permissions.txt +120 -0
  418. collector/_console_static/docs/iam-policies/gcp-collector-readonly.json +31 -0
  419. collector/_console_static/docs/iam-policies/kubernetes-collector-readonly.json +39 -0
  420. collector/_console_static/docs/iam-policies/kubernetes-collector-readonly.yaml +90 -0
  421. collector/_console_static/docs/index.html +1 -0
  422. collector/_console_static/docs/index.txt +23 -0
  423. collector/_console_static/docs/kubernetes/authentication/index.html +1 -0
  424. collector/_console_static/docs/kubernetes/authentication/index.txt +27 -0
  425. collector/_console_static/docs/kubernetes/collectors/_/index.html +1 -0
  426. collector/_console_static/docs/kubernetes/collectors/_/index.txt +27 -0
  427. collector/_console_static/docs/kubernetes/collectors/index.html +1 -0
  428. collector/_console_static/docs/kubernetes/collectors/index.txt +27 -0
  429. collector/_console_static/docs/kubernetes/collectors/k8s_apiserver_audit/index.html +1 -0
  430. collector/_console_static/docs/kubernetes/collectors/k8s_apiserver_audit/index.txt +27 -0
  431. collector/_console_static/docs/kubernetes/collectors/k8s_audit_posture/index.html +1 -0
  432. collector/_console_static/docs/kubernetes/collectors/k8s_audit_posture/index.txt +27 -0
  433. collector/_console_static/docs/kubernetes/collectors/k8s_cluster_state/index.html +1 -0
  434. collector/_console_static/docs/kubernetes/collectors/k8s_cluster_state/index.txt +27 -0
  435. collector/_console_static/docs/kubernetes/collectors/k8s_cni_logs/index.html +1 -0
  436. collector/_console_static/docs/kubernetes/collectors/k8s_cni_logs/index.txt +27 -0
  437. collector/_console_static/docs/kubernetes/collectors/k8s_container_logs/index.html +1 -0
  438. collector/_console_static/docs/kubernetes/collectors/k8s_container_logs/index.txt +27 -0
  439. collector/_console_static/docs/kubernetes/collectors/k8s_etcd/index.html +1 -0
  440. collector/_console_static/docs/kubernetes/collectors/k8s_etcd/index.txt +27 -0
  441. collector/_console_static/docs/kubernetes/collectors/k8s_events/index.html +1 -0
  442. collector/_console_static/docs/kubernetes/collectors/k8s_events/index.txt +27 -0
  443. collector/_console_static/docs/kubernetes/collectors/k8s_kubelet_logs/index.html +1 -0
  444. collector/_console_static/docs/kubernetes/collectors/k8s_kubelet_logs/index.txt +27 -0
  445. collector/_console_static/docs/kubernetes/collectors/k8s_rbac/index.html +1 -0
  446. collector/_console_static/docs/kubernetes/collectors/k8s_rbac/index.txt +27 -0
  447. collector/_console_static/docs/kubernetes/collectors/k8s_runtime_logs/index.html +1 -0
  448. collector/_console_static/docs/kubernetes/collectors/k8s_runtime_logs/index.txt +27 -0
  449. collector/_console_static/docs/kubernetes/connections/index.html +1 -0
  450. collector/_console_static/docs/kubernetes/connections/index.txt +27 -0
  451. collector/_console_static/docs/kubernetes/index.html +1 -0
  452. collector/_console_static/docs/kubernetes/index.txt +24 -0
  453. collector/_console_static/docs/kubernetes/permissions/index.html +1 -0
  454. collector/_console_static/docs/kubernetes/permissions/index.txt +27 -0
  455. collector/_console_static/export/index.html +1 -0
  456. collector/_console_static/export/index.txt +26 -0
  457. collector/_console_static/icons/aws/account.svg +18 -0
  458. collector/_console_static/icons/aws/apigateway.svg +18 -0
  459. collector/_console_static/icons/aws/cloudfront.svg +18 -0
  460. collector/_console_static/icons/aws/cloudtrail.svg +18 -0
  461. collector/_console_static/icons/aws/cloudwatch.svg +18 -0
  462. collector/_console_static/icons/aws/config.svg +18 -0
  463. collector/_console_static/icons/aws/detective.svg +18 -0
  464. collector/_console_static/icons/aws/dynamodb_streams.svg +18 -0
  465. collector/_console_static/icons/aws/ec2.svg +18 -0
  466. collector/_console_static/icons/aws/eks_audit.svg +18 -0
  467. collector/_console_static/icons/aws/elb_alb.svg +18 -0
  468. collector/_console_static/icons/aws/guardduty.svg +18 -0
  469. collector/_console_static/icons/aws/iam.svg +18 -0
  470. collector/_console_static/icons/aws/inspector2.svg +18 -0
  471. collector/_console_static/icons/aws/kms.svg +18 -0
  472. collector/_console_static/icons/aws/lambda.svg +18 -0
  473. collector/_console_static/icons/aws/lambda_logs.svg +18 -0
  474. collector/_console_static/icons/aws/log_posture.svg +18 -0
  475. collector/_console_static/icons/aws/macie.svg +18 -0
  476. collector/_console_static/icons/aws/network_firewall.svg +18 -0
  477. collector/_console_static/icons/aws/opensearch.svg +18 -0
  478. collector/_console_static/icons/aws/rds.svg +18 -0
  479. collector/_console_static/icons/aws/route53_resolver.svg +18 -0
  480. collector/_console_static/icons/aws/s3.svg +18 -0
  481. collector/_console_static/icons/aws/s3_access.svg +18 -0
  482. collector/_console_static/icons/aws/secrets.svg +18 -0
  483. collector/_console_static/icons/aws/securityhub.svg +18 -0
  484. collector/_console_static/icons/aws/vpc_flow.svg +18 -0
  485. collector/_console_static/icons/aws/waf.svg +18 -0
  486. collector/_console_static/icons/azure/activity_log.svg +1 -0
  487. collector/_console_static/icons/azure/aks_audit.svg +1 -0
  488. collector/_console_static/icons/azure/app_gateway.svg +1 -0
  489. collector/_console_static/icons/azure/azure_firewall.svg +1 -0
  490. collector/_console_static/icons/azure/defender.svg +1 -0
  491. collector/_console_static/icons/azure/diag_posture.svg +1 -0
  492. collector/_console_static/icons/azure/dns.svg +1 -0
  493. collector/_console_static/icons/azure/entra_audit.svg +1 -0
  494. collector/_console_static/icons/azure/entra_directory.svg +1 -0
  495. collector/_console_static/icons/azure/entra_signin.svg +1 -0
  496. collector/_console_static/icons/azure/front_door.svg +1 -0
  497. collector/_console_static/icons/azure/key_vault.svg +1 -0
  498. collector/_console_static/icons/azure/nsg_flow.svg +1 -0
  499. collector/_console_static/icons/azure/oauth_consent.svg +1 -0
  500. collector/_console_static/icons/azure/rbac.svg +1 -0
  501. collector/_console_static/icons/azure/resource_graph.svg +1 -0
  502. collector/_console_static/icons/azure/storage_access.svg +1 -0
  503. collector/_console_static/icons/azure/subscription.svg +1 -0
  504. collector/_console_static/icons/azure/vnet_flow.svg +1 -0
  505. collector/_console_static/icons/gcp/api_gateway.svg +7 -0
  506. collector/_console_static/icons/gcp/bigquery_audit.svg +1 -0
  507. collector/_console_static/icons/gcp/cloud_armor.svg +1 -0
  508. collector/_console_static/icons/gcp/cloud_audit_admin.svg +1 -0
  509. collector/_console_static/icons/gcp/cloud_audit_data.svg +1 -0
  510. collector/_console_static/icons/gcp/cloud_audit_system.svg +1 -0
  511. collector/_console_static/icons/gcp/cloud_cdn.svg +1 -0
  512. collector/_console_static/icons/gcp/cloud_dns.svg +1 -0
  513. collector/_console_static/icons/gcp/cloud_functions.svg +1 -0
  514. collector/_console_static/icons/gcp/cloud_monitoring.svg +1 -0
  515. collector/_console_static/icons/gcp/cloud_nat.svg +1 -0
  516. collector/_console_static/icons/gcp/cloud_sql.svg +1 -0
  517. collector/_console_static/icons/gcp/firewall_logs.svg +1 -0
  518. collector/_console_static/icons/gcp/gce.svg +1 -0
  519. collector/_console_static/icons/gcp/gke_audit.svg +1 -0
  520. collector/_console_static/icons/gcp/iam_policy.svg +1 -0
  521. collector/_console_static/icons/gcp/load_balancer.svg +1 -0
  522. collector/_console_static/icons/gcp/logging_posture.svg +1 -0
  523. collector/_console_static/icons/gcp/login_events.svg +1 -0
  524. collector/_console_static/icons/gcp/network_posture.svg +1 -0
  525. collector/_console_static/icons/gcp/project.svg +20 -0
  526. collector/_console_static/icons/gcp/scc_findings.svg +1 -0
  527. collector/_console_static/icons/gcp/secret_manager.svg +7 -0
  528. collector/_console_static/icons/gcp/storage_access.svg +1 -0
  529. collector/_console_static/icons/gcp/vm_logs.svg +1 -0
  530. collector/_console_static/icons/gcp/vpc_flow.svg +1 -0
  531. collector/_console_static/icons/kubernetes/k8s_apiserver_audit.svg +86 -0
  532. collector/_console_static/icons/kubernetes/k8s_audit_posture.svg +84 -0
  533. collector/_console_static/icons/kubernetes/k8s_cluster_state.svg +92 -0
  534. collector/_console_static/icons/kubernetes/k8s_cni_logs.svg +84 -0
  535. collector/_console_static/icons/kubernetes/k8s_container_logs.svg +103 -0
  536. collector/_console_static/icons/kubernetes/k8s_control_plane_logs.svg +84 -0
  537. collector/_console_static/icons/kubernetes/k8s_etcd.svg +89 -0
  538. collector/_console_static/icons/kubernetes/k8s_events.svg +85 -0
  539. collector/_console_static/icons/kubernetes/k8s_kubelet_logs.svg +86 -0
  540. collector/_console_static/icons/kubernetes/k8s_pod_logs.svg +103 -0
  541. collector/_console_static/icons/kubernetes/k8s_rbac.svg +102 -0
  542. collector/_console_static/icons/kubernetes/k8s_runtime_logs.svg +84 -0
  543. collector/_console_static/index.html +1 -0
  544. collector/_console_static/index.txt +20 -0
  545. collector/_console_static/logos/aws.png +0 -0
  546. collector/_console_static/logos/azure.png +0 -0
  547. collector/_console_static/logos/gcp.png +0 -0
  548. collector/_console_static/logos/kubernetes.svg +91 -0
  549. collector/_console_static/runs/_/index.html +1 -0
  550. collector/_console_static/runs/_/index.txt +26 -0
  551. collector/_console_static/runs/index.html +1 -0
  552. collector/_console_static/runs/index.txt +23 -0
  553. collector/_console_static/runs/new/index.html +1 -0
  554. collector/_console_static/runs/new/index.txt +23 -0
  555. collector/_console_static/settings/index.html +1 -0
  556. collector/_console_static/settings/index.txt +26 -0
  557. collector/_iam_policies/README.md +28 -0
  558. collector/_iam_policies/aws-collector-permissions.txt +182 -0
  559. collector/_iam_policies/aws-collector-readonly.json +201 -0
  560. collector/_iam_policies/azure-collector-graph.json +35 -0
  561. collector/_iam_policies/azure-collector-readonly.json +45 -0
  562. collector/_iam_policies/gcp-collector-permissions.txt +120 -0
  563. collector/_iam_policies/gcp-collector-readonly.json +31 -0
  564. collector/_iam_policies/kubernetes-collector-readonly.json +39 -0
  565. collector/_iam_policies/kubernetes-collector-readonly.yaml +90 -0
  566. collector/_schemas/artifact.schema.json +88 -0
  567. collector/_schemas/manifest.schema.json +210 -0
  568. collector/_schemas/package.schema.json +49 -0
  569. collector/_schemas/unified-event.schema.json +130 -0
  570. collector/cli.py +1946 -0
  571. collector/clouds/__init__.py +1 -0
  572. collector/clouds/aws/__init__.py +3 -0
  573. collector/clouds/aws/client_factory.py +183 -0
  574. collector/clouds/azure/__init__.py +3 -0
  575. collector/clouds/azure/client_factory.py +544 -0
  576. collector/clouds/gcp/__init__.py +3 -0
  577. collector/clouds/gcp/client_factory.py +1079 -0
  578. collector/clouds/kubernetes/__init__.py +0 -0
  579. collector/clouds/kubernetes/client_factory.py +447 -0
  580. collector/clouds/kubernetes/node.py +223 -0
  581. collector/devgui.py +607 -0
  582. collector/engine/__init__.py +34 -0
  583. collector/engine/acquire_platform.py +43 -0
  584. collector/engine/acquisition.py +287 -0
  585. collector/engine/api/__init__.py +1 -0
  586. collector/engine/api/aws/__init__.py +1 -0
  587. collector/engine/api/aws/common/__init__.py +1 -0
  588. collector/engine/api/aws/common/cw_logs.py +94 -0
  589. collector/engine/api/aws/common/s3_logs.py +147 -0
  590. collector/engine/api/aws/control_plane/__init__.py +1 -0
  591. collector/engine/api/aws/control_plane/cloudtrail.py +787 -0
  592. collector/engine/api/aws/control_plane/cloudtrail_s3.py +340 -0
  593. collector/engine/api/aws/control_plane/cloudtrail_validation.py +213 -0
  594. collector/engine/api/aws/control_plane/cloudwatch.py +269 -0
  595. collector/engine/api/aws/control_plane/config.py +97 -0
  596. collector/engine/api/aws/control_plane/log_posture.py +202 -0
  597. collector/engine/api/aws/detections/__init__.py +1 -0
  598. collector/engine/api/aws/detections/detective.py +105 -0
  599. collector/engine/api/aws/detections/guardduty.py +137 -0
  600. collector/engine/api/aws/detections/inspector2.py +122 -0
  601. collector/engine/api/aws/detections/macie.py +119 -0
  602. collector/engine/api/aws/detections/securityhub.py +116 -0
  603. collector/engine/api/aws/identity/__init__.py +1 -0
  604. collector/engine/api/aws/identity/account.py +72 -0
  605. collector/engine/api/aws/identity/iam.py +392 -0
  606. collector/engine/api/aws/identity/kms.py +76 -0
  607. collector/engine/api/aws/identity/secrets.py +60 -0
  608. collector/engine/api/aws/network/__init__.py +1 -0
  609. collector/engine/api/aws/network/apigateway.py +224 -0
  610. collector/engine/api/aws/network/cloudfront.py +214 -0
  611. collector/engine/api/aws/network/elb_alb.py +242 -0
  612. collector/engine/api/aws/network/route53_resolver.py +295 -0
  613. collector/engine/api/aws/network/vpc_flow.py +264 -0
  614. collector/engine/api/aws/network/vpc_flow_s3.py +215 -0
  615. collector/engine/api/aws/network/waf.py +156 -0
  616. collector/engine/api/aws/runner.py +237 -0
  617. collector/engine/api/aws/workloads/__init__.py +1 -0
  618. collector/engine/api/aws/workloads/ec2.py +242 -0
  619. collector/engine/api/aws/workloads/eks_audit.py +172 -0
  620. collector/engine/api/aws/workloads/lambda_.py +79 -0
  621. collector/engine/api/aws/workloads/lambda_logs.py +170 -0
  622. collector/engine/api/aws/workloads/rds_logs.py +169 -0
  623. collector/engine/api/aws/workloads/s3.py +116 -0
  624. collector/engine/api/aws/workloads/s3_access.py +212 -0
  625. collector/engine/api/azure/__init__.py +1 -0
  626. collector/engine/api/azure/common/__init__.py +32 -0
  627. collector/engine/api/azure/common/diagnostics.py +165 -0
  628. collector/engine/api/azure/common/storage_logs.py +127 -0
  629. collector/engine/api/azure/control_plane/__init__.py +1 -0
  630. collector/engine/api/azure/control_plane/activity_log.py +335 -0
  631. collector/engine/api/azure/control_plane/activity_log_common.py +20 -0
  632. collector/engine/api/azure/control_plane/diag_posture.py +163 -0
  633. collector/engine/api/azure/control_plane/resource_graph.py +84 -0
  634. collector/engine/api/azure/detections/__init__.py +1 -0
  635. collector/engine/api/azure/detections/defender.py +93 -0
  636. collector/engine/api/azure/identity/__init__.py +1 -0
  637. collector/engine/api/azure/identity/entra_audit.py +78 -0
  638. collector/engine/api/azure/identity/entra_directory.py +108 -0
  639. collector/engine/api/azure/identity/entra_signin.py +85 -0
  640. collector/engine/api/azure/identity/oauth_consent.py +73 -0
  641. collector/engine/api/azure/identity/rbac.py +118 -0
  642. collector/engine/api/azure/identity/subscription.py +65 -0
  643. collector/engine/api/azure/network/__init__.py +1 -0
  644. collector/engine/api/azure/network/app_gateway.py +29 -0
  645. collector/engine/api/azure/network/azure_firewall.py +34 -0
  646. collector/engine/api/azure/network/dns.py +35 -0
  647. collector/engine/api/azure/network/flow_common.py +203 -0
  648. collector/engine/api/azure/network/front_door.py +41 -0
  649. collector/engine/api/azure/network/nsg_flow.py +26 -0
  650. collector/engine/api/azure/network/vnet_flow.py +26 -0
  651. collector/engine/api/azure/runner.py +203 -0
  652. collector/engine/api/azure/workloads/__init__.py +1 -0
  653. collector/engine/api/azure/workloads/aks_audit.py +197 -0
  654. collector/engine/api/azure/workloads/key_vault.py +30 -0
  655. collector/engine/api/azure/workloads/storage_access.py +32 -0
  656. collector/engine/api/gcp/__init__.py +1 -0
  657. collector/engine/api/gcp/common/__init__.py +5 -0
  658. collector/engine/api/gcp/common/logging_collector.py +292 -0
  659. collector/engine/api/gcp/control_plane/__init__.py +1 -0
  660. collector/engine/api/gcp/control_plane/cloud_audit_admin.py +11 -0
  661. collector/engine/api/gcp/control_plane/cloud_audit_data.py +11 -0
  662. collector/engine/api/gcp/control_plane/cloud_audit_system.py +11 -0
  663. collector/engine/api/gcp/control_plane/logging_posture.py +189 -0
  664. collector/engine/api/gcp/detections/__init__.py +1 -0
  665. collector/engine/api/gcp/detections/cloud_monitoring.py +15 -0
  666. collector/engine/api/gcp/detections/scc_findings.py +76 -0
  667. collector/engine/api/gcp/identity/__init__.py +1 -0
  668. collector/engine/api/gcp/identity/iam_policy.py +150 -0
  669. collector/engine/api/gcp/identity/login_events.py +16 -0
  670. collector/engine/api/gcp/identity/project.py +61 -0
  671. collector/engine/api/gcp/network/__init__.py +1 -0
  672. collector/engine/api/gcp/network/api_gateway.py +12 -0
  673. collector/engine/api/gcp/network/cloud_armor.py +166 -0
  674. collector/engine/api/gcp/network/cloud_cdn.py +16 -0
  675. collector/engine/api/gcp/network/cloud_dns.py +12 -0
  676. collector/engine/api/gcp/network/cloud_nat.py +12 -0
  677. collector/engine/api/gcp/network/firewall_logs.py +12 -0
  678. collector/engine/api/gcp/network/load_balancer.py +14 -0
  679. collector/engine/api/gcp/network/network_posture.py +123 -0
  680. collector/engine/api/gcp/network/vpc_flow.py +12 -0
  681. collector/engine/api/gcp/runner.py +537 -0
  682. collector/engine/api/gcp/workloads/__init__.py +1 -0
  683. collector/engine/api/gcp/workloads/bigquery_audit.py +17 -0
  684. collector/engine/api/gcp/workloads/cloud_functions.py +12 -0
  685. collector/engine/api/gcp/workloads/cloud_sql.py +12 -0
  686. collector/engine/api/gcp/workloads/gce.py +160 -0
  687. collector/engine/api/gcp/workloads/gke_audit.py +197 -0
  688. collector/engine/api/gcp/workloads/secret_manager.py +15 -0
  689. collector/engine/api/gcp/workloads/storage_access.py +17 -0
  690. collector/engine/api/gcp/workloads/vm_logs.py +12 -0
  691. collector/engine/api/kubernetes/__init__.py +0 -0
  692. collector/engine/api/kubernetes/api_plane/__init__.py +0 -0
  693. collector/engine/api/kubernetes/api_plane/audit_posture.py +267 -0
  694. collector/engine/api/kubernetes/api_plane/cluster_state.py +468 -0
  695. collector/engine/api/kubernetes/api_plane/events.py +251 -0
  696. collector/engine/api/kubernetes/api_plane/rbac.py +264 -0
  697. collector/engine/api/kubernetes/common/__init__.py +0 -0
  698. collector/engine/api/kubernetes/common/analysis.py +165 -0
  699. collector/engine/api/kubernetes/common/apiserver_flags.py +130 -0
  700. collector/engine/api/kubernetes/common/distro.py +345 -0
  701. collector/engine/api/kubernetes/common/journal.py +58 -0
  702. collector/engine/api/kubernetes/common/nodebase.py +108 -0
  703. collector/engine/api/kubernetes/common/nodecontext.py +68 -0
  704. collector/engine/api/kubernetes/common/preflight.py +146 -0
  705. collector/engine/api/kubernetes/node_plane/__init__.py +0 -0
  706. collector/engine/api/kubernetes/node_plane/apiserver_audit.py +394 -0
  707. collector/engine/api/kubernetes/node_plane/cni_logs.py +147 -0
  708. collector/engine/api/kubernetes/node_plane/container_logs.py +118 -0
  709. collector/engine/api/kubernetes/node_plane/etcd.py +577 -0
  710. collector/engine/api/kubernetes/node_plane/kubelet_logs.py +125 -0
  711. collector/engine/api/kubernetes/node_plane/runtime_logs.py +229 -0
  712. collector/engine/api/kubernetes/runner.py +287 -0
  713. collector/engine/api_reporter.py +294 -0
  714. collector/engine/azure_log_backend.py +77 -0
  715. collector/engine/executor.py +55 -0
  716. collector/engine/gcp_collection_summary.py +95 -0
  717. collector/engine/gcp_export_bulk.py +216 -0
  718. collector/engine/gcp_log_backend.py +231 -0
  719. collector/engine/gcp_log_export.py +583 -0
  720. collector/engine/gcp_log_filter_sql.py +606 -0
  721. collector/engine/gcp_strategy_resolver.py +411 -0
  722. collector/engine/loader.py +52 -0
  723. collector/engine/matrix_state.py +352 -0
  724. collector/engine/registry/__init__.py +109 -0
  725. collector/engine/registry/aws.py +74 -0
  726. collector/engine/registry/azure.py +62 -0
  727. collector/engine/registry/gcp.py +76 -0
  728. collector/engine/registry/kubernetes.py +51 -0
  729. collector/engine/run_common.py +88 -0
  730. collector/engine/run_finalize.py +61 -0
  731. collector/engine/run_launcher.py +260 -0
  732. collector/engine/validate.py +192 -0
  733. collector/kit/__init__.py +1 -0
  734. collector/kit/auth_embed.py +38 -0
  735. collector/kit/build.py +636 -0
  736. collector/kit/deliver.py +106 -0
  737. collector/kit/format.py +317 -0
  738. collector/kit/import_cmd.py +97 -0
  739. collector/kit/mint.py +707 -0
  740. collector/kit/preview.py +90 -0
  741. collector/kit/run.py +658 -0
  742. collector/kit/run_view.py +232 -0
  743. collector/kit/templates/README-operator.md +147 -0
  744. collector/kit/templates/deployment/cloudshell.md +41 -0
  745. collector/kit/templates/deployment/ec2.md +45 -0
  746. collector/kit/templates/deployment/workstation.md +52 -0
  747. collector/kit/templates/ec2-bootstrap.sh +29 -0
  748. collector/kit/templates/gcp-log-setup-gcs.md +33 -0
  749. collector/kit/templates/run.sh +5 -0
  750. collector/kit/templates/ventra.py +491 -0
  751. collector/lib/__init__.py +1 -0
  752. collector/lib/auth.py +78 -0
  753. collector/lib/base.py +300 -0
  754. collector/lib/chain_of_custody/__init__.py +6 -0
  755. collector/lib/chain_of_custody/hashing.py +21 -0
  756. collector/lib/chain_of_custody/signing.py +74 -0
  757. collector/lib/elevate.py +180 -0
  758. collector/lib/ingest.py +80 -0
  759. collector/lib/limits.py +23 -0
  760. collector/lib/models.py +346 -0
  761. collector/lib/packaging/__init__.py +5 -0
  762. collector/lib/packaging/packager.py +129 -0
  763. collector/lib/params.py +219 -0
  764. collector/lib/scoping.py +1111 -0
  765. collector/lib/transport/__init__.py +5 -0
  766. collector/lib/transport/base.py +132 -0
  767. collector/lib/uv_util.py +77 -0
  768. collector/paths.py +122 -0
  769. collector/runner.py +18 -0
  770. collector/tools/__init__.py +1 -0
  771. collector/tools/verify_readonly.py +73 -0
  772. ventra-1.0.1.dist-info/METADATA +377 -0
  773. ventra-1.0.1.dist-info/RECORD +813 -0
  774. ventra-1.0.1.dist-info/WHEEL +4 -0
  775. ventra-1.0.1.dist-info/entry_points.txt +8 -0
  776. ventra-1.0.1.dist-info/licenses/LICENSE +202 -0
  777. ventra_ingester/__init__.py +5 -0
  778. ventra_ingester/cli.py +126 -0
  779. ventra_ingester/enrichment/__init__.py +10 -0
  780. ventra_ingester/enrichment/enrich.py +100 -0
  781. ventra_ingester/evidence_extract.py +100 -0
  782. ventra_ingester/exporters/__init__.py +1 -0
  783. ventra_ingester/exporters/elastic_ndjson.py +572 -0
  784. ventra_ingester/ingest_watch.py +151 -0
  785. ventra_ingester/limits.py +11 -0
  786. ventra_ingester/loaders/__init__.py +5 -0
  787. ventra_ingester/loaders/casestore.py +340 -0
  788. ventra_ingester/normalizer/__init__.py +12 -0
  789. ventra_ingester/normalizer/base.py +106 -0
  790. ventra_ingester/normalizer/inventory.py +201 -0
  791. ventra_ingester/normalizer/sources/__init__.py +22 -0
  792. ventra_ingester/normalizer/sources/access_logs.py +275 -0
  793. ventra_ingester/normalizer/sources/azure_activity_log.py +89 -0
  794. ventra_ingester/normalizer/sources/azure_diagnostics.py +285 -0
  795. ventra_ingester/normalizer/sources/azure_entra.py +119 -0
  796. ventra_ingester/normalizer/sources/azure_nsg_flow.py +74 -0
  797. ventra_ingester/normalizer/sources/cloudtrail.py +219 -0
  798. ventra_ingester/normalizer/sources/cloudwatch.py +54 -0
  799. ventra_ingester/normalizer/sources/dns_logs.py +50 -0
  800. ventra_ingester/normalizer/sources/eks_audit.py +90 -0
  801. ventra_ingester/normalizer/sources/findings.py +298 -0
  802. ventra_ingester/normalizer/sources/gcp_audit.py +164 -0
  803. ventra_ingester/normalizer/sources/gcp_findings.py +42 -0
  804. ventra_ingester/normalizer/sources/k8s_apiserver_audit.py +102 -0
  805. ventra_ingester/normalizer/sources/k8s_events.py +114 -0
  806. ventra_ingester/normalizer/sources/k8s_logs.py +261 -0
  807. ventra_ingester/normalizer/sources/k8s_state.py +283 -0
  808. ventra_ingester/normalizer/sources/network.py +170 -0
  809. ventra_ingester/normalizer/sources/waf.py +87 -0
  810. ventra_ingester/package.py +204 -0
  811. ventra_ingester/pipeline.py +387 -0
  812. ventra_ingester/verify/__init__.py +5 -0
  813. ventra_ingester/verify/integrity.py +131 -0
app/__init__.py ADDED
@@ -0,0 +1,8 @@
1
+ """Ventra analyst console backend.
2
+
3
+ A thin FastAPI layer over the case store the ingester produces. It never calls out to the
4
+ cloud; it only reads ``cases/<id>/`` (events.parquet via DuckDB + the JSON sidecars). RBAC is
5
+ enforced here, server-side. No telemetry.
6
+ """
7
+
8
+ __version__ = "0.1.0"
app/config.py ADDED
@@ -0,0 +1,88 @@
1
+ """Backend configuration. Everything is local and offline by design."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ from pathlib import Path
7
+
8
+
9
+ def _default_data_root() -> Path:
10
+ env = os.environ.get("VENTRA_HOME", "").strip()
11
+ if env:
12
+ return Path(env).expanduser().resolve()
13
+ # Packaged / pipx installs: keep state under the user data dir, not cwd. Shared with
14
+ # the CLI (`ventra import`, collect auto-ingest) so both use the same case store.
15
+ try:
16
+ from collector.paths import default_data_root
17
+
18
+ return default_data_root()
19
+ except Exception:
20
+ pass
21
+ return Path.cwd().resolve()
22
+
23
+
24
+ def _default_artifacts_root() -> Path:
25
+ """Locate the artifact YAML catalog regardless of the backend's working directory."""
26
+ env = os.environ.get("VENTRA_ARTIFACTS_ROOT")
27
+ if env:
28
+ return Path(env).resolve()
29
+ try:
30
+ from collector.paths import default_artifacts_root
31
+
32
+ return default_artifacts_root()
33
+ except Exception:
34
+ pass
35
+ return Path("artifacts").resolve()
36
+
37
+
38
+ _DATA = _default_data_root()
39
+
40
+
41
+ class Settings:
42
+ # Root of the case store the ingester writes to.
43
+ case_store: Path = Path(os.environ.get("VENTRA_CASE_STORE", str(_DATA / "cases"))).resolve()
44
+ # Root of the artifact YAML catalog the Acquire tab and kit builder read.
45
+ artifacts_root: Path = _default_artifacts_root()
46
+ # Where uploaded packages are staged before ingest.
47
+ upload_dir: Path = Path(os.environ.get("VENTRA_UPLOAD_DIR", str(_DATA / ".ventra-uploads"))).resolve()
48
+ # Hard cap on an uploaded evidence package, in MB. Streamed to disk; the request is
49
+ # rejected once the limit is exceeded so a large upload can't exhaust memory or disk.
50
+ max_upload_mb: int = int(os.environ.get("VENTRA_MAX_UPLOAD_MB", "20480"))
51
+ # CORS origins for the frontend dev server.
52
+ cors_origins: list[str] = os.environ.get(
53
+ "VENTRA_CORS", "http://localhost:3000,http://localhost:8080"
54
+ ).split(",")
55
+ # Refuse requests whose Host isn't this machine (DNS rebinding; see app.host_check). Add
56
+ # names with VENTRA_ALLOWED_HOSTS rather than turning this off.
57
+ host_check: bool = os.environ.get("VENTRA_HOST_CHECK", "on").strip().lower() not in (
58
+ "0",
59
+ "off",
60
+ "false",
61
+ "no",
62
+ )
63
+ # Telemetry is OFF and not configurable to on. Stated explicitly for auditors.
64
+ telemetry: bool = False
65
+ # S3 prefix polled by Import from S3 in the console (s3://bucket/prefix/).
66
+ ingest_s3_prefix: str = os.environ.get("VENTRA_INGEST_S3_PREFIX", "").strip()
67
+ ingest_download_dir: Path = Path(
68
+ os.environ.get("VENTRA_INGEST_DOWNLOAD_DIR", str(_DATA / ".ventra-ingest-watch"))
69
+ ).resolve()
70
+ _ingest_state = os.environ.get("VENTRA_INGEST_STATE_FILE", "").strip()
71
+ ingest_state_file: Path | None = Path(_ingest_state).resolve() if _ingest_state else None
72
+ # Saved connections and collection profiles for the Configuration section.
73
+ config_dir: Path = Path(os.environ.get("VENTRA_CONFIG_DIR", str(_DATA / ".ventra-config"))).resolve()
74
+ # File-backed collection run state (matrix + SSE events).
75
+ runs_dir: Path = Path(os.environ.get("VENTRA_RUNS_DIR", str(_DATA / ".ventra-runs"))).resolve()
76
+ # Optional SIEM drop zone: export writes NDJSON here for Logstash/Filebeat/forwarders.
77
+ # Unset = download-only. Never holds SIEM credentials — shippers watch this path.
78
+ _export_drop = os.environ.get("VENTRA_EXPORT_DROP_DIR", "").strip()
79
+ export_drop_dir: Path | None = Path(_export_drop).resolve() if _export_drop else None
80
+
81
+
82
+ settings = Settings()
83
+ settings.upload_dir.mkdir(parents=True, exist_ok=True)
84
+ settings.config_dir.mkdir(parents=True, exist_ok=True)
85
+ settings.runs_dir.mkdir(parents=True, exist_ok=True)
86
+ settings.case_store.mkdir(parents=True, exist_ok=True)
87
+ if settings.export_drop_dir is not None:
88
+ settings.export_drop_dir.mkdir(parents=True, exist_ok=True)
app/config_store.py ADDED
@@ -0,0 +1,147 @@
1
+ """File-backed configuration store for connections and collection profiles."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import os
7
+ import uuid
8
+ from pathlib import Path
9
+ from typing import Any
10
+
11
+ # Connection fields that hold credentials. They stay on disk (the collectors need them) but
12
+ # never leave the backend: API responses carry only which ones are set.
13
+ SECRET_FIELDS = (
14
+ "aws_secret_access_key",
15
+ "aws_session_token",
16
+ "azure_client_secret",
17
+ "azure_client_certificate_content",
18
+ "gcp_service_account_json",
19
+ "kubeconfig_content",
20
+ )
21
+
22
+
23
+ def public_connection(conn: dict[str, Any]) -> dict[str, Any]:
24
+ """A connection as the API returns it: secrets removed, ``stored_secrets`` lists what is set."""
25
+ out = {k: v for k, v in conn.items() if k not in SECRET_FIELDS}
26
+ out["stored_secrets"] = [k for k in SECRET_FIELDS if conn.get(k)]
27
+ return out
28
+
29
+
30
+ class ConfigNotFound(Exception):
31
+ pass
32
+
33
+
34
+ class ConfigStore:
35
+ def __init__(self, root: Path) -> None:
36
+ self.root = root
37
+ self.root.mkdir(mode=0o700, parents=True, exist_ok=True)
38
+ self.connections_path = self.root / "connections.json"
39
+ self.profiles_path = self.root / "profiles.json"
40
+ self._restrict_permissions()
41
+
42
+ def _restrict_permissions(self) -> None:
43
+ """Owner-only access for the store (and files written by older versions)."""
44
+ if os.name != "posix":
45
+ return
46
+ for path, mode in (
47
+ (self.root, 0o700),
48
+ (self.connections_path, 0o600),
49
+ (self.profiles_path, 0o600),
50
+ ):
51
+ try:
52
+ if path.exists() and (path.stat().st_mode & 0o777) != mode:
53
+ path.chmod(mode)
54
+ except OSError:
55
+ pass # not ours to change (e.g. read-only mount); nothing more we can do
56
+
57
+ def _read(self, path: Path) -> list[dict[str, Any]]:
58
+ if not path.is_file():
59
+ return []
60
+ return json.loads(path.read_text(encoding="utf-8"))
61
+
62
+ def _write(self, path: Path, items: list[dict[str, Any]]) -> None:
63
+ """Write atomically, owner read/write only: the file holds cloud credentials."""
64
+ tmp = path.with_name(f".{path.name}.{uuid.uuid4().hex}.tmp")
65
+ fd = os.open(tmp, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o600)
66
+ try:
67
+ with os.fdopen(fd, "w", encoding="utf-8") as fh:
68
+ json.dump(items, fh, indent=2)
69
+ os.replace(tmp, path)
70
+ except BaseException:
71
+ tmp.unlink(missing_ok=True)
72
+ raise
73
+
74
+ def list_connections(self) -> list[dict[str, Any]]:
75
+ return self._read(self.connections_path)
76
+
77
+ def get_connection(self, conn_id: str) -> dict[str, Any]:
78
+ item = next((c for c in self.list_connections() if c.get("id") == conn_id), None)
79
+ if item is None:
80
+ raise ConfigNotFound(f"Connection not found: {conn_id}")
81
+ return item
82
+
83
+ def create_connection(self, data: dict[str, Any]) -> dict[str, Any]:
84
+ from datetime import datetime, timezone
85
+
86
+ items = self.list_connections()
87
+ entry = {
88
+ "id": str(uuid.uuid4()),
89
+ "created_at": datetime.now(timezone.utc).isoformat(),
90
+ **data,
91
+ }
92
+ items.append(entry)
93
+ self._write(self.connections_path, items)
94
+ return entry
95
+
96
+ def update_connection(self, conn_id: str, patch: dict[str, Any]) -> dict[str, Any]:
97
+ items = self.list_connections()
98
+ for i, item in enumerate(items):
99
+ if item.get("id") == conn_id:
100
+ updated = {**item, **patch, "id": conn_id}
101
+ items[i] = updated
102
+ self._write(self.connections_path, items)
103
+ return updated
104
+ raise ConfigNotFound(f"Connection not found: {conn_id}")
105
+
106
+ def delete_connection(self, conn_id: str) -> None:
107
+ items = [c for c in self.list_connections() if c.get("id") != conn_id]
108
+ if len(items) == len(self._read(self.connections_path)):
109
+ raise ConfigNotFound(f"Connection not found: {conn_id}")
110
+ self._write(self.connections_path, items)
111
+
112
+ def list_profiles(self) -> list[dict[str, Any]]:
113
+ return self._read(self.profiles_path)
114
+
115
+ def get_profile(self, profile_id: str) -> dict[str, Any]:
116
+ item = next((p for p in self.list_profiles() if p.get("id") == profile_id), None)
117
+ if item is None:
118
+ raise ConfigNotFound(f"Profile not found: {profile_id}")
119
+ return item
120
+
121
+ def create_profile(self, data: dict[str, Any]) -> dict[str, Any]:
122
+ items = self.list_profiles()
123
+ entry = {"id": str(uuid.uuid4()), **data}
124
+ items.append(entry)
125
+ self._write(self.profiles_path, items)
126
+ return entry
127
+
128
+ def update_profile(self, profile_id: str, patch: dict[str, Any]) -> dict[str, Any]:
129
+ items = self.list_profiles()
130
+ for i, item in enumerate(items):
131
+ if item.get("id") == profile_id:
132
+ updated = {**item, **patch, "id": profile_id}
133
+ items[i] = updated
134
+ self._write(self.profiles_path, items)
135
+ return updated
136
+ raise ConfigNotFound(f"Profile not found: {profile_id}")
137
+
138
+ def delete_profile(self, profile_id: str) -> None:
139
+ items = [p for p in self.list_profiles() if p.get("id") != profile_id]
140
+ if len(items) == len(self._read(self.profiles_path)):
141
+ raise ConfigNotFound(f"Profile not found: {profile_id}")
142
+ self._write(self.profiles_path, items)
143
+
144
+
145
+ from .config import settings
146
+
147
+ config_store = ConfigStore(settings.config_dir)
app/evidence.py ADDED
@@ -0,0 +1,243 @@
1
+ """Browse raw evidence files extracted from the sealed package into ``cases/<id>/evidence/``."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import gzip
6
+ import json
7
+ import re
8
+ from pathlib import Path
9
+ from typing import Any
10
+
11
+ from .config import settings
12
+
13
+ _PATH_RE = re.compile(r"^[A-Za-z0-9][A-Za-z0-9._/-]{0,512}$")
14
+
15
+
16
+ class EvidenceError(ValueError):
17
+ pass
18
+
19
+
20
+ class EvidenceNotFound(EvidenceError):
21
+ pass
22
+
23
+
24
+ def _evidence_root(case_dir: Path) -> Path:
25
+ return case_dir / "evidence"
26
+
27
+
28
+ def _resolve_evidence_path(case_dir: Path, rel_path: str) -> Path:
29
+ rel = rel_path.strip().lstrip("/").replace("\\", "/")
30
+ if not rel or ".." in rel.split("/") or not _PATH_RE.fullmatch(rel):
31
+ raise EvidenceError(f"Invalid evidence path: {rel_path!r}")
32
+ root = _evidence_root(case_dir).resolve()
33
+ target = (root / rel).resolve()
34
+ if target != root and root not in target.parents:
35
+ raise EvidenceError(f"Path escapes evidence root: {rel_path!r}")
36
+ return target
37
+
38
+
39
+ def _manifest_source_meta(manifest: dict[str, Any]) -> dict[str, dict[str, Any]]:
40
+ out: dict[str, dict[str, Any]] = {}
41
+ for entry in manifest.get("sources") or []:
42
+ if not isinstance(entry, dict):
43
+ continue
44
+ path = str(entry.get("path") or "").strip()
45
+ if path:
46
+ out[path] = entry
47
+ name = str(entry.get("name") or "").strip()
48
+ if name and name not in out:
49
+ out[name] = entry
50
+ return out
51
+
52
+
53
+ def _classify_file(rel: str) -> str:
54
+ name = rel.rsplit("/", 1)[-1]
55
+ if name.startswith("events"):
56
+ return "events"
57
+ if name == "config.json":
58
+ return "config"
59
+ if name == "snapshot.json":
60
+ return "snapshot"
61
+ if name == "_meta.json":
62
+ return "meta"
63
+ if "credential_report" in name:
64
+ return "credential_report"
65
+ if rel.startswith("errors/"):
66
+ return "error"
67
+ if rel == "collection.log":
68
+ return "collection_log"
69
+ if rel == "manifest.json":
70
+ return "manifest"
71
+ if rel.endswith(".sig"):
72
+ return "signature"
73
+ return "other"
74
+
75
+
76
+ # Sidecar / packaging kinds must not display a source-level inherited record_count.
77
+ _NON_DATA_KINDS = frozenset({"config", "meta", "manifest", "signature", "collection_log", "error"})
78
+
79
+
80
+ def _record_count_for_file(kind: str, manifest_entry: dict[str, Any] | None) -> int | None:
81
+ if not manifest_entry:
82
+ return None
83
+ if kind in _NON_DATA_KINDS:
84
+ return None
85
+ raw = manifest_entry.get("record_count")
86
+ if raw is None:
87
+ return None
88
+ try:
89
+ return int(raw)
90
+ except (TypeError, ValueError):
91
+ return None
92
+
93
+
94
+ def ensure_evidence_extracted(case_dir: Path, case_id: str) -> Path:
95
+ """Return the evidence directory, extracting from a retained package when missing."""
96
+ root = _evidence_root(case_dir)
97
+ if root.is_dir() and any(root.rglob("*")):
98
+ return root
99
+
100
+ from ventra_ingester.evidence_extract import extract_package, find_package_for_case
101
+
102
+ pkg_dir = case_dir / "package"
103
+ package = find_package_for_case(case_id, pkg_dir, settings.upload_dir)
104
+ if package is None:
105
+ raise EvidenceNotFound(f"No raw evidence files for case {case_id!r}. Re-import the sealed package.")
106
+ extract_package(package, root)
107
+ return root
108
+
109
+
110
+ def list_evidence_files(case_dir: Path, manifest: dict[str, Any]) -> dict[str, Any]:
111
+ case_id = str(manifest.get("case_id") or case_dir.name)
112
+ root = ensure_evidence_extracted(case_dir, case_id)
113
+ meta_by_path = _manifest_source_meta(manifest)
114
+ files: list[dict[str, Any]] = []
115
+ total_bytes = 0
116
+ for path in sorted(root.rglob("*")):
117
+ if not path.is_file():
118
+ continue
119
+ rel = path.relative_to(root).as_posix()
120
+ size = path.stat().st_size
121
+ total_bytes += size
122
+ source_name = ""
123
+ if rel.startswith("sources/"):
124
+ parts = rel.split("/")
125
+ if len(parts) >= 2:
126
+ source_name = parts[1]
127
+ # Prefer exact path, then source name (collector-level entry), then first path segment.
128
+ manifest_entry = (
129
+ meta_by_path.get(rel)
130
+ or (meta_by_path.get(source_name) if source_name else None)
131
+ or meta_by_path.get(rel.split("/", 1)[0])
132
+ )
133
+ kind = _classify_file(rel)
134
+ files.append(
135
+ {
136
+ "path": rel,
137
+ "size": size,
138
+ "kind": kind,
139
+ "source": source_name or None,
140
+ "sha256": (manifest_entry or {}).get("sha256"),
141
+ "record_count": _record_count_for_file(kind, manifest_entry),
142
+ "status": (manifest_entry or {}).get("status"),
143
+ "notes": (manifest_entry or {}).get("notes"),
144
+ }
145
+ )
146
+ return {
147
+ "case_id": case_id,
148
+ "root": "evidence",
149
+ "files": files,
150
+ "total_files": len(files),
151
+ "total_bytes": total_bytes,
152
+ }
153
+
154
+
155
+ def read_evidence_text(case_dir: Path, rel_path: str, *, max_bytes: int | None = None) -> dict[str, Any]:
156
+ target = _resolve_evidence_path(case_dir, rel_path)
157
+ if not target.is_file():
158
+ raise EvidenceNotFound(f"No evidence file at {rel_path!r}")
159
+ size = target.stat().st_size
160
+ cap = max_bytes if max_bytes is not None else size
161
+ raw = target.read_bytes()[:cap]
162
+ truncated = len(raw) < size
163
+ if rel_path.endswith(".gz") and not rel_path.endswith(".tar.gz"):
164
+ try:
165
+ raw = gzip.decompress(raw)
166
+ truncated = truncated or len(raw) >= cap
167
+ except OSError:
168
+ pass
169
+ text = raw.decode("utf-8", errors="replace")
170
+ content_type = "json" if rel_path.endswith(".json") else "text"
171
+ if content_type == "json":
172
+ try:
173
+ parsed = json.loads(text)
174
+ return {
175
+ "path": rel_path,
176
+ "size": size,
177
+ "truncated": truncated,
178
+ "content_type": "json",
179
+ "json": parsed,
180
+ }
181
+ except json.JSONDecodeError:
182
+ content_type = "text"
183
+ return {
184
+ "path": rel_path,
185
+ "size": size,
186
+ "truncated": truncated,
187
+ "content_type": content_type,
188
+ "text": text,
189
+ }
190
+
191
+
192
+ def read_evidence_lines(
193
+ case_dir: Path,
194
+ rel_path: str,
195
+ *,
196
+ offset: int = 0,
197
+ limit: int | None = None,
198
+ ) -> dict[str, Any]:
199
+ """Return JSON-lines records from an events file with optional pagination."""
200
+ target = _resolve_evidence_path(case_dir, rel_path)
201
+ if not target.is_file():
202
+ raise EvidenceNotFound(f"No evidence file at {rel_path!r}")
203
+
204
+ if limit is None:
205
+ limit = 10_000_000
206
+
207
+ data = target.read_bytes()
208
+ if rel_path.endswith(".gz"):
209
+ data = gzip.decompress(data)
210
+ lines = data.decode("utf-8", errors="replace").splitlines()
211
+ total_lines = len(lines)
212
+ slice_lines = lines[offset : offset + limit]
213
+ records: list[Any] = []
214
+ for line in slice_lines:
215
+ line = line.strip()
216
+ if not line:
217
+ continue
218
+ try:
219
+ records.append(json.loads(line))
220
+ except json.JSONDecodeError:
221
+ records.append({"_raw": line})
222
+ return {
223
+ "path": rel_path,
224
+ "total_lines": total_lines,
225
+ "offset": offset,
226
+ "count": len(records),
227
+ "has_more": offset + len(slice_lines) < total_lines,
228
+ "records": records,
229
+ }
230
+
231
+
232
+ def read_evidence_bytes(case_dir: Path, rel_path: str) -> tuple[Path, str]:
233
+ target = _resolve_evidence_path(case_dir, rel_path)
234
+ if not target.is_file():
235
+ raise EvidenceNotFound(f"No evidence file at {rel_path!r}")
236
+ media = "application/octet-stream"
237
+ if rel_path.endswith(".json"):
238
+ media = "application/json"
239
+ elif rel_path.endswith(".log"):
240
+ media = "text/plain"
241
+ elif rel_path.endswith(".gz"):
242
+ media = "application/gzip"
243
+ return target, media