voidaccess 2.0.3__tar.gz → 2.1.0__tar.gz

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 (408) hide show
  1. {voidaccess-2.0.3/voidaccess.egg-info → voidaccess-2.1.0}/PKG-INFO +243 -242
  2. voidaccess-2.1.0/api/actor_views.py +91 -0
  3. {voidaccess-2.0.3 → voidaccess-2.1.0}/api/auth.py +15 -2
  4. {voidaccess-2.0.3 → voidaccess-2.1.0}/api/main.py +182 -60
  5. voidaccess-2.1.0/api/ownership.py +58 -0
  6. voidaccess-2.1.0/api/rate_limit.py +81 -0
  7. {voidaccess-2.0.3 → voidaccess-2.1.0}/api/routes/actors.py +45 -34
  8. {voidaccess-2.0.3 → voidaccess-2.1.0}/api/routes/admin.py +41 -13
  9. {voidaccess-2.0.3 → voidaccess-2.1.0}/api/routes/auth.py +18 -19
  10. {voidaccess-2.0.3 → voidaccess-2.1.0}/api/routes/entities.py +30 -25
  11. {voidaccess-2.0.3 → voidaccess-2.1.0}/api/routes/export.py +3 -2
  12. voidaccess-2.1.0/api/routes/ingest.py +169 -0
  13. {voidaccess-2.0.3 → voidaccess-2.1.0}/api/routes/investigations.py +431 -156
  14. voidaccess-2.1.0/api/routes/monitors.py +151 -0
  15. {voidaccess-2.0.3 → voidaccess-2.1.0}/api/routes/search.py +9 -6
  16. voidaccess-2.1.0/auth/token_blacklist.py +178 -0
  17. voidaccess-2.1.0/benchmark/__init__.py +11 -0
  18. voidaccess-2.1.0/benchmark/artifact.py +115 -0
  19. voidaccess-2.1.0/benchmark/data/benchmark_queries.json +18 -0
  20. voidaccess-2.1.0/benchmark/engine_cull.py +123 -0
  21. voidaccess-2.1.0/benchmark/engine_probe.py +345 -0
  22. voidaccess-2.1.0/benchmark/metrics.py +362 -0
  23. voidaccess-2.1.0/benchmark/queries.py +95 -0
  24. voidaccess-2.1.0/config.py +447 -0
  25. voidaccess-2.1.0/credential_presence/__init__.py +209 -0
  26. voidaccess-2.1.0/db/entity_views.py +47 -0
  27. {voidaccess-2.0.3 → voidaccess-2.1.0}/db/migrations/env.py +16 -0
  28. voidaccess-2.1.0/db/migrations/versions/0027_add_shared_corpus_tier.py +139 -0
  29. voidaccess-2.1.0/db/migrations/versions/0028_add_shared_provenance.py +42 -0
  30. voidaccess-2.1.0/db/migrations/versions/0029_add_job_queue.py +79 -0
  31. voidaccess-2.1.0/db/migrations/versions/0030_add_onion_consecutive_dead.py +46 -0
  32. voidaccess-2.1.0/db/migrations/versions/0031_add_source_reputation.py +60 -0
  33. voidaccess-2.1.0/db/migrations/versions/0032_add_global_entity_source.py +63 -0
  34. voidaccess-2.1.0/db/migrations/versions/0033_add_ingest_tables.py +58 -0
  35. voidaccess-2.1.0/db/migrations/versions/0034_add_global_entity_disposition.py +40 -0
  36. voidaccess-2.1.0/db/migrations/versions/0035_add_global_entity_source_contributor.py +41 -0
  37. voidaccess-2.1.0/db/migrations/versions/0036_multiuser_security.py +87 -0
  38. {voidaccess-2.0.3 → voidaccess-2.1.0}/db/models.py +68 -3
  39. {voidaccess-2.0.3 → voidaccess-2.1.0}/db/queries.py +40 -22
  40. {voidaccess-2.0.3 → voidaccess-2.1.0}/db/session.py +2 -2
  41. {voidaccess-2.0.3 → voidaccess-2.1.0}/export/ioc_package.py +1 -1
  42. {voidaccess-2.0.3 → voidaccess-2.1.0}/export/stix.py +2 -1
  43. {voidaccess-2.0.3 → voidaccess-2.1.0}/extractor/llm_extract.py +55 -5
  44. {voidaccess-2.0.3 → voidaccess-2.1.0}/extractor/ner.py +13 -0
  45. {voidaccess-2.0.3 → voidaccess-2.1.0}/extractor/normalizer.py +18 -98
  46. voidaccess-2.1.0/extractor/org_filter.py +96 -0
  47. {voidaccess-2.0.3 → voidaccess-2.1.0}/extractor/pipeline.py +3 -3
  48. voidaccess-2.1.0/feeds/__init__.py +503 -0
  49. voidaccess-2.1.0/freshness/__init__.py +60 -0
  50. voidaccess-2.1.0/freshness/recrawl.py +216 -0
  51. voidaccess-2.1.0/freshness/scheduler.py +188 -0
  52. {voidaccess-2.0.3 → voidaccess-2.1.0}/graph/builder.py +6 -0
  53. voidaccess-2.1.0/hygiene/__init__.py +119 -0
  54. voidaccess-2.1.0/index_population/__init__.py +45 -0
  55. voidaccess-2.1.0/index_population/seeds.py +286 -0
  56. voidaccess-2.1.0/index_population/usage.py +235 -0
  57. voidaccess-2.1.0/ingest/__init__.py +48 -0
  58. voidaccess-2.1.0/ingest/control.py +45 -0
  59. voidaccess-2.1.0/ingest/keys.py +124 -0
  60. voidaccess-2.1.0/ingest/models.py +92 -0
  61. voidaccess-2.1.0/ingest/service.py +82 -0
  62. voidaccess-2.1.0/jobqueue/__init__.py +51 -0
  63. voidaccess-2.1.0/jobqueue/models.py +101 -0
  64. voidaccess-2.1.0/jobqueue/queue.py +245 -0
  65. voidaccess-2.1.0/jobqueue/worker.py +162 -0
  66. {voidaccess-2.0.3 → voidaccess-2.1.0}/monitor/_db.py +2 -2
  67. {voidaccess-2.0.3 → voidaccess-2.1.0}/monitor/alerts.py +1 -0
  68. {voidaccess-2.0.3 → voidaccess-2.1.0}/monitor/config.py +14 -1
  69. {voidaccess-2.0.3 → voidaccess-2.1.0}/monitor/jobs.py +8 -8
  70. voidaccess-2.1.0/monitor/migration.py +18 -0
  71. {voidaccess-2.0.3 → voidaccess-2.1.0}/monitor/scheduler.py +15 -1
  72. voidaccess-2.1.0/netpool/__init__.py +109 -0
  73. voidaccess-2.1.0/observability/__init__.py +13 -0
  74. voidaccess-2.1.0/observability/corpus_health.py +264 -0
  75. voidaccess-2.1.0/owned_index/__init__.py +72 -0
  76. voidaccess-2.1.0/owned_index/client.py +334 -0
  77. voidaccess-2.1.0/owned_index/index.py +268 -0
  78. voidaccess-2.1.0/owned_index/schema.py +222 -0
  79. voidaccess-2.1.0/progress/__init__.py +493 -0
  80. voidaccess-2.1.0/progress/schema/progress-v2.schema.json +227 -0
  81. voidaccess-2.1.0/progress/trace.py +769 -0
  82. {voidaccess-2.0.3 → voidaccess-2.1.0}/pyproject.toml +31 -3
  83. voidaccess-2.1.0/ratelimit/__init__.py +38 -0
  84. voidaccess-2.1.0/ratelimit/limiter.py +118 -0
  85. voidaccess-2.1.0/sanitizer/__init__.py +38 -0
  86. voidaccess-2.1.0/sanitizer/detectors.py +202 -0
  87. voidaccess-2.1.0/sanitizer/gate.py +99 -0
  88. voidaccess-2.1.0/sanitizer/provenance.py +66 -0
  89. voidaccess-2.1.0/sanitizer/validate.py +35 -0
  90. {voidaccess-2.0.3 → voidaccess-2.1.0}/scraper/scrape.py +153 -51
  91. voidaccess-2.1.0/search/__init__.py +49 -0
  92. {voidaccess-2.0.3 → voidaccess-2.1.0}/search/config.py +26 -0
  93. voidaccess-2.1.0/search/engine_catalog.py +66 -0
  94. voidaccess-2.1.0/search/ranking.py +268 -0
  95. {voidaccess-2.0.3 → voidaccess-2.1.0}/search/search.py +176 -24
  96. voidaccess-2.1.0/search/selection.py +153 -0
  97. {voidaccess-2.0.3 → voidaccess-2.1.0}/search/tor_isolation.py +9 -11
  98. {voidaccess-2.0.3 → voidaccess-2.1.0}/setup.cfg +4 -4
  99. voidaccess-2.1.0/shared_corpus/__init__.py +62 -0
  100. voidaccess-2.1.0/shared_corpus/access.py +701 -0
  101. voidaccess-2.1.0/shared_corpus/consent.py +30 -0
  102. voidaccess-2.1.0/shared_corpus/models.py +413 -0
  103. voidaccess-2.1.0/shared_corpus/promote.py +463 -0
  104. voidaccess-2.1.0/shared_corpus/read.py +422 -0
  105. voidaccess-2.1.0/snapshot_store/__init__.py +39 -0
  106. voidaccess-2.1.0/snapshot_store/s3.py +244 -0
  107. voidaccess-2.1.0/snapshot_store/store.py +203 -0
  108. {voidaccess-2.0.3 → voidaccess-2.1.0}/sources/__init__.py +9 -10
  109. {voidaccess-2.0.3 → voidaccess-2.1.0}/sources/actor_profiles.py +6 -1
  110. {voidaccess-2.0.3 → voidaccess-2.1.0}/sources/blockchain.py +22 -6
  111. {voidaccess-2.0.3 → voidaccess-2.1.0}/sources/breach_lookup.py +29 -6
  112. voidaccess-2.1.0/sources/cache.py +165 -0
  113. {voidaccess-2.0.3 → voidaccess-2.1.0}/sources/cisa.py +23 -6
  114. voidaccess-2.1.0/sources/cve_intel.py +322 -0
  115. voidaccess-2.1.0/sources/data/onion_seeds.json +2205 -0
  116. {voidaccess-2.0.3 → voidaccess-2.1.0}/sources/dns_enrichment.py +49 -14
  117. {voidaccess-2.0.3 → voidaccess-2.1.0}/sources/domain_reputation.py +23 -11
  118. {voidaccess-2.0.3 → voidaccess-2.1.0}/sources/email_reputation.py +24 -7
  119. {voidaccess-2.0.3 → voidaccess-2.1.0}/sources/engines.py +17 -84
  120. {voidaccess-2.0.3 → voidaccess-2.1.0}/sources/enrichment.py +653 -309
  121. voidaccess-2.1.0/sources/enrichment_allowlist.py +143 -0
  122. voidaccess-2.1.0/sources/epss.py +133 -0
  123. voidaccess-2.1.0/sources/exploitdb.py +103 -0
  124. {voidaccess-2.0.3 → voidaccess-2.1.0}/sources/github_scraper.py +4 -0
  125. {voidaccess-2.0.3 → voidaccess-2.1.0}/sources/gitlab_scraper.py +4 -0
  126. {voidaccess-2.0.3 → voidaccess-2.1.0}/sources/hash_reputation.py +38 -11
  127. voidaccess-2.1.0/sources/historical_intel.py +306 -0
  128. voidaccess-2.1.0/sources/http_pool.py +160 -0
  129. {voidaccess-2.0.3 → voidaccess-2.1.0}/sources/infostealer.py +11 -2
  130. {voidaccess-2.0.3 → voidaccess-2.1.0}/sources/ip_reputation.py +27 -8
  131. {voidaccess-2.0.3 → voidaccess-2.1.0}/sources/nvd.py +42 -25
  132. {voidaccess-2.0.3 → voidaccess-2.1.0}/sources/paste_scraper.py +31 -7
  133. {voidaccess-2.0.3 → voidaccess-2.1.0}/sources/proxy_client.py +21 -4
  134. {voidaccess-2.0.3 → voidaccess-2.1.0}/sources/rss_scraper.py +58 -16
  135. {voidaccess-2.0.3 → voidaccess-2.1.0}/sources/shodan.py +14 -3
  136. voidaccess-2.1.0/sources/source_control.py +653 -0
  137. {voidaccess-2.0.3 → voidaccess-2.1.0}/sources/telegram.py +4 -0
  138. {voidaccess-2.0.3 → voidaccess-2.1.0}/sources/virustotal.py +10 -2
  139. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_api.py +40 -29
  140. voidaccess-2.1.0/tests/test_api_monitors.py +24 -0
  141. voidaccess-2.1.0/tests/test_benchmark.py +414 -0
  142. voidaccess-2.1.0/tests/test_cancel_checkpoints.py +574 -0
  143. voidaccess-2.1.0/tests/test_content_safety_parity.py +284 -0
  144. voidaccess-2.1.0/tests/test_corpus_promotion.py +319 -0
  145. voidaccess-2.1.0/tests/test_credential_presence.py +172 -0
  146. voidaccess-2.1.0/tests/test_cve_intel.py +189 -0
  147. voidaccess-2.1.0/tests/test_defang.py +96 -0
  148. voidaccess-2.1.0/tests/test_defang_api_integration.py +105 -0
  149. voidaccess-2.1.0/tests/test_disabled_sources.py +414 -0
  150. voidaccess-2.1.0/tests/test_e5_fetch.py +292 -0
  151. voidaccess-2.1.0/tests/test_e5_org_filter.py +58 -0
  152. voidaccess-2.1.0/tests/test_e5_sources.py +502 -0
  153. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_email_reputation.py +14 -13
  154. voidaccess-2.1.0/tests/test_embedding_backend_health.py +101 -0
  155. voidaccess-2.1.0/tests/test_enrich_deadline.py +293 -0
  156. voidaccess-2.1.0/tests/test_enrichment_allowlist.py +382 -0
  157. voidaccess-2.1.0/tests/test_feeds.py +200 -0
  158. voidaccess-2.1.0/tests/test_freshness.py +388 -0
  159. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_graph.py +2 -1
  160. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_graph_integration.py +10 -0
  161. voidaccess-2.1.0/tests/test_hygiene.py +81 -0
  162. voidaccess-2.1.0/tests/test_index_population.py +378 -0
  163. voidaccess-2.1.0/tests/test_ingest.py +335 -0
  164. voidaccess-2.1.0/tests/test_jobqueue.py +258 -0
  165. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_llm.py +18 -12
  166. voidaccess-2.1.0/tests/test_low_noise_ranking.py +193 -0
  167. voidaccess-2.1.0/tests/test_malwarebazaar_auth.py +63 -0
  168. voidaccess-2.1.0/tests/test_migration_persistence.py +95 -0
  169. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_monitor.py +3 -3
  170. voidaccess-2.1.0/tests/test_multiuser_security.py +225 -0
  171. voidaccess-2.1.0/tests/test_multiuser_upgrade.py +68 -0
  172. voidaccess-2.1.0/tests/test_netpool.py +111 -0
  173. voidaccess-2.1.0/tests/test_observability.py +113 -0
  174. voidaccess-2.1.0/tests/test_owned_index.py +586 -0
  175. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_pacing_quotas.py +7 -0
  176. voidaccess-2.1.0/tests/test_packaging.py +217 -0
  177. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_pagination.py +4 -0
  178. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_priority_score_cli_api_parity.py +66 -0
  179. voidaccess-2.1.0/tests/test_progress.py +209 -0
  180. voidaccess-2.1.0/tests/test_quiet_mode.py +138 -0
  181. voidaccess-2.1.0/tests/test_ratelimit.py +76 -0
  182. voidaccess-2.1.0/tests/test_redteam_moat.py +245 -0
  183. voidaccess-2.1.0/tests/test_sanitizer.py +180 -0
  184. voidaccess-2.1.0/tests/test_search_consolidation.py +117 -0
  185. voidaccess-2.1.0/tests/test_search_ranking.py +183 -0
  186. voidaccess-2.1.0/tests/test_shared_corpus.py +304 -0
  187. voidaccess-2.1.0/tests/test_shared_read.py +284 -0
  188. voidaccess-2.1.0/tests/test_snapshot_store.py +324 -0
  189. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_sources.py +9 -132
  190. voidaccess-2.1.0/tests/test_sources_status.py +360 -0
  191. voidaccess-2.1.0/tests/test_speed_controls.py +146 -0
  192. voidaccess-2.1.0/tests/test_summary_fallback.py +284 -0
  193. voidaccess-2.1.0/tests/test_temporal_regression.py +76 -0
  194. voidaccess-2.1.0/tests/test_token_blacklist.py +55 -0
  195. voidaccess-2.1.0/tests/test_trace_events.py +924 -0
  196. voidaccess-2.1.0/tests/test_trust_gate.py +404 -0
  197. voidaccess-2.1.0/trust_gate/__init__.py +62 -0
  198. voidaccess-2.1.0/trust_gate/anomaly.py +94 -0
  199. voidaccess-2.1.0/trust_gate/gate.py +476 -0
  200. voidaccess-2.1.0/trust_gate/model.py +334 -0
  201. voidaccess-2.1.0/trust_gate/thresholds.py +99 -0
  202. voidaccess-2.1.0/utils/cancel.py +207 -0
  203. {voidaccess-2.0.3 → voidaccess-2.1.0}/utils/content_safety.py +153 -1
  204. voidaccess-2.1.0/utils/defang.py +142 -0
  205. voidaccess-2.1.0/utils/entity_priority.py +360 -0
  206. {voidaccess-2.0.3 → voidaccess-2.1.0}/utils/investigation_metrics.py +15 -0
  207. voidaccess-2.1.0/vector/model_singleton.py +161 -0
  208. {voidaccess-2.0.3 → voidaccess-2.1.0}/vector/search.py +8 -6
  209. {voidaccess-2.0.3 → voidaccess-2.1.0}/vector/store.py +47 -2
  210. {voidaccess-2.0.3 → voidaccess-2.1.0}/voidaccess/llm.py +946 -904
  211. voidaccess-2.1.0/voidaccess/summary_fallback.py +168 -0
  212. {voidaccess-2.0.3 → voidaccess-2.1.0/voidaccess.egg-info}/PKG-INFO +243 -242
  213. {voidaccess-2.0.3 → voidaccess-2.1.0}/voidaccess.egg-info/SOURCES.txt +133 -0
  214. {voidaccess-2.0.3 → voidaccess-2.1.0}/voidaccess.egg-info/requires.txt +2 -1
  215. voidaccess-2.1.0/voidaccess.egg-info/top_level.txt +38 -0
  216. {voidaccess-2.0.3 → voidaccess-2.1.0}/voidaccess_cli/__init__.py +1 -1
  217. {voidaccess-2.0.3 → voidaccess-2.1.0}/voidaccess_cli/adapters/sqlite.py +78 -3
  218. voidaccess-2.1.0/voidaccess_cli/commands/admin.py +16 -0
  219. voidaccess-2.1.0/voidaccess_cli/commands/benchmark.py +73 -0
  220. {voidaccess-2.0.3 → voidaccess-2.1.0}/voidaccess_cli/commands/investigate.py +1177 -283
  221. {voidaccess-2.0.3 → voidaccess-2.1.0}/voidaccess_cli/display.py +36 -5
  222. {voidaccess-2.0.3 → voidaccess-2.1.0}/voidaccess_cli/main.py +25 -2
  223. voidaccess-2.1.0/voidaccess_cli/reporter.py +53 -0
  224. voidaccess-2.0.3/api/routes/monitors.py +0 -404
  225. voidaccess-2.0.3/auth/token_blacklist.py +0 -140
  226. voidaccess-2.0.3/config.py +0 -251
  227. voidaccess-2.0.3/search/__init__.py +0 -392
  228. voidaccess-2.0.3/search/engine_catalog.py +0 -30
  229. voidaccess-2.0.3/sources/cache.py +0 -92
  230. voidaccess-2.0.3/sources/data/onion_seeds.json +0 -523
  231. voidaccess-2.0.3/sources/historical_intel.py +0 -262
  232. voidaccess-2.0.3/tests/test_api_monitors.py +0 -127
  233. voidaccess-2.0.3/utils/defang.py +0 -94
  234. voidaccess-2.0.3/utils/entity_priority.py +0 -189
  235. voidaccess-2.0.3/vector/model_singleton.py +0 -92
  236. voidaccess-2.0.3/voidaccess.egg-info/top_level.txt +0 -21
  237. {voidaccess-2.0.3 → voidaccess-2.1.0}/LICENSE +0 -0
  238. {voidaccess-2.0.3 → voidaccess-2.1.0}/README.md +0 -0
  239. {voidaccess-2.0.3 → voidaccess-2.1.0}/alembic.ini +0 -0
  240. {voidaccess-2.0.3 → voidaccess-2.1.0}/analysis/__init__.py +0 -0
  241. {voidaccess-2.0.3 → voidaccess-2.1.0}/analysis/opsec.py +0 -0
  242. {voidaccess-2.0.3 → voidaccess-2.1.0}/analysis/patterns.py +0 -0
  243. {voidaccess-2.0.3 → voidaccess-2.1.0}/analysis/temporal.py +0 -0
  244. {voidaccess-2.0.3 → voidaccess-2.1.0}/api/__init__.py +0 -0
  245. {voidaccess-2.0.3 → voidaccess-2.1.0}/api/errors.py +0 -0
  246. {voidaccess-2.0.3 → voidaccess-2.1.0}/api/routes/__init__.py +0 -0
  247. {voidaccess-2.0.3 → voidaccess-2.1.0}/api/routes/settings.py +0 -0
  248. {voidaccess-2.0.3 → voidaccess-2.1.0}/auth/__init__.py +0 -0
  249. {voidaccess-2.0.3 → voidaccess-2.1.0}/crawler/__init__.py +0 -0
  250. {voidaccess-2.0.3 → voidaccess-2.1.0}/crawler/dedup.py +0 -0
  251. {voidaccess-2.0.3 → voidaccess-2.1.0}/crawler/frontier.py +0 -0
  252. {voidaccess-2.0.3 → voidaccess-2.1.0}/crawler/spider.py +0 -0
  253. {voidaccess-2.0.3 → voidaccess-2.1.0}/crawler/utils.py +0 -0
  254. {voidaccess-2.0.3 → voidaccess-2.1.0}/data/__init__.py +0 -0
  255. {voidaccess-2.0.3 → voidaccess-2.1.0}/data/common_words_en.txt +0 -0
  256. {voidaccess-2.0.3 → voidaccess-2.1.0}/data/domain_stopwords_en.txt +0 -0
  257. {voidaccess-2.0.3 → voidaccess-2.1.0}/data/monitors.yaml +0 -0
  258. {voidaccess-2.0.3 → voidaccess-2.1.0}/data/seed_data.json.gz +0 -0
  259. {voidaccess-2.0.3 → voidaccess-2.1.0}/data/threat_gazetteer.json +0 -0
  260. {voidaccess-2.0.3 → voidaccess-2.1.0}/db/__init__.py +0 -0
  261. {voidaccess-2.0.3 → voidaccess-2.1.0}/db/migrations/__init__.py +0 -0
  262. {voidaccess-2.0.3 → voidaccess-2.1.0}/db/migrations/versions/0001_initial_schema.py +0 -0
  263. {voidaccess-2.0.3 → voidaccess-2.1.0}/db/migrations/versions/0002_add_investigation_status_column.py +0 -0
  264. {voidaccess-2.0.3 → voidaccess-2.1.0}/db/migrations/versions/0002_add_missing_tables.py +0 -0
  265. {voidaccess-2.0.3 → voidaccess-2.1.0}/db/migrations/versions/0003_add_canonical_value_and_entity_links.py +0 -0
  266. {voidaccess-2.0.3 → voidaccess-2.1.0}/db/migrations/versions/0004_add_page_posted_at.py +0 -0
  267. {voidaccess-2.0.3 → voidaccess-2.1.0}/db/migrations/versions/0005_add_extraction_method.py +0 -0
  268. {voidaccess-2.0.3 → voidaccess-2.1.0}/db/migrations/versions/0006_add_monitor_alerts.py +0 -0
  269. {voidaccess-2.0.3 → voidaccess-2.1.0}/db/migrations/versions/0007_add_actor_style_profiles.py +0 -0
  270. {voidaccess-2.0.3 → voidaccess-2.1.0}/db/migrations/versions/0008_add_users_table.py +0 -0
  271. {voidaccess-2.0.3 → voidaccess-2.1.0}/db/migrations/versions/0009_add_investigation_id_to_relationships.py +0 -0
  272. {voidaccess-2.0.3 → voidaccess-2.1.0}/db/migrations/versions/0010_add_composite_index_entity_relationships.py +0 -0
  273. {voidaccess-2.0.3 → voidaccess-2.1.0}/db/migrations/versions/0011_add_page_extraction_cache.py +0 -0
  274. {voidaccess-2.0.3 → voidaccess-2.1.0}/db/migrations/versions/0013_add_graph_status.py +0 -0
  275. {voidaccess-2.0.3 → voidaccess-2.1.0}/db/migrations/versions/0015_add_progress_fields.py +0 -0
  276. {voidaccess-2.0.3 → voidaccess-2.1.0}/db/migrations/versions/0016_backfill_graph_status.py +0 -0
  277. {voidaccess-2.0.3 → voidaccess-2.1.0}/db/migrations/versions/0017_add_user_api_keys.py +0 -0
  278. {voidaccess-2.0.3 → voidaccess-2.1.0}/db/migrations/versions/0018_add_user_id_to_investigations.py +0 -0
  279. {voidaccess-2.0.3 → voidaccess-2.1.0}/db/migrations/versions/0019_add_content_safety_log.py +0 -0
  280. {voidaccess-2.0.3 → voidaccess-2.1.0}/db/migrations/versions/0020_add_entity_source_tracking.py +0 -0
  281. {voidaccess-2.0.3 → voidaccess-2.1.0}/db/migrations/versions/0021_add_search_engine_stats.py +0 -0
  282. {voidaccess-2.0.3 → voidaccess-2.1.0}/db/migrations/versions/0022_add_actor_profiles.py +0 -0
  283. {voidaccess-2.0.3 → voidaccess-2.1.0}/db/migrations/versions/0023_add_investigation_metadata.py +0 -0
  284. {voidaccess-2.0.3 → voidaccess-2.1.0}/db/migrations/versions/0024_add_investigation_step_metrics.py +0 -0
  285. {voidaccess-2.0.3 → voidaccess-2.1.0}/db/migrations/versions/0025_add_cancellation_requested.py +0 -0
  286. {voidaccess-2.0.3 → voidaccess-2.1.0}/db/migrations/versions/0026_add_entity_investigation_count.py +0 -0
  287. {voidaccess-2.0.3 → voidaccess-2.1.0}/db/search_engine_stats.py +0 -0
  288. {voidaccess-2.0.3 → voidaccess-2.1.0}/export/__init__.py +0 -0
  289. {voidaccess-2.0.3 → voidaccess-2.1.0}/export/_entity_loading.py +0 -0
  290. {voidaccess-2.0.3 → voidaccess-2.1.0}/export/misp.py +0 -0
  291. {voidaccess-2.0.3 → voidaccess-2.1.0}/export/relationships.py +0 -0
  292. {voidaccess-2.0.3 → voidaccess-2.1.0}/export/sigma.py +0 -0
  293. {voidaccess-2.0.3 → voidaccess-2.1.0}/export/snort_export.py +0 -0
  294. {voidaccess-2.0.3 → voidaccess-2.1.0}/export/yara_export.py +0 -0
  295. {voidaccess-2.0.3 → voidaccess-2.1.0}/extractor/__init__.py +0 -0
  296. {voidaccess-2.0.3 → voidaccess-2.1.0}/extractor/confidence.py +0 -0
  297. {voidaccess-2.0.3 → voidaccess-2.1.0}/extractor/dependency_relationship.py +0 -0
  298. {voidaccess-2.0.3 → voidaccess-2.1.0}/extractor/entity_shape.py +0 -0
  299. {voidaccess-2.0.3 → voidaccess-2.1.0}/extractor/gazetteer.py +0 -0
  300. {voidaccess-2.0.3 → voidaccess-2.1.0}/extractor/identity.py +0 -0
  301. {voidaccess-2.0.3 → voidaccess-2.1.0}/extractor/regex_patterns.py +0 -0
  302. {voidaccess-2.0.3 → voidaccess-2.1.0}/extractor/relationship_extract.py +0 -0
  303. {voidaccess-2.0.3 → voidaccess-2.1.0}/extractor/software_suppression.py +0 -0
  304. {voidaccess-2.0.3 → voidaccess-2.1.0}/fingerprint/__init__.py +0 -0
  305. {voidaccess-2.0.3 → voidaccess-2.1.0}/fingerprint/calibration.py +0 -0
  306. {voidaccess-2.0.3 → voidaccess-2.1.0}/fingerprint/profiler.py +0 -0
  307. {voidaccess-2.0.3 → voidaccess-2.1.0}/fingerprint/stylometry.py +0 -0
  308. {voidaccess-2.0.3 → voidaccess-2.1.0}/graph/__init__.py +0 -0
  309. {voidaccess-2.0.3 → voidaccess-2.1.0}/graph/export.py +0 -0
  310. {voidaccess-2.0.3 → voidaccess-2.1.0}/graph/model.py +0 -0
  311. {voidaccess-2.0.3 → voidaccess-2.1.0}/graph/queries.py +0 -0
  312. {voidaccess-2.0.3 → voidaccess-2.1.0}/graph/visualize.py +0 -0
  313. {voidaccess-2.0.3 → voidaccess-2.1.0}/i18n/__init__.py +0 -0
  314. {voidaccess-2.0.3 → voidaccess-2.1.0}/i18n/detect.py +0 -0
  315. {voidaccess-2.0.3 → voidaccess-2.1.0}/i18n/query_expand.py +0 -0
  316. {voidaccess-2.0.3 → voidaccess-2.1.0}/i18n/translate.py +0 -0
  317. {voidaccess-2.0.3 → voidaccess-2.1.0}/monitor/__init__.py +0 -0
  318. {voidaccess-2.0.3 → voidaccess-2.1.0}/monitor/diff.py +0 -0
  319. {voidaccess-2.0.3 → voidaccess-2.1.0}/pacing/__init__.py +0 -0
  320. {voidaccess-2.0.3 → voidaccess-2.1.0}/scraper/__init__.py +0 -0
  321. {voidaccess-2.0.3 → voidaccess-2.1.0}/scraper/scrape_js.py +0 -0
  322. {voidaccess-2.0.3 → voidaccess-2.1.0}/scraper/tor_pool.py +0 -0
  323. {voidaccess-2.0.3 → voidaccess-2.1.0}/search/circuit_breaker.py +0 -0
  324. {voidaccess-2.0.3 → voidaccess-2.1.0}/search/query_builder.py +0 -0
  325. {voidaccess-2.0.3 → voidaccess-2.1.0}/sources/data/__init__.py +0 -0
  326. {voidaccess-2.0.3 → voidaccess-2.1.0}/sources/pastes.py +0 -0
  327. {voidaccess-2.0.3 → voidaccess-2.1.0}/sources/seed_manager.py +0 -0
  328. {voidaccess-2.0.3 → voidaccess-2.1.0}/sources/seeds.py +0 -0
  329. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_actor_extraction_gap.py +0 -0
  330. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_analysis_opsec.py +0 -0
  331. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_analysis_stylometry.py +0 -0
  332. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_analysis_temporal.py +0 -0
  333. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_blockchain.py +0 -0
  334. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_breach_lookup.py +0 -0
  335. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_cli_manifest.py +0 -0
  336. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_cli_proxy_config.py +0 -0
  337. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_community_detection_parity.py +0 -0
  338. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_confidence_calibration.py +0 -0
  339. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_config.py +0 -0
  340. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_consolidated_contracts.py +0 -0
  341. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_crawler.py +0 -0
  342. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_db.py +0 -0
  343. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_dependency_relationship.py +0 -0
  344. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_dns_enrichment.py +0 -0
  345. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_domain_reputation.py +0 -0
  346. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_entity_priority.py +0 -0
  347. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_extractor_llm_pipeline.py +0 -0
  348. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_filter_e2e_manual.py +0 -0
  349. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_filter_parser_manual.py +0 -0
  350. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_fingerprint.py +0 -0
  351. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_gazetteer.py +0 -0
  352. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_github_scraper.py +0 -0
  353. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_gitlab_scraper.py +0 -0
  354. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_hash_reputation.py +0 -0
  355. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_heuristic_expansion.py +0 -0
  356. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_i18n.py +0 -0
  357. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_infostealer.py +0 -0
  358. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_ioc_package_export.py +0 -0
  359. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_ip_reputation.py +0 -0
  360. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_legacy_backfill.py +0 -0
  361. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_llm_utils.py +0 -0
  362. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_model_singleton.py +0 -0
  363. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_monitor_integration.py +0 -0
  364. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_nvd.py +0 -0
  365. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_pacing.py +0 -0
  366. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_pacing_enrichment.py +0 -0
  367. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_paste_scraper.py +0 -0
  368. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_proxy_client.py +0 -0
  369. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_ransomlook.py +0 -0
  370. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_regex_patterns.py +0 -0
  371. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_relationship_extract.py +0 -0
  372. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_requirement_bugs.py +0 -0
  373. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_rss_scraper.py +0 -0
  374. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_scrape_isolation.py +0 -0
  375. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_scrape_js.py +0 -0
  376. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_settings.py +0 -0
  377. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_sigma_export.py +0 -0
  378. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_snort_export.py +0 -0
  379. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_software_suppression.py +0 -0
  380. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_sources_enrichment_new.py +0 -0
  381. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_stix_export.py +0 -0
  382. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_vector.py +0 -0
  383. {voidaccess-2.0.3 → voidaccess-2.1.0}/tests/test_yara_export.py +0 -0
  384. {voidaccess-2.0.3 → voidaccess-2.1.0}/utils/__init__.py +0 -0
  385. {voidaccess-2.0.3 → voidaccess-2.1.0}/utils/async_utils.py +0 -0
  386. {voidaccess-2.0.3 → voidaccess-2.1.0}/utils/content_dedup.py +0 -0
  387. {voidaccess-2.0.3 → voidaccess-2.1.0}/utils/encryption.py +0 -0
  388. {voidaccess-2.0.3 → voidaccess-2.1.0}/utils/enrichment_cache.py +0 -0
  389. {voidaccess-2.0.3 → voidaccess-2.1.0}/utils/ioc_freshness.py +0 -0
  390. {voidaccess-2.0.3 → voidaccess-2.1.0}/utils/user_keys.py +0 -0
  391. {voidaccess-2.0.3 → voidaccess-2.1.0}/vector/__init__.py +0 -0
  392. {voidaccess-2.0.3 → voidaccess-2.1.0}/vector/embedder.py +0 -0
  393. {voidaccess-2.0.3 → voidaccess-2.1.0}/voidaccess/__init__.py +0 -0
  394. {voidaccess-2.0.3 → voidaccess-2.1.0}/voidaccess/backfill.py +0 -0
  395. {voidaccess-2.0.3 → voidaccess-2.1.0}/voidaccess/config.py +0 -0
  396. {voidaccess-2.0.3 → voidaccess-2.1.0}/voidaccess/llm_utils.py +0 -0
  397. {voidaccess-2.0.3 → voidaccess-2.1.0}/voidaccess.egg-info/dependency_links.txt +0 -0
  398. {voidaccess-2.0.3 → voidaccess-2.1.0}/voidaccess.egg-info/entry_points.txt +0 -0
  399. {voidaccess-2.0.3 → voidaccess-2.1.0}/voidaccess_cli/adapters/__init__.py +0 -0
  400. {voidaccess-2.0.3 → voidaccess-2.1.0}/voidaccess_cli/browser.py +0 -0
  401. {voidaccess-2.0.3 → voidaccess-2.1.0}/voidaccess_cli/commands/__init__.py +0 -0
  402. {voidaccess-2.0.3 → voidaccess-2.1.0}/voidaccess_cli/commands/actors.py +0 -0
  403. {voidaccess-2.0.3 → voidaccess-2.1.0}/voidaccess_cli/commands/configure.py +0 -0
  404. {voidaccess-2.0.3 → voidaccess-2.1.0}/voidaccess_cli/commands/enrich.py +0 -0
  405. {voidaccess-2.0.3 → voidaccess-2.1.0}/voidaccess_cli/commands/export.py +0 -0
  406. {voidaccess-2.0.3 → voidaccess-2.1.0}/voidaccess_cli/commands/show.py +0 -0
  407. {voidaccess-2.0.3 → voidaccess-2.1.0}/voidaccess_cli/config.py +0 -0
  408. {voidaccess-2.0.3 → voidaccess-2.1.0}/voidaccess_cli/tor_detect.py +0 -0
