iccywolfy/Sentinela
GitHub: iccywolfy/Sentinela
企业级开源情报与地缘政治风险平台,融合多源数据与 AI 关联分析以支持战略决策。
Stars: 0 | Forks: 1
# SENTINELA — 全球情报融合平台
SENTINELA 是一个企业级的开源情报 (OSINT) 和地缘政治风险平台,专为情报分析师、战略顾问和高层决策者设计。它将多源数据摄取、AI 辅助关联、叙事分歧分析和自动告警融合到一个统一的作战视图中。
## 目录
- [架构概览](#architecture-overview)
- [模块](#modules)
- [技术栈](#technology-stack)
- [仓库结构](#repository-structure)
- [快速开始 (Docker Compose)](#quick-start-docker-compose)
- [开发环境设置](#development-setup)
- [生产环境部署 (Kubernetes / Helm)](#production-deployment-kubernetes--helm)
- [API 参考](#api-reference)
- [配置](#configuration)
- [CI/CD](#cicd)
- [默认凭据](#default-credentials)
## 架构概览
```
┌─────────────────────────────────────┐
│ SENTINELA Platform │
└─────────────────────────────────────┘
┌──────────────┐ ┌──────────────────┐ ┌────────────────────────┐
│ Frontend │───▶│ API Gateway │───▶│ Ingestion Service │
│ React 18 │ │ NestJS :3000 │ │ NestJS :3001 │
│ Vite + TW │ │ JWT Auth │ │ RSS/REST/Crawl/Upload │
└──────────────┘ │ Risk Scoring │ │ BullMQ Pipeline │
│ Workspace │ │ Event Normalization │
│ Dashboard │ └───────────┬────────────┘
└────────┬─────────┘ │
│ ▼
┌──────────────────────┐ │ ┌─────────────────────────┐
│ Correlation Service │◀────┘ │ Elasticsearch │
│ NestJS :3002 │ │ (Event Index) │
│ 8 Correlation types │ └─────────────────────────┘
│ Narrative Intel │
│ 9 Media Blocs │ ┌───────────────────────┐
└──────────────────────┘ │ Alert Service │
│ NestJS :3003 │
┌──────────────────────┐ │ 9 Alert Types │
│ Report Service │ │ Watchlists │
│ NestJS :3004 │ │ Noise Suppressor │
│ 11 Report Types │ └───────────────────────┘
│ Puppeteer PDF │
│ MinIO/S3 Storage │ ┌───────────────────────┐
└──────────────────────┘ │ NLP Service │
│ Python FastAPI :8000│
│ NER, Sentiment │
│ Lang Detection │
└───────────────────────┘
Infrastructure: PostgreSQL · Elasticsearch · Redis · Kafka · MinIO · Keycloak
Observability: Prometheus · Grafana
```
## 模块
### M1 — 数据源矩阵
管理情报来源的生命周期,并提供完整的元数据跟踪。
- **来源类型:** 新闻媒体、政府门户网站、智库、学术界、社交媒体、金融、情报订阅源
- **收集方式:** RSS Feed、REST API、Web 爬虫、手动上传、URL 监视列表
- **特性:** 可信度评分 (基于 EMA)、健康监控、MD5 去重、可配置的轮询频率
- **连接器:** RSS/Atom、带认证的 REST API、CSS 选择器 Web 爬虫
### M2 — 摄取管道
通过 BullMQ 队列实现的全自动 7 阶段处理管道。
| 阶段 | 描述 |
|-------|-------------|
| 1. Validation (验证) | Schema 和内容验证 |
| 2. Deduplication (去重) | 基于 MD5 哈希的内容去重 |
| 3. Language Detection (语言检测) | Unicode 启发式 + langdetect |
| 4. NLP Enrichment (NLP 增强) | 通过 NLP 服务进行 NER、情感分析、领域分类 |
| 5. Normalization (标准化) | 将原始内容映射到统一的事件 schema |
| 6. Dual Indexing (双重索引) | 写入 PostgreSQL (持久化) + Elasticsearch (可搜索) |
| 7. Completion (完成) | 更新来源指标,发送 Kafka 事件 |
**可靠性:** 3 次重试(带指数退避)、死信队列、租户级隔离。
### M3 — 事件标准化
将异构的原始内容转换为统一的 **NormalizedEvent** schema,包含 50 多个字段。
关键字段:`event_id`、`headline`、`event_domain`、`classification_type`、`impact_score`、`credibility_score`、`urgency_score`、`primary_location`、`actors`、`entities`、`sector_tags`、`provenance_chain`、`language`、`sentiment`、`keywords`。
**事件领域:** GEOPOLITICAL · ECONOMIC · MILITARY · CYBER · HUMANITARIAN · ENVIRONMENTAL · SOCIAL · TECHNOLOGICAL
### M4 — 关联引擎
使用 6 种策略识别跨领域和时间的事件关系:
| 策略 | 逻辑 |
|----------|-------|
| Temporal (时间) | 72 小时窗口内的事件,跨领域 |
| Geographic (地理) | 共享国家代码 |
| Entity-based (实体) | 共享参与者或组织(集合交集) |
| Thematic (主题) | 共享标签(≥2 个重叠) |
| Rule-based (规则) | 数据库驱动的可配置条件 |
| Cross-domain (跨域) | 10 种硬编码的地缘政治模式(例如:能源→制裁、网络→金融) |
关联按强度 (0–1) 评分,并存储基本原理、证据列表和替代假设。
### M5 — 叙事情报
监控 9 个媒体集团的信息生态系统,并检测叙事分歧。
**媒体集团:**
`WEST_MEDIA` · `RU_STATE` · `CN_STATE` · `MENA_REGIONAL` · `LATAM_MEDIA` · `GOV_OFFICIAL` · `THINK_TANK` · `TECH_SCIENTIFIC` · `INDEPENDENT`
- **分歧指数** (0–100):基于情感范围和框架多样性,衡量各集团间的叙事极化程度
- **框架分析:** 每个领域特定于集团的偏见图和情感基线
- **极化术语:** 检测跨集团分歧最大的术语
- **覆盖盲区:** 识别被某些集团报道但被其他集团忽视的主题
### M6 — 风险评分
具有完整可解释性的多维事件风险评分。
**13 个评分因子:**
`impact`、`urgency`、`credibility`、`geopoliticalInstability`、`economicImpact`、`militaryActivity`、`cyberThreat`、`humanitarianCrisis`、`environmentalRisk`、`socialUnrest`、`technologicalDisruption`、`novelty`、`corroboration`
- 权重可按租户配置
- 带有模型版本控制的评分历史,用于漂移检测
- 国家风险记分卡,由单事件评分汇总而成
- 自然语言可解释性:前 5 大因子分解
### M7 — 告警与监视列表
具有智能噪声抑制功能的实时告警。
**告警类型:**
`THRESHOLD_BREACH` · `WATCHLIST_MATCH` · `CORRELATION_DETECTED` · `NARRATIVE_SHIFT` · `CRISIS_ESCALATION` · `SOURCE_ANOMALY` · `ENTITY_ACTIVITY` · `GEOGRAPHIC_ALERT` · `PATTERN_MATCH`
**监视列表类型:**
`ENTITY` · `COUNTRY` · `KEYWORD` · `TOPIC` · `SECTOR` · `COMPOUND`
**噪声抑制器 (基于 Redis):**
- 每个告警的冷却窗口
- 基于内容的去重,带有可配置的 TTL
- 用于分析师驱动抑制调优的反馈循环
### M8 — 调查工作区
协作式调查案例管理环境。
- **案例生命周期:** OPEN → IN_PROGRESS → PENDING_REVIEW → CLOSED → ARCHIVED
- **证据关联:** 每个案例关联事件、笔记、附件
- **语义搜索:** 通过 Elasticsearch 进行全文 + 模糊匹配,并提供高亮摘录
- **实体透视:** 链接到特定参与者/组织/国家的所有事件
- **集合:** 精选的事件集
- **档案:** 汇编的案例摘要
- **调查时间线:** 按时间顺序重建事件
### M9 — 高管层
为领导层提供的战略决策支持工具。
- **全球指挥仪表盘:** 实时 KPI、顶级风险事件、告警流、领域细分、国家风险热力图
- **每日情报简报:** AI 辅助的按领域叙事摘要
- **危机室:** 升级事件跟踪、情景预测(3 种情景及其概率估计)
### M10 — 报告工作室
专业的情报报告生成,支持 PDF 导出。
**11 种报告类型:**
`FLASH_ALERT` · `DAILY_BRIEF` · `WEEKLY_DIGEST` · `COUNTRY_RISK_DOSSIER` · `ENTITY_PROFILE` · `THREAT_ASSESSMENT` · `INCIDENT_REPORT` · `NARRATIVE_ANALYSIS` · `CORRELATION_REPORT` · `EXECUTIVE_SUMMARY` · `CUSTOM`
- 章节:执行摘要、分析、方法论、结论、附录(溯源链)
- 通过 Puppeteer 渲染 PDF,采用深海军蓝/金色的品牌布局
- 每个租户可配置品牌(Logo、配色方案、页眉/页脚)
- 生命周期:DRAFT → GENERATING → READY → APPROVED → PUBLISHED
- 存储在 MinIO/S3 上,提供预签名下载 URL
## 技术栈
| 层级 | 技术 |
|-------|-----------|
| Frontend (前端) | React 18, TypeScript, Vite, TailwindCSS, TanStack Query, Zustand |
| Backend (后端) | NestJS (TypeScript), Prisma ORM, PassportJS (JWT) |
| NLP | Python 3.11, FastAPI, spaCy, langdetect |
| Database (数据库) | PostgreSQL 16 |
| Search (搜索) | Elasticsearch 8.13 |
| Queue (队列) | BullMQ + Redis 7 |
| Messaging (消息) | Apache Kafka (Confluent) |
| Object Storage (对象存储) | MinIO (兼容 S3) |
| Auth (认证) | Keycloak 24 + JWT |
| PDF | Puppeteer + Handlebars |
| Observability (可观测性) | Prometheus + Grafana |
| Infra (dev) (基础设施-开发) | Docker Compose |
| Infra (prod) (基础设施-生产) | Kubernetes + Helm 3 |
| CI/CD | GitHub Actions |
| Monorepo | Turborepo |
## 仓库结构
```
sentinela/
├── apps/
│ ├── frontend/ # React 18 + Vite SPA
│ ├── api-gateway/ # NestJS — Auth, Scoring, Workspace, Executive (M6, M8, M9)
│ ├── ingestion-service/ # NestJS — Sources, Pipeline, Normalization (M1, M2, M3)
│ ├── correlation-service/ # NestJS — Correlation, Narrative (M4, M5)
│ ├── alert-service/ # NestJS — Alerting, Watchlists (M7)
│ ├── report-service/ # NestJS — PDF Reports, Storage (M10)
│ └── nlp-service/ # Python FastAPI — NER, Sentiment, Classification
├── packages/
│ ├── types/ # Shared TypeScript interfaces (all 10 modules)
│ ├── database/ # Prisma schema + migrations (25+ models)
│ └── ui/ # Shared design system base
├── infra/
│ ├── helm/sentinela/ # Helm chart (Chart.yaml, values.yaml, templates/)
│ ├── prometheus/ # Prometheus scrape config
│ ├── grafana/dashboards/ # Grafana dashboard provisioning
│ └── keycloak/ # Keycloak realm config with roles and dev users
├── .github/workflows/
│ ├── ci.yml # PR: lint, build, test, docker build
│ └── deploy.yml # main/tag: GHCR push + helm upgrade
├── docker-compose.yml # Full local dev stack
├── turbo.json # Turborepo pipeline config
└── package.json # Monorepo root (workspaces)
```
## 快速开始
### 前置条件
- Docker ≥ 24 和 Docker Compose v2
- 最少 8 GB RAM(Elasticsearch 至少需要 1 GB 堆内存)
### 1. 克隆并配置
```
git clone https://github.com/iccywolfy/Sentinela.git
cd Sentinela
cp .env.example .env
# 编辑 .env 以设置 JWT_SECRET 和您环境中的其他机密
```
### 2. 启动完整技术栈
```
docker compose up -d
```
这将启动所有 17 个服务。首次启动大约需要 3–5 分钟,包括拉取镜像和初始化 Elasticsearch。
### 3. 验证服务
| 服务 | URL | 备注 |
|---------|-----|-------|
| Frontend (前端) | http://localhost:5173 | React SPA |
| API Gateway (API 网关) | http://localhost:3000 | REST API |
| Ingestion (摄取) | http://localhost:3001/health | |
| Correlation (关联) | http://localhost:3002/health | |
| Alert (告警) | http://localhost:3003/health | |
| Report (报告) | http://localhost:3004/health | |
| NLP | http://localhost:8000/health | |
| Keycloak | http://localhost:8080 | admin / admin |
| MinIO Console | http://localhost:9001 | minioadmin / minioadmin |
| Prometheus | http://localhost:9090 | |
| Grafana | http://localhost:3100 | admin / sentinela |
| Elasticsearch | http://localhost:9200 | |
### 4. 登录
打开 http://localhost:5173 并使用以下账号登录:
```
Email: analyst@sentinela.local
Password: sentinela
```
### 5. 添加您的第一个来源
导航到 **Sources → Add Source** 并添加一个 RSS 源,例如:
```
Name: Reuters World News
URL: https://feeds.reuters.com/reuters/worldNews
Method: RSS_FEED
Category: NEWS_MEDIA
Credibility: 0.85
Frequency: 30 (minutes)
```
事件将在一个收集周期内开始出现在资源管理器中。
## 开发环境设置
### 前置条件
- Node.js 20+
- npm 10+
- Python 3.11+ (用于 nlp-service)
### 安装依赖
```
npm install
```
### 生成 Prisma 客户端
```
npx prisma generate --schema=packages/database/prisma/schema.prisma
```
### 仅启动基础设施
```
docker compose up -d postgres elasticsearch redis kafka zookeeper minio keycloak
```
### 在开发模式下运行所有服务
```
# 所有服务启用热重载
npm run dev
# 或单个服务
npm run dev --workspace=apps/api-gateway
npm run dev --workspace=apps/ingestion-service
npm run dev --workspace=apps/frontend
```
### 运行数据库迁移
```
DATABASE_URL="postgresql://sentinela:sentinela@localhost:5432/sentinela" \
npx prisma migrate dev --schema=packages/database/prisma/schema.prisma
```
### 运行测试
```
npm run test
# 或使用 turbo
npx turbo run test
```
## 生产环境部署 (Kubernetes / Helm)
### 前置条件
- Kubernetes 集群 (1.27+)
- Helm 3.14+
- `kubectl` 已为您的集群配置
- GHCR 凭据(或您自己的镜像仓库)
### 添加所需的密钥
```
kubectl create namespace sentinela
kubectl create secret generic sentinela-secrets \
--namespace sentinela \
--from-literal=database-url="postgresql://sentinela:STRONG_PASS@sentinela-postgresql:5432/sentinela" \
--from-literal=jwt-secret="$(openssl rand -hex 32)" \
--from-literal=minio-access-key="sentinela" \
--from-literal=minio-secret-key="$(openssl rand -hex 24)"
```
### 使用 Helm 安装
```
helm upgrade --install sentinela ./infra/helm/sentinela \
--namespace sentinela \
--create-namespace \
--set global.imageTag=1.0.0 \
--set apiGateway.ingress.host=api.your-domain.com \
--set frontend.ingress.host=sentinela.your-domain.com \
--wait
```
### 生产环境覆盖配置
```
global:
imageTag: "1.0.0"
apiGateway:
replicaCount: 3
ingress:
enabled: true
host: api.your-domain.com
tls: true
frontend:
replicaCount: 2
ingress:
enabled: true
host: sentinela.your-domain.com
tls: true
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 10
networkPolicy:
enabled: true
```
```
helm upgrade --install sentinela ./infra/helm/sentinela \
--namespace sentinela \
-f values-prod.yaml
```
## API 参考
所有端点都以 `/api/v1` 为前缀,并且除了 `/api/v1/auth/login` 外,都需要 `Bearer` JWT Token。
### 认证
```
POST /api/v1/auth/login
Content-Type: application/json
{ "email": "analyst@sentinela.local", "password": "sentinela" }
```
### 事件
```
GET /api/v1/events?query=ukraine&domain=GEOPOLITICAL&minScore=0.7&page=1&limit=20
GET /api/v1/events/:id
```
### 风险评分
```
GET /api/v1/scoring/country-scoreboard
GET /api/v1/scoring/:eventId/explain
```
### 告警
```
GET /api/v1/alerts?status=ACTIVE&severity=CRITICAL
POST /api/v1/alerts/:id/acknowledge
POST /api/v1/alerts/:id/resolve
```
### 工作区
```
GET /api/v1/workspace/cases
POST /api/v1/workspace/cases
GET /api/v1/workspace/cases/:id
POST /api/v1/workspace/cases/:id/events
POST /api/v1/workspace/cases/:id/notes
GET /api/v1/workspace/search?q=entity+name
```
### 报告
```
GET /api/v1/reports
POST /api/v1/reports/generate
GET /api/v1/reports/:id
POST /api/v1/reports/:id/approve
POST /api/v1/reports/:id/publish
```
### 叙事
```
GET /api/v1/narrative/profile/latest
GET /api/v1/narrative/divergence
```
### 来源
```
GET /api/v1/sources
POST /api/v1/sources
POST /api/v1/sources/:id/collect
```
### 高管
```
GET /api/v1/executive/dashboard/overview
GET /api/v1/executive/dashboard/brief
GET /api/v1/executive/crisis-room
GET /api/v1/executive/crisis-room/scenarios
```
## 配置
所有服务均通过环境变量进行配置。有关完整列表,请参阅 `.env.example`。
| 变量 | 描述 | 默认值 |
|----------|-------------|---------|
| `DATABASE_URL` | PostgreSQL 连接字符串 | `postgresql://sentinela:sentinela@postgres:5432/sentinela` |
| `REDIS_URL` | Redis 连接字符串 | `redis://redis:6379` |
| `KAFKA_BROKERS` | Kafka Broker 列表 | `kafka:9092` |
| `ELASTICSEARCH_URL` | Elasticsearch URL | `http://elasticsearch:9200` |
| `S3_ENDPOINT` | MinIO/S3 端点 | `http://minio:9000` |
| `S3_ACCESS_KEY` S3 访问密钥 | `minioadmin` |
| `S3_SECRET_KEY` | S3 密钥 | `minioadmin` |
| `S3_BUCKET` | S3 Bucket 名称 | `sentinela` |
| `JWT_SECRET` | JWT 签名密钥 | **请在生产环境中修改** |
| `NLP_SERVICE_URL` | NLP 服务 URL | `http://nlp-service:8000` |
| `NODE_ENV` | Node 环境 | `development` |
### 多租户
SENTINELA 支持多个隔离的租户。所有数据(事件、告警、案例、报告、来源)均通过 `tenantId` 进行范围界定。每个请求都需要 `x-tenant-id` 和 `x-user-id` Header(登录后由前端自动注入)。
## CI/CD
### 持续集成 (`ci.yml`)
在每次推送到 `main`/`develop` 以及所有 Pull Request 时触发:
1. **Lint** — 对所有 TypeScript 应用运行 ESLint
2. **Build** — Turborepo 先构建包再构建应用
3. **Test** — 使用实时 PostgreSQL + Redis 服务容器运行单元测试
4. **Docker Build** — 验证所有 7 个 Docker 镜像是否能干净地构建(不推送)
### 持续部署 (`deploy.yml`)
在推送到 `main` 或版本标签 (`v*`) 时触发:
1. **Build & Push** — 构建所有 7 个 Docker 镜像并推送到 GHCR (`ghcr.io/iccywolfy/sentinela/*`)
2. **Helm Upgrade** — 仅在版本标签时部署到 Kubernetes 集群(需要 `KUBECONFIG` Secret)
**CD 所需的 GitHub Secrets:**
| Secret | 描述 |
|--------|-------------|
| `KUBECONFIG` | Kubernetes 集群 kubeconfig |
| `JWT_SECRET` | 生产环境 JWT 签名密钥 |
| `POSTGRES_PASSWORD` | 生产环境 PostgreSQL 密码 |
| `MINIO_PASSWORD` | 生产环境 MinIO 密码 |
## 默认凭据
| 服务 | 用户名 | 密码 |
|---------|----------|----------|
| SENTINELA App | `analyst@sentinela.local` | `sentinela` |
| SENTINELA Admin | `admin@sentinela.local` | `sentinela` |
| Keycloak Admin | `admin` | `admin` |
| PostgreSQL | `sentinela` | `sentinela` |
| MinIO | `minioadmin` | `minioadmin` |
| Grafana | `admin` | `sentinela` |
## 许可证
Copyright © 2024 SENTINELA Team. All rights reserved.
*SENTINELA — See everything. Understand everything. Act decisively.*
标签:AI 辅助分析, API 网关, BullMQ, Docker, ESC4, Helm, HTTP/HTTPS抓包, JWT 认证, NestJS, OSINT, React, Syscalls, Tailwind CSS, TypeScript, Vite, 企业级安全, 叙事分歧分析, 地缘政治风险, 子域名突变, 安全插件, 安全防御评估, 实时处理, 密码管理, 开源网络情报, 微服务架构, 态势感知, 情报分析, 情报融合, 战略决策支持, 搜索引擎查询, 数据摄取, 测试用例, 网络诊断, 自动化攻击, 自动告警, 舆情分析, 请求拦截, 逆向工具, 风险评分, 风险预警