Skip to content

威胁画像模块 · Actor Portrait Module

Status: shipped (Phase 7, Steps 1–10) Frontend route: /actors Backend prefix: /api/v1/actors

10-step iterative upgrade. The flagship "who is this seller?" workspace. Step 3 (Identity Resolution Engine) is the hard core — every other step either feeds into it or surfaces what it builds. Design imperative quoted from the user kicking off Phase 7:

威胁画像一定要专业,切入到点子上,如何通过抓取的信息精准的定位威胁, 这个点非常重要。不能磨棱两可。


1. Module purpose

For each canonical adversary (one row in portal_actors), surface everything we know — and infer everything we can — so the analyst / 律师 / 鉴定中心 can answer:

  1. Who? — name + aliases + canonical contact registry (微信 / QQ / TG / Discord / 电话 / 邮箱 / 钱包 / 域名 / 用户名)
  2. What do they do? — 报价图谱、URL 命中、平台分布、地域、活动节律
  3. How dangerous? — multi-factor 0–100 risk score + radar chart
  4. Who do they work with? — depth-1 ego graph + 4 桥的 edge evidence
  5. What lifecycle stage? — active / dormant / closed, auto-inferred
  6. What changed? — full activity timeline + AI 简报

The output is courtroom-ready evidence packets, not opinion. Every number / claim must be reproducible from the raw rows in the DB.


2. Step ledger

Step Scope Deliverable
1 总览仪表盘 + KPI GET /actors/stats + 5-tile Hero KPI (高危 / 活跃 / 蛰伏 / 已结案 / 本周新增) + TopRiskActors + PlatformDistribution panels
2 详情页全身画像 GET /actors/:id/related(5 collection bundle)+ 5-tile 跨源 KPI strip + 资产清单 + 社群足迹
3 Identity Resolution Engine portal_actor_identifiers + _merge_candidates + _audit 三张表 + 7 endpoints + 合并审核工作台
4 多源信号融合 GET /actors/:id/sources 一遍 pass 聚合:联系方式注册表 / 报价图谱 / URL / 地域 / 平台 / 活动节律
5 量化风险评分引擎 GET /actors/:id/risk-score 六因素加权 0–100 + 雷达图 + 每因素 reason 痕迹
6 关系网络图 GET /actors/:id/network 四桥 (指纹 / 私服 / 社群 / 共同目标) + 纯 SVG force-directed 图
7 富化 + 生命周期推断 POST /actors/:id/enrich 派生 primary_* + 自动 active→dormant→closed
8 活动流 + AI 简报 GET /actors/:id/activity(5 源 union)+ GET /actors/:id/ai-summary(actor-fusion/v1 templated)
9 批量动作 + 观察名单 portal_actor_watchlists 表 + watch toggle + watchlist page + bulk-enrich / bulk-status / CSV export
10 文档 + e2e + 部署 本文档 + portal routes test + 部署 ai-astraweb + 同步 docs.astraeye.ai

3. Identity Resolution Engine(Step 3 核心)

3.1 数据模型

portal_actor_identifiers
  UNIQUE (tenant_id, kind, value)  ← 闸门
  kind  ∈ {wechat, qq, telegram, discord, phone, email,
            wallet_btc, wallet_eth, wallet_trc20, wallet_generic,
            domain, domain_registrant_email, username}
  occurrences int  — 同一标识符在多个来源里出现次数
  confidence  int  — per-row 0-100

portal_actor_merge_candidates
  (a, b) lex-normalised; status ∈ {pending, merged, rejected, dismissed}
  score int 0-100; reasons jsonb

portal_actor_audit
  action ∈ {merge, split, ingest, enrich}
  payload jsonb  — 完整 pre-state,可作回滚依据

3.2 Kind weight 表(用于评分 + 合并候选)

wallet_*     1.00   ← 加密钱包 = 近确定性
phone        0.95
email        0.85
wechat / qq  0.85
discord      0.85
domain_registrant_email 0.80
telegram     0.70
domain       0.40   ← 故意低:CloudFlare / NS 共享常见
username     0.30

3.3 自动合并候选检测

UpsertActorIdentifier(in) 接到一个 (kind, value) 已落在不同 actor 上时:

  1. 绝不静默重指 actor_id
  2. 写 / 更新 portal_actor_merge_candidates 一行
  3. 重算 pair score = max(weight × confidence) across shared identifiers
  4. score ≥ 85 → 建议自动合并(UI 标红 + 强匹配 chip)
  5. 60 ≤ score < 85 → 候选队列
  6. < 60 → 不入候选(避免噪声)

3.4 合并语义

MergeActors(target, source, byUser, notes) 单事务做:

  1. snapshot source actor + 标识符 → audit payload
  2. 移动 identifiers(UNIQUE 冲突时 bump target 行的 occurrences + 删 source 行)
  3. 重指 metadata 指针:threats / private_servers / social_intel / publications
  4. 重指 FK:evidence_chains / legal_docs
  5. source.status = 'merged'(软删,保留 audit 完整性)
  6. 关闭涉及 pair 的 pending 候选
  7. 写 audit

SplitActor 是反向:peel 子集 identifiers 到新 actor,不移动 SI/PS 链接(人工再连)。


4. API endpoints(全列表)

4.1 列表 / 统计 / 关联

Method Path 用途
GET /actors 列表(search / page / page_size)
GET /actors/stats 5 KPI tile + top_risk_actors + by_platform
GET /actors/:id 单画像详情
GET /actors/:id/related 5 collection bundle (threats / ps / si / legal / evidence)
GET /actors/:id/threats 该画像名下的威胁分页列表