@@ -1,242 +1,243 @@
1
- Metadata-Version: 2.4
2
- Name: voidaccess
3
- Version: 2.0.3
4
- Summary: Dark web OSINT CLI — automated threat intelligence from query to report
5
- Author: VoidAccess
6
- License-Expression: MIT
7
- Keywords: osint,darkweb,threat-intelligence,tor,cli
8
- Classifier: Development Status :: 4 - Beta
9
- Classifier: Environment :: Console
10
- Classifier: Intended Audience :: Information Technology
11
- Classifier: Operating System :: OS Independent
12
- Classifier: Programming Language :: Python :: 3
13
- Classifier: Programming Language :: Python :: 3.11
14
- Classifier: Programming Language :: Python :: 3.12
15
- Classifier: Topic :: Security
16
- Requires-Python: >=3.10
17
- Description-Content-Type: text/markdown
18
- License-File: LICENSE
19
- Requires-Dist: typer==0.24.1
20
- Requires-Dist: rich==15.0.0
21
- Requires-Dist: textual==8.2.7
22
- Requires-Dist: click==8.3.2
23
- Requires-Dist: fastapi==0.136.0
24
- Requires-Dist: aiohttp==3.13.5
25
- Requires-Dist: aiohttp-socks==0.11.0
26
- Requires-Dist: alembic==1.18.4
27
- Requires-Dist: apscheduler==3.11.2
28
- Requires-Dist: pillow==12.2.0
29
- Requires-Dist: sqlalchemy[asyncio]==2.0.49
30
- Requires-Dist: aiosqlite==0.22.1
31
- Requires-Dist: filelock==3.29.0
32
- Requires-Dist: numpy==2.2.6
33
- Requires-Dist: langchain==0.3.25
34
- Requires-Dist: langchain-openai==0.3.19
35
- Requires-Dist: langchain-anthropic==0.3.22
36
- Requires-Dist: langchain-google-genai==2.1.12
37
- Requires-Dist: langchain-groq==0.3.8
38
- Requires-Dist: langchain-ollama==0.3.10
39
- Requires-Dist: python-dotenv==1.2.2
40
- Requires-Dist: httpx==0.28.1
41
- Requires-Dist: spacy==3.8.14
42
- Requires-Dist: beautifulsoup4==4.14.3
43
- Requires-Dist: feedparser==6.0.11
44
- Requires-Dist: networkx==3.4.2
45
- Requires-Dist: pydantic==2.13.3
46
- Requires-Dist: python-jose[cryptography]==3.5.0
47
- Requires-Dist: passlib[bcrypt]==1.7.4
48
- Requires-Dist: bcrypt<4.1,>=3.1.0
49
- Requires-Dist: slowapi==0.1.9
50
- Requires-Dist: redis==7.4.0
51
- Requires-Dist: pyyaml==6.0.3
52
- Requires-Dist: openai==1.109.1
53
- Requires-Dist: cryptography==46.0.7
54
- Requires-Dist: python-dateutil==2.9.0.post0
55
- Requires-Dist: langdetect==1.0.9
56
- Requires-Dist: pyvis==0.3.2
57
- Requires-Dist: urllib3==2.6.3
58
- Requires-Dist: trafilatura==2.0.0
59
- Requires-Dist: lxml_html_clean>=0.4.2
60
- Requires-Dist: requests==2.33.1
61
- Requires-Dist: python-socks[asyncio]==2.8.1
62
- Requires-Dist: tldextract==5.3.1
63
- Requires-Dist: stix2==3.0.2
64
- Provides-Extra: dev
65
- Requires-Dist: pytest; extra == "dev"
66
- Requires-Dist: pytest-asyncio; extra == "dev"
67
- Requires-Dist: aioresponses>=0.7.6; extra == "dev"
68
- Provides-Extra: nlp
69
- Requires-Dist: sentence-transformers>=3.0; extra == "nlp"
70
- Requires-Dist: torch>=2.3; extra == "nlp"
71
- Requires-Dist: transformers>=4.42; extra == "nlp"
72
- Provides-Extra: vector
73
- Requires-Dist: chromadb>=0.5; extra == "vector"
74
- Requires-Dist: sentence-transformers>=3.0; extra == "vector"
75
- Requires-Dist: torch>=2.3; extra == "vector"
76
- Provides-Extra: telegram
77
- Requires-Dist: telethon>=1.36; extra == "telegram"
78
- Provides-Extra: js
79
- Requires-Dist: playwright>=1.45; extra == "js"
80
- Provides-Extra: all
81
- Requires-Dist: chromadb>=0.5; extra == "all"
82
- Requires-Dist: playwright>=1.45; extra == "all"
83
- Requires-Dist: sentence-transformers>=3.0; extra == "all"
84
- Requires-Dist: telethon>=1.36; extra == "all"
85
- Requires-Dist: torch>=2.3; extra == "all"
86
- Requires-Dist: transformers>=4.42; extra == "all"
87
- Dynamic: license-file
88
-
89
- <p align="center">
90
- <img src="public/logo_circle.png" width="160" alt="VoidAccess logo">
91
- </p>
92
-
93
- <h1 align="center">VoidAccess</h1>
94
-
95
- <p align="center">
96
- <a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="License: MIT"></a>
97
- <a href="https://www.python.org/"><img src="https://img.shields.io/badge/Python-3.10%2B-blue.svg" alt="Python 3.10+"></a>
98
- <a href="docker-compose.yml"><img src="https://img.shields.io/badge/Docker-Compose-blue.svg" alt="Docker Compose"></a>
99
- <a href="https://pypi.org/project/voidaccess/"><img src="https://img.shields.io/pypi/v/voidaccess?logo=pypi&logoColor=white" alt="PyPI version"></a>
100
- <a href="https://pypi.org/project/voidaccess/"><img src="https://img.shields.io/pypi/dm/voidaccess" alt="PyPI downloads"></a>
101
- </p>
102
-
103
- Self-hostable OSINT for turning dark-web research queries into structured threat intelligence. Built for security researchers, threat-intelligence teams, and authorized investigators who need collection, enrichment, relationship mapping, and export in one workflow.
104
-
105
- ## Terminal Output
106
-
107
- ![VoidAccess](public/terminal-hero.png)
108
-
109
- ## Quick Start
110
-
111
- ```bash
112
- pip install voidaccess
113
- voidaccess investigate "LockBit ransomware" --no-llm --no-tor --depth shallow
114
- voidaccess list
115
- voidaccess actors
116
- voidaccess status
117
- ```
118
-
119
- ![VoidAccess investigation demo](public/cli_investigation_gif.gif)
120
-
121
- ## What It Does
122
-
123
- - **Parallel collection** - searches Tor indexes, paste sites, code forges, security feeds, and curated `.onion` seeds.
124
- - **Entity extraction** - finds IOCs, wallets, credentials, handles, vulnerabilities, actors, malware, people, and organizations.
125
- - **Multi-source enrichment** - adds reputation, breach, passive DNS, sandbox, blockchain, and threat-feed context.
126
- - **Actor intelligence** - persists aliases, infrastructure, notes, timelines, and cross-investigation relationships.
127
- - **Relationship graphs** - builds co-occurrence graphs, communities, paths, and infrastructure clusters.
128
- - **Content safety** - filters prohibited queries, URLs, content, and extracted entities at mandatory pipeline gates.
129
- - **Structured exports** - produces STIX 2.1, MISP, Sigma, YARA, Snort, Suricata, CSV, Markdown, JSON, and IOC packages.
130
- - **CLI and web UI** - runs locally with SQLite or as a Docker Compose stack with PostgreSQL and a browser interface.
131
-
132
- ## Pipeline
133
-
134
- | Stage | Action |
135
- |---|---|
136
- | 1 | Refine the investigation query with the selected LLM |
137
- | 2 | Collect from Tor search, paste sites, code forges, RSS feeds, and curated seeds in parallel |
138
- | 3 | Filter noisy or irrelevant pages |
139
- | 4 | Enrich the query and early indicators from threat-intelligence sources |
140
- | 5 | Discover additional `.onion` links recursively |
141
- | 6 | Reuse recently processed pages from the vector cache |
142
- | 7 | Fetch selected pages through Tor with response-size limits |
143
- | 8 | Persist newly collected content |
144
- | 9 | Merge collected and enriched intelligence |
145
- | 10 | Extract entities with regex, NER, and optional LLM analysis |
146
- | 11 | Cross-reference entities against historical and seed datasets |
147
- | 12 | Build relationships, communities, and infrastructure clusters |
148
- | 13 | Generate the final intelligence summary and export-ready result |
149
-
150
- Full pipeline behavior, timeouts, recovery, and data flow are documented in [Architecture](docs/architecture.md).
151
-
152
- ## Entity Types
153
-
154
- | Category | Examples |
155
- |---|---|
156
- | Cryptocurrency | Bitcoin, Ethereum, Monero, Litecoin, Zcash, Solana, Tron, ENS |
157
- | Network indicators | IPv4, IPv6, domains, URLs, `.onion` addresses, MAC addresses, PGP keys |
158
- | File indicators | MD5, SHA-1, SHA-256, malware families |
159
- | Credentials | Cloud keys, tokens, JWTs, API keys, stealer logs, combo-list entries |
160
- | Messaging | Telegram, Discord, XMPP, Tox, Session, Matrix, Wire, ICQ, Wickr |
161
- | Vulnerabilities | CVEs, MITRE ATT&CK techniques and tactics, Exploit-DB IDs |
162
- | Detection content | YARA rules, Nuclei templates, Snort and Suricata indicators |
163
- | Threat intelligence | Actor handles, ransomware groups, paste links, people, organizations, locations |
164
-
165
- ## Collection and Enrichment
166
-
167
- | Layer | Sources |
168
- |---|---|
169
- | Dark-web search | 16+ Tor search engines and curated `.onion` seeds |
170
- | Open-web collection | Pastebin, dpaste, paste.ee, Rentry, GitHub, GitLab, and curated RSS feeds |
171
- | Threat feeds | AlienVault OTX, abuse.ch, MalwareBazaar, ThreatFox, URLhaus, ransomware.live, CISA KEV |
172
- | IP and domain context | Shodan InternetDB, GreyNoise, AbuseIPDB, Feodo Tracker, C2IntelFeeds, crt.sh, URLScan.io, Wayback Machine, CIRCL PDNS, RDAP |
173
- | File and identity context | VirusTotal, Hybrid Analysis, Have I Been Pwned, EmailRep |
174
- | Blockchain | BlockCypher and Etherscan |
175
-
176
- Sources that need API keys skip cleanly when their keys are absent. The complete key and configuration reference is in [Architecture](docs/architecture.md#13-configuration-reference).
177
-
178
- ### Optional vector embeddings
179
-
180
- The default installation can run without PyTorch. When the embedding stack is
181
- unavailable, VoidAccess logs that it is using a deterministic SHA-256 fallback
182
- encoder. Install the optional NLP dependencies to enable full
183
- sentence-transformer vector embeddings:
184
-
185
- ```bash
186
- pip install "voidaccess[nlp]"
187
- ```
188
-
189
- ## LLM Providers
190
-
191
- | Provider | Typical models | Notes |
192
- |---|---|---|
193
- | OpenRouter | DeepSeek, Llama, Claude | Default route; free models are available |
194
- | Groq | Llama | Fast hosted inference with a free tier |
195
- | OpenAI | GPT models | API key required |
196
- | Anthropic | Claude | Claude Haiku is the tested default |
197
- | Google Gemini | Gemini Flash and Pro | Google AI Studio key required |
198
- | Ollama | Any installed local model | Local and suitable for air-gapped deployments |
199
-
200
- ## CLI Reference
201
-
202
- | Command | Description |
203
- |---------|-------------|
204
- | `voidaccess investigate "QUERY"` | Run an investigation |
205
- | `voidaccess show` | Open the interactive entity browser |
206
- | `voidaccess export INVESTIGATION_ID --format FORMAT` | Export as STIX, MISP, Sigma, YARA, Snort, Suricata, package, CSV, Markdown, or JSON |
207
- | `voidaccess package INVESTIGATION_ID` | Build an IOC package ZIP |
208
- | `voidaccess enrich INVESTIGATION_ID` | Re-enrich a saved investigation |
209
- | `voidaccess list` | List saved investigations |
210
- | `voidaccess status` | Show configuration, Tor, cache, engine, and seed status |
211
- | `voidaccess actors` | List persistent actor profiles |
212
- | `voidaccess actor HANDLE` | Show an actor profile |
213
- | `voidaccess actor HANDLE --timeline` | Show an actor activity timeline |
214
- | `voidaccess actor HANDLE --note "TEXT"` | Add an analyst note to an actor profile |
215
- | `voidaccess timeline HANDLE` | Open an actor timeline directly |
216
- | `voidaccess configure` | Run the setup wizard |
217
- | `voidaccess configure llm` | Configure the LLM provider, model, and key |
218
- | `voidaccess configure keys` | Configure enrichment API keys |
219
- | `voidaccess configure tor` | Override the Tor proxy host and port |
220
- | `voidaccess version` | Print the installed version |
221
-
222
- Optional clearnet requests can use [ScrapingAnt](https://scrapingant.com/?ref=mzliyzh) with `--use-scraping-api` or `--use-proxies`; Tor, `.onion`, GitHub, and GitLab traffic are unaffected.
223
-
224
- ## Self-Hosting
225
-
226
- Run the full PostgreSQL, Tor, FastAPI, and Next.js stack with Docker Compose. The [self-hosting guide](docs/self-hosting.md) covers guided setup, environment configuration, operations, and troubleshooting.
227
-
228
- ## Links
229
-
230
- | | |
231
- |-|-|
232
- | [Self-hosting guide](docs/self-hosting.md) | Docker Compose, environment setup, operations, and troubleshooting |
233
- | [Architecture](docs/architecture.md) | Pipeline internals, modules, schema, API, enrichment, graph, and configuration reference |
234
- | [Contributing](CONTRIBUTING.md) | Development setup, standards, and pull requests |
235
- | [Security](SECURITY.md) | Supported versions and private vulnerability reporting |
236
- | [Usage policy](docs/USAGE_POLICY.md) | Authorized-use requirements and prohibited activity |
237
- | [PyPI](https://pypi.org/project/voidaccess/) | Published package and release files |
238
- | [GitHub](https://github.com/KatrielMoses/VoidAccess) | Source, issues, and releases |
239
-
240
- ## License
241
-
242
- MIT. Use VoidAccess only for authorized security research and threat-intelligence work; see the [Usage Policy](docs/USAGE_POLICY.md).
1
+ Metadata-Version: 2.4
2
+ Name: voidaccess
3
+ Version: 2.1.0
4
+ Summary: Dark web OSINT CLI — automated threat intelligence from query to report
5
+ Author: VoidAccess
6
+ License-Expression: MIT
7
+ Keywords: osint,darkweb,threat-intelligence,tor,cli
8
+ Classifier: Development Status :: 4 - Beta
9
+ Classifier: Environment :: Console
10
+ Classifier: Intended Audience :: Information Technology
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Topic :: Security
16
+ Requires-Python: >=3.10
17
+ Description-Content-Type: text/markdown
18
+ License-File: LICENSE
19
+ Requires-Dist: typer==0.24.1
20
+ Requires-Dist: rich==15.0.0
21
+ Requires-Dist: textual==8.2.7
22
+ Requires-Dist: click==8.3.2
23
+ Requires-Dist: fastapi==0.136.0
24
+ Requires-Dist: aiohttp==3.13.5
25
+ Requires-Dist: aiohttp-socks==0.11.0
26
+ Requires-Dist: alembic==1.18.4
27
+ Requires-Dist: apscheduler==3.11.2
28
+ Requires-Dist: pillow==12.2.0
29
+ Requires-Dist: sqlalchemy[asyncio]==2.0.49
30
+ Requires-Dist: aiosqlite==0.22.1
31
+ Requires-Dist: filelock==3.29.0
32
+ Requires-Dist: numpy<2,>=1.26
33
+ Requires-Dist: langchain==0.3.25
34
+ Requires-Dist: langchain-openai==0.3.19
35
+ Requires-Dist: langchain-anthropic==0.3.22
36
+ Requires-Dist: langchain-google-genai==2.1.12
37
+ Requires-Dist: langchain-groq==0.3.8
38
+ Requires-Dist: langchain-ollama==0.3.10
39
+ Requires-Dist: python-dotenv==1.2.2
40
+ Requires-Dist: httpx==0.28.1
41
+ Requires-Dist: spacy==3.8.14
42
+ Requires-Dist: beautifulsoup4==4.14.3
43
+ Requires-Dist: feedparser==6.0.11
44
+ Requires-Dist: networkx==3.4.2
45
+ Requires-Dist: pydantic==2.13.3
46
+ Requires-Dist: python-jose[cryptography]==3.5.0
47
+ Requires-Dist: passlib[bcrypt]==1.7.4
48
+ Requires-Dist: bcrypt<4.1,>=3.1.0
49
+ Requires-Dist: slowapi==0.1.9
50
+ Requires-Dist: redis==7.4.0
51
+ Requires-Dist: pyyaml==6.0.3
52
+ Requires-Dist: openai==1.109.1
53
+ Requires-Dist: cryptography==46.0.7
54
+ Requires-Dist: python-dateutil==2.9.0.post0
55
+ Requires-Dist: langdetect==1.0.9
56
+ Requires-Dist: pyvis==0.3.2
57
+ Requires-Dist: urllib3==2.6.3
58
+ Requires-Dist: trafilatura==2.0.0
59
+ Requires-Dist: lxml_html_clean>=0.4.2
60
+ Requires-Dist: requests==2.33.1
61
+ Requires-Dist: python-socks[asyncio]==2.8.1
62
+ Requires-Dist: tldextract==5.3.1
63
+ Requires-Dist: stix2==3.0.2
64
+ Provides-Extra: dev
65
+ Requires-Dist: pytest; extra == "dev"
66
+ Requires-Dist: pytest-asyncio; extra == "dev"
67
+ Requires-Dist: aioresponses>=0.7.6; extra == "dev"
68
+ Requires-Dist: jsonschema>=4.18; extra == "dev"
69
+ Provides-Extra: nlp
70
+ Requires-Dist: sentence-transformers>=3.0; extra == "nlp"
71
+ Requires-Dist: torch>=2.3; extra == "nlp"
72
+ Requires-Dist: transformers>=4.42; extra == "nlp"
73
+ Provides-Extra: vector
74
+ Requires-Dist: chromadb>=0.5; extra == "vector"
75
+ Requires-Dist: sentence-transformers>=3.0; extra == "vector"
76
+ Requires-Dist: torch>=2.3; extra == "vector"
77
+ Provides-Extra: telegram
78
+ Requires-Dist: telethon>=1.36; extra == "telegram"
79
+ Provides-Extra: js
80
+ Requires-Dist: playwright>=1.45; extra == "js"
81
+ Provides-Extra: all
82
+ Requires-Dist: chromadb>=0.5; extra == "all"
83
+ Requires-Dist: playwright>=1.45; extra == "all"
84
+ Requires-Dist: sentence-transformers>=3.0; extra == "all"
85
+ Requires-Dist: telethon>=1.36; extra == "all"
86
+ Requires-Dist: torch>=2.3; extra == "all"
87
+ Requires-Dist: transformers>=4.42; extra == "all"
88
+ Dynamic: license-file
89
+
90
+ <p align="center">
91
+ <img src="public/logo_circle.png" width="160" alt="VoidAccess logo">
92
+ </p>
93
+
94
+ <h1 align="center">VoidAccess</h1>
95
+
96
+ <p align="center">
97
+ <a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="License: MIT"></a>
98
+ <a href="https://www.python.org/"><img src="https://img.shields.io/badge/Python-3.10%2B-blue.svg" alt="Python 3.10+"></a>
99
+ <a href="docker-compose.yml"><img src="https://img.shields.io/badge/Docker-Compose-blue.svg" alt="Docker Compose"></a>
100
+ <a href="https://pypi.org/project/voidaccess/"><img src="https://img.shields.io/pypi/v/voidaccess?logo=pypi&logoColor=white" alt="PyPI version"></a>
101
+ <a href="https://pypi.org/project/voidaccess/"><img src="https://img.shields.io/pypi/dm/voidaccess" alt="PyPI downloads"></a>
102
+ </p>
103
+
104
+ Self-hostable OSINT for turning dark-web research queries into structured threat intelligence. Built for security researchers, threat-intelligence teams, and authorized investigators who need collection, enrichment, relationship mapping, and export in one workflow.
105
+
106
+ ## Terminal Output
107
+
108
+ ![VoidAccess](public/terminal-hero.png)
109
+
110
+ ## Quick Start
111
+
112
+ ```bash
113
+ pip install voidaccess
114
+ voidaccess investigate "LockBit ransomware" --no-llm --no-tor --depth shallow
115
+ voidaccess list
116
+ voidaccess actors
117
+ voidaccess status
118
+ ```
119
+
120
+ ![VoidAccess investigation demo](public/cli_investigation_gif.gif)
121
+
122
+ ## What It Does
123
+
124
+ - **Parallel collection** - searches Tor indexes, paste sites, code forges, security feeds, and curated `.onion` seeds.
125
+ - **Entity extraction** - finds IOCs, wallets, credentials, handles, vulnerabilities, actors, malware, people, and organizations.
126
+ - **Multi-source enrichment** - adds reputation, breach, passive DNS, sandbox, blockchain, and threat-feed context.
127
+ - **Actor intelligence** - persists aliases, infrastructure, notes, timelines, and cross-investigation relationships.
128
+ - **Relationship graphs** - builds co-occurrence graphs, communities, paths, and infrastructure clusters.
129
+ - **Content safety** - filters prohibited queries, URLs, content, and extracted entities at mandatory pipeline gates.
130
+ - **Structured exports** - produces STIX 2.1, MISP, Sigma, YARA, Snort, Suricata, CSV, Markdown, JSON, and IOC packages.
131
+ - **CLI and web UI** - runs locally with SQLite or as a Docker Compose stack with PostgreSQL and a browser interface.
132
+
133
+ ## Pipeline
134
+
135
+ | Stage | Action |
136
+ |---|---|
137
+ | 1 | Refine the investigation query with the selected LLM |
138
+ | 2 | Collect from Tor search, paste sites, code forges, RSS feeds, and curated seeds in parallel |
139
+ | 3 | Filter noisy or irrelevant pages |
140
+ | 4 | Enrich the query and early indicators from threat-intelligence sources |
141
+ | 5 | Discover additional `.onion` links recursively |
142
+ | 6 | Reuse recently processed pages from the vector cache |
143
+ | 7 | Fetch selected pages through Tor with response-size limits |
144
+ | 8 | Persist newly collected content |
145
+ | 9 | Merge collected and enriched intelligence |
146
+ | 10 | Extract entities with regex, NER, and optional LLM analysis |
147
+ | 11 | Cross-reference entities against historical and seed datasets |
148
+ | 12 | Build relationships, communities, and infrastructure clusters |
149
+ | 13 | Generate the final intelligence summary and export-ready result |
150
+
151
+ Full pipeline behavior, timeouts, recovery, and data flow are documented in [Architecture](docs/architecture.md).
152
+
153
+ ## Entity Types
154
+
155
+ | Category | Examples |
156
+ |---|---|
157
+ | Cryptocurrency | Bitcoin, Ethereum, Monero, Litecoin, Zcash, Solana, Tron, ENS |
158
+ | Network indicators | IPv4, IPv6, domains, URLs, `.onion` addresses, MAC addresses, PGP keys |
159
+ | File indicators | MD5, SHA-1, SHA-256, malware families |
160
+ | Credentials | Cloud keys, tokens, JWTs, API keys, stealer logs, combo-list entries |
161
+ | Messaging | Telegram, Discord, XMPP, Tox, Session, Matrix, Wire, ICQ, Wickr |
162
+ | Vulnerabilities | CVEs, MITRE ATT&CK techniques and tactics, Exploit-DB IDs |
163
+ | Detection content | YARA rules, Nuclei templates, Snort and Suricata indicators |
164
+ | Threat intelligence | Actor handles, ransomware groups, paste links, people, organizations, locations |
165
+
166
+ ## Collection and Enrichment
167
+
168
+ | Layer | Sources |
169
+ |---|---|
170
+ | Dark-web search | 16+ Tor search engines and curated `.onion` seeds |
171
+ | Open-web collection | Pastebin, dpaste, paste.ee, Rentry, GitHub, GitLab, and curated RSS feeds |
172
+ | Threat feeds | AlienVault OTX, abuse.ch, MalwareBazaar, ThreatFox, URLhaus, ransomware.live, CISA KEV |
173
+ | IP and domain context | Shodan InternetDB, GreyNoise, AbuseIPDB, Feodo Tracker, C2IntelFeeds, crt.sh, URLScan.io, Wayback Machine, CIRCL PDNS, RDAP |
174
+ | File and identity context | VirusTotal, Hybrid Analysis, Have I Been Pwned, EmailRep |
175
+ | Blockchain | BlockCypher and Etherscan |
176
+
177
+ Sources that need API keys skip cleanly when their keys are absent. The complete key and configuration reference is in [Architecture](docs/architecture.md#13-configuration-reference).
178
+
179
+ ### Optional vector embeddings
180
+
181
+ The default installation can run without PyTorch. When the embedding stack is
182
+ unavailable, VoidAccess logs that it is using a deterministic SHA-256 fallback
183
+ encoder. Install the optional NLP dependencies to enable full
184
+ sentence-transformer vector embeddings:
185
+
186
+ ```bash
187
+ pip install "voidaccess[nlp]"
188
+ ```
189
+
190
+ ## LLM Providers
191
+
192
+ | Provider | Typical models | Notes |
193
+ |---|---|---|
194
+ | OpenRouter | DeepSeek, Llama, Claude | Default route; free models are available |
195
+ | Groq | Llama | Fast hosted inference with a free tier |
196
+ | OpenAI | GPT models | API key required |
197
+ | Anthropic | Claude | Claude Haiku is the tested default |
198
+ | Google Gemini | Gemini Flash and Pro | Google AI Studio key required |
199
+ | Ollama | Any installed local model | Local and suitable for air-gapped deployments |
200
+
201
+ ## CLI Reference
202
+
203
+ | Command | Description |
204
+ |---------|-------------|
205
+ | `voidaccess investigate "QUERY"` | Run an investigation |
206
+ | `voidaccess show` | Open the interactive entity browser |
207
+ | `voidaccess export INVESTIGATION_ID --format FORMAT` | Export as STIX, MISP, Sigma, YARA, Snort, Suricata, package, CSV, Markdown, or JSON |
208
+ | `voidaccess package INVESTIGATION_ID` | Build an IOC package ZIP |
209
+ | `voidaccess enrich INVESTIGATION_ID` | Re-enrich a saved investigation |
210
+ | `voidaccess list` | List saved investigations |
211
+ | `voidaccess status` | Show configuration, Tor, cache, engine, and seed status |
212
+ | `voidaccess actors` | List persistent actor profiles |
213
+ | `voidaccess actor HANDLE` | Show an actor profile |
214
+ | `voidaccess actor HANDLE --timeline` | Show an actor activity timeline |
215
+ | `voidaccess actor HANDLE --note "TEXT"` | Add an analyst note to an actor profile |
216
+ | `voidaccess timeline HANDLE` | Open an actor timeline directly |
217
+ | `voidaccess configure` | Run the setup wizard |
218
+ | `voidaccess configure llm` | Configure the LLM provider, model, and key |
219
+ | `voidaccess configure keys` | Configure enrichment API keys |
220
+ | `voidaccess configure tor` | Override the Tor proxy host and port |
221
+ | `voidaccess version` | Print the installed version |
222
+
223
+ Optional clearnet requests can use [ScrapingAnt](https://scrapingant.com/?ref=mzliyzh) with `--use-scraping-api` or `--use-proxies`; Tor, `.onion`, GitHub, and GitLab traffic are unaffected.
224
+
225
+ ## Self-Hosting
226
+
227
+ Run the full PostgreSQL, Tor, FastAPI, and Next.js stack with Docker Compose. The [self-hosting guide](docs/self-hosting.md) covers guided setup, environment configuration, operations, and troubleshooting.
228
+
229
+ ## Links
230
+
231
+ | | |
232
+ |-|-|
233
+ | [Self-hosting guide](docs/self-hosting.md) | Docker Compose, environment setup, operations, and troubleshooting |
234
+ | [Architecture](docs/architecture.md) | Pipeline internals, modules, schema, API, enrichment, graph, and configuration reference |
235
+ | [Contributing](CONTRIBUTING.md) | Development setup, standards, and pull requests |
236
+ | [Security](SECURITY.md) | Supported versions and private vulnerability reporting |
237
+ | [Usage policy](docs/USAGE_POLICY.md) | Authorized-use requirements and prohibited activity |
238
+ | [PyPI](https://pypi.org/project/voidaccess/) | Published package and release files |
239
+ | [GitHub](https://github.com/KatrielMoses/VoidAccess) | Source, issues, and releases |
240
+
241
+ ## License
242
+
243
+ MIT. Use VoidAccess only for authorized security research and threat-intelligence work; see the [Usage Policy](docs/USAGE_POLICY.md).
@@ -0,0 +1,91 @@
1
+ """Actor API views derived only from the caller's investigation evidence."""
2
+ import uuid
3
+ from datetime import datetime, timezone
4
+ from sqlalchemy import or_
5
+ from db.models import ActorProfile, ActorAlias, ActorInfrastructure, ActorNote, Investigation
6
+ from db.session import get_session
7
+ from sources.actor_profiles import _serialize_profile
8
+
9
+
10
+ class ScopedActorManager:
11
+ _TIMELINE_EVENT_TYPES = {"FIRST_SEEN", "INVESTIGATION", "NEW_ALIAS", "NEW_INFRASTRUCTURE", "NOTE_ADDED"}
12
+
13
+ def __init__(self, current):
14
+ self.owner = current.user.id
15
+ self.admin = current.user.role == "admin"
16
+
17
+ async def get_profile(self, handle):
18
+ canonical = handle.strip().lower().lstrip("@")
19
+ with get_session() as session:
20
+ aliases = session.query(ActorAlias).filter(ActorAlias.alias_value == handle)
21
+ if not self.admin:
22
+ aliases = aliases.filter(ActorAlias.user_id == self.owner)
23
+ alias_ids = [a.actor_id for a in aliases.all()]
24
+ row = session.query(ActorProfile).filter(or_(ActorProfile.canonical_handle == canonical, ActorProfile.id.in_(alias_ids))).first()
25
+ if row is None:
26
+ return None
27
+ owned = session.query(Investigation.id).filter_by(user_id=self.owner)
28
+ aq = session.query(ActorAlias).filter_by(actor_id=row.id)
29
+ iq = session.query(ActorInfrastructure).filter_by(actor_id=row.id)
30
+ if not self.admin:
31
+ aq = aq.filter(ActorAlias.user_id == self.owner)
32
+ iq = iq.filter(ActorInfrastructure.source_investigation_id.in_(owned))
33
+ aliases, infra = aq.all(), iq.all()
34
+ if not self.admin and not (aliases or infra):
35
+ return None
36
+ result = _serialize_profile(row, aliases, infra)
37
+ nq = session.query(ActorNote).filter_by(actor_id=row.id)
38
+ if not self.admin:
39
+ nq = nq.filter_by(user_id=self.owner)
40
+ notes = nq.order_by(ActorNote.created_at).all()
41
+ result["notes"] = "\n".join(n.text for n in notes)
42
+ if not self.admin:
43
+ times = [x.first_seen_at for x in aliases + infra if x.first_seen_at]
44
+ result["first_seen_at"] = min(times).isoformat() if times else None
45
+ result["last_seen_at"] = max(times).isoformat() if times else None
46
+ result["created_at"] = result["first_seen_at"]
47
+ result["updated_at"] = result["last_seen_at"]
48
+ result["investigation_count"] = len(result["investigation_ids"])
49
+ result["confidence"] = max([x.confidence or 0 for x in aliases + infra], default=0)
50
+ return result
51
+
52
+ async def add_alias(self, actor_id, alias_value, alias_type, investigation_id, confidence=None):
53
+ with get_session() as session:
54
+ row = session.query(ActorAlias).filter_by(actor_id=uuid.UUID(actor_id), alias_value=alias_value, user_id=self.owner).first()
55
+ if row:
56
+ row.confidence = max(row.confidence or 0, confidence or 0)
57
+ else:
58
+ session.add(ActorAlias(actor_id=uuid.UUID(actor_id), alias_value=alias_value,
59
+ alias_type=alias_type, user_id=self.owner, confidence=confidence,
60
+ first_seen_at=datetime.now(timezone.utc)))
61
+
62
+ async def find_alias_candidates(self, actor_id, min_confidence=0.60):
63
+ # Candidate evidence must itself be owner-scoped. Analyst annotations
64
+ # are the authoritative candidates; global aggregate scoring is CLI-only.
65
+ with get_session() as session:
66
+ query = session.query(ActorAlias).filter_by(actor_id=uuid.UUID(actor_id))
67
+ if not self.admin:
68
+ query = query.filter_by(user_id=self.owner)
69
+ return [{"candidate_handle": a.alias_value, "confidence": a.confidence, "signals": ["owned_alias"]}
70
+ for a in query.all() if (a.confidence or 0) >= min_confidence]
71
+
72
+ async def get_actor_timeline(self, handle, limit=50, event_types=None):
73
+ profile = await self.get_profile(handle)
74
+ if not profile:
75
+ return []
76
+ events = []
77
+ for item in profile["aliases"]:
78
+ events.append({"event_type": "NEW_ALIAS", "timestamp": item["first_seen_at"],
79
+ "description": item["alias_value"], "metadata": item})
80
+ for item in profile["infrastructure"]:
81
+ events.append({"event_type": "NEW_INFRASTRUCTURE", "timestamp": item["first_seen_at"],
82
+ "description": item["entity_value"], "metadata": item})
83
+ with get_session() as session:
84
+ query = session.query(ActorNote).filter_by(actor_id=uuid.UUID(profile["id"]))
85
+ if not self.admin:
86
+ query = query.filter_by(user_id=self.owner)
87
+ for n in query.all():
88
+ events.append({"event_type": "NOTE_ADDED", "timestamp": n.created_at.isoformat(),
89
+ "description": n.text, "metadata": {}})
90
+ return sorted([e for e in events if not event_types or e["event_type"] in event_types],
91
+ key=lambda e: e["timestamp"] or "")[-limit:]