4.2 Identity Resolution(Step 3)

Method Path 用途
GET /actors/:id/identifiers 列该 actor 的所有标识符(confidence DESC)
POST /actors/:id/identifiers 手动加一个标识符(命中已存在 → 合并候选)
POST /actors/:id/ingest-identifiers 一键从关联 SI/PS 抽出标识符聚合
GET /actors/merge-candidates 待审合并候选(按 score DESC)
POST /actors/merge 执行合并
POST /actors/merge-candidates/:id/decision 拒绝 / dismiss 候选
POST /actors/:id/split 拆出新 actor

4.3 多源融合 + 评分 + 网络(Step 4-6)

Method Path 用途
GET /actors/:id/sources canonical 多源融合(contacts / pricing / urls / geo / platforms / activity)
GET /actors/:id/risk-score 六因素 0–100 加权 + 因素明细
GET /actors/:id/network depth-1 ego graph + 4 类边 + per-edge evidence

4.4 富化 + 生命周期(Step 7)

Method Path 用途
GET /actors/:id/enrichment 读 metadata.enrichment 块(不重算)
POST /actors/:id/enrich 重算 + 写 metadata + 可能更新 actor.status + audit

4.5 活动 + AI 简报(Step 8)

Method Path 用途
GET /actors/:id/activity?limit=N 5 路 union 时间线
GET /actors/:id/ai-summary 确定性 templated 简报(actor-fusion/v1)

4.6 观察名单 + 批量(Step 9)

Method Path 用途
GET /actors/watchlist 当前用户的观察名单 + score_delta / status_changed 计算字段
POST /actors/:id/watch 加入观察
DELETE /actors/:id/watch 取消观察
POST /actors/bulk-enrich 批量富化
POST /actors/bulk-watch 批量加观察
POST /actors/bulk-status 批量改 status

5. Risk score 因素权重表(Step 5)

Factor Weight Scoring 规则
威胁强度 30% weighted (critical×10 + high×5 + medium×2 + low×1),50 饱和到 100
身份强度 20% sum(kind_weight × 10),1 个钱包 ≈ 10 分
活跃近度 18% 阶梯:今天=100 / 周内=90 / 月内=70 / 季内=40 / 半年=20 / 年内=10
平台广度 12% unique platforms × 20,5 个平台饱和
报价频次 10% 任何报价基线 20 + count×4 饱和 100
资产规模 10% linked PS × 12

Band 阈值:≥80 critical / ≥60 high / ≥35 medium / 其它 low


6. Network graph 四桥(Step 6)

Kind Weight 上限 信号强度
identifier kind_weight × confidence 强 — 共享强标识符(钱包 / 微信)
private_server 35 中 — 两位都连同一 PS
social_channel 25 中 — 同 (platform, group_id) 内交叉发帖
threat_target 10 弱 — 共同目标游戏(convergent interest,非合谋)

绝不做 depth ≥ 2 — well-connected hub 在 2-跳就爆图。点击邻居跳进去再展。


7. Lifecycle 阈值(Step 7)

dormantAfterDays = 30
closedAfterDays  = 180

硬约束: - merged 永不被自动回滚 - 分析师手动 closed / archived 不被自动覆盖

每次富化写 portal_actor_audit 一行(action=enrich, payload 含 inferred_status + reason)—— "系统在 5/17 把这位推到 dormant"完全可追溯。


8. Frontend routes / components 索引

/actors                       — Hero + KPI + Top-N + Platform dist + 卡片列表
/actors/[id]                  — 全身画像页(10 panels)
/actors/merge-review          — 合并审核工作台(Step 3)
/actors/watchlist             — 观察名单 + bulk toolbar(Step 9)

components/actors/
  IdentifiersPanel             — 身份指纹(Step 3)
  SourceFusionPanel            — 多源融合(Step 4)
  RiskScorePanel               — 风险评分 + 雷达图(Step 5)
  NetworkGraphPanel            — 关系网络图(Step 6)
  LifecyclePanel               — 生命周期 + 主属性(Step 7)
  WatchToggle                  — 观察按钮(Step 9)

components/viz/
  ActorActivityFeed            — 活动流(Step 8)
  ActorAISummary               — AI 简报(Step 8)

9. 已知不做 / Phase 7.5 备忘

  • WHOIS / IP geo 实时拉取:当前 geo 推断只用 PS.geo_country(已在 sync 上游写入)。实时 WHOIS 查询是 Phase 7.5
  • 真 langdetect:当前 primary_language 是 CJK vs Latin 比例的启发式。fastText / cld3 接入是 Phase 7.5
  • 实际 Telegram / 邮件预警:当前 alert_on CSV 字段已落库,但 watcher 进程没跑(站内 score_delta + activity feed 是当前唯一 UI 反馈)
  • LLM-backed AI summary:当前 actor-fusion/v1 是确定性 templated(DGX vLLM 接入待 Phase 8)
  • 关系图 depth ≥ 2:故意不做(爆图)
  • 跨 tenant 合并:super_admin 才能做;当前需要直连 DB;专门的"全局合并管理"页面是 Phase 7.5

10. Migrations

000009_actor_identity.up.sql      — 标识符 / 合并候选 / 审计 三表(Step 3)
000010_actor_watchlist.up.sql     — 观察名单(Step 9)

两个迁移都有对应 .down.sql,AutoMigrate 也已开启(dev 模式覆盖)。