kloyaa/risk-assessment-system

GitHub: kloyaa/risk-assessment-system

结合规则引擎与 XGBoost 机器学习的实时金融交易欺诈检测平台,提供风险评分、自动决策和监控仪表板。

Stars: 0 | Forks: 0

# 风险评估系统 (RAS) 用于金融交易的实时欺诈检测平台。结合基于规则的启发式方法与 XGBoost ML 模型,生成风险评估、批准/拒绝决策以及实时仪表板警报。 ## 架构 ``` ┌─────────────────────────────────────────────────────────────┐ │ SvelteKit Frontend (port 3000) │ │ Dashboard · Transactions · Labels · ML · Settings │ └──────────────────────────┬──────────────────────────────────┘ │ HTTP + WebSocket ┌──────────────────────────▼──────────────────────────────────┐ │ FastAPI Backend (port 8000) │ │ │ │ POST /api/v1/transactions/assess │ │ ├─ Rule engine (velocity · amount · device/IP blocklist)│ │ └─ XGBoost ML (32 features, trained on labeled data) │ │ combined = 0.40 × rule_score + 0.60 × ml_score │ │ │ │ POST /api/v1/ml/train — trigger training │ │ POST /api/v1/ml/simulate — generate dataset │ │ POST /api/v1/ml/upload-dataset — upload CSV/JSONL │ └──────┬───────────────────────────────────────┬──────────────┘ │ asyncpg │ redis.asyncio ┌──────▼──────────┐ ┌─────────▼──────────────┐ │ PostgreSQL 16 │ │ Redis 7 │ │ Transactions │ │ WebSocket pub/sub │ │ Labels │ │ Training lock │ │ Risk scores │ └────────────────────────┘ │ API keys │ │ Settings │ └─────────────────┘ ``` **风险等级:** | 分数 | 等级 | 操作 | |-------|-------|--------| | 0.00 – 0.35 | 低 | 批准 | | 0.35 – 0.70 | 中 | 批准 — 标记为人工审核 | | 0.70 – 1.00 | 高 | **拒绝** | 任何高严重性 (HIGH) 规则都会强制拦截交易,无论综合得分如何。 ## 快速开始 **要求:** Docker Desktop(包含 Compose v2)或 Docker Engine + Compose 插件。 ``` git clone cd risk-assessment-system cp .env.example .env ``` 编辑 `.env` — 至少设置以下内容(出于安全考虑必须设置): ``` SECRET_KEY= ADMIN_PASSWORD= HASH_SECRET= ``` 启动所有服务: ``` docker compose up --build ``` 首次启动时,后端会打印您的 API key: ``` docker compose logs backend | grep "FIRST API KEY" ``` | 服务 | URL | |---------|-----| | 仪表板 | http://localhost:3000 | | API 文档 (Swagger) | http://localhost:8000/docs | | 健康检查 | http://localhost:8000/health | ## 环境变量 将 `.env.example` 复制到 `.env`。以下所有变量都可以在那里或通过环境变量进行覆盖。 ### 安全(生产环境中必需) | 变量 | 描述 | 生成方法 | |----------|-------------|-----------------| | `SECRET_KEY` | 签署 JWT token | `python -c "import secrets; print(secrets.token_hex(32))"` | | `ADMIN_PASSWORD` | 仪表板管理员登录密码 | 任何强密码 | | `HASH_SECRET` | 用于账号哈希的 HMAC 密钥 | `python -c "import secrets; print(secrets.token_hex(32))"` | | `ALLOWED_ORIGINS` | 逗号分隔的允许 CORS 来源 | `https://dashboard.yourdomain.com` | | `ENV` | 设置为 `production` 以在存在不安全默认值时快速失败 | `production` | ### 数据库 | 变量 | 默认值 | 描述 | |----------|---------|-------------| | `POSTGRES_USER` | `ras` | PostgreSQL 用户 | | `POSTGRES_PASSWORD` | `raspassword` | PostgreSQL 密码 — 请在生产环境中更改 | | `POSTGRES_DB` | `ras_db` | 数据库名称 | ### 应用程序 | 变量 | 默认值 | 描述 | |----------|---------|-------------| | `DEBUG` | `false` | 启用 debug 级别日志记录 | | `FIRST_API_KEY` | _(自动生成)_ | 覆盖初始化生成的 API key | | `TRAINING_N_JOBS` | `2` | XGBoost CPU 线程数(`-1` = 所有核心,在共享主机上请避免使用) | | `RATE_LIMIT_ASSESS_PER_MINUTE` | `120` | 每个 API key 每分钟最大 `/assess` 调用次数 | | `MODEL_DIR` | `/app/ml_models` | 容器内的模型存储路径 | ### 前端(Vite 构建时,非机密) | 变量 | 默认值 | 描述 | |----------|---------|-------------| | `VITE_API_BASE_URL` | `http://localhost:8000` | 浏览器所见的后端 URL | | `VITE_WS_BASE_URL` | `ws://localhost:8000` | WebSocket URL | ## Docker 参考 ### 开发模式(默认) 后端(`uvicorn --reload`)和前端(Vite HMR)均支持实时重载: ``` docker compose up # starts all services docker compose up --build # rebuild images first (after dependency changes) ``` 源文件通过 `develop.watch` 同步 — 保存文件后更改即刻生效,无需重新构建。 ### 监视模式(依赖项变更时自动重新构建) ``` docker compose watch ``` 当 `requirements.txt` 或 `package.json` 更改时,自动重新构建受影响的服务容器。 ### 生产环境 ``` # 将生产环境值放入 .env,然后: docker compose up --build -d ``` 当 `ENV=production` 时,如果 `SECRET_KEY`、`ADMIN_PASSWORD` 或 `HASH_SECRET` 保留不安全的默认值,后端将拒绝启动。 ### 常用命令 ``` docker compose logs -f backend # stream backend logs docker compose logs -f # all services docker compose ps # service status docker compose down # stop + remove containers (volumes preserved) docker compose down -v # full reset — deletes all data ``` ### ML 模型持久化 训练后的模型存储在命名的 Docker 卷中(`ml_models → /app/ml_models`)。它**可以在重启和镜像重建中保留**。只有 `down -v` 会删除它。 备份模型卷: ``` docker run --rm \ -v risk-assessment-system_ml_models:/data \ -v $(pwd):/backup \ alpine tar czf /backup/ml_models_backup.tar.gz -C /data . ``` 恢复: ``` docker run --rm \ -v risk-assessment-system_ml_models:/data \ -v $(pwd):/backup \ alpine tar xzf /backup/ml_models_backup.tar.gz -C /data ``` ## API 集成指南 ### 认证 每个请求都需要 `X-API-Key` 标头: ``` X-API-Key: your-api-key-here ``` ### 评估交易 ``` POST /api/v1/transactions/assess Content-Type: application/json X-API-Key: ``` **最小请求:** ``` { "transaction_id": "TXN-20241115-001", "timestamp": "2024-11-15T14:30:00+08:00", "amount": 15000.00, "currency": "PHP", "sender_account": "1234567890", "receiver_account": "0987654321", "transaction_type": "transfer", "channel": "mobile" } ``` **完整请求(推荐 — 设备和 IP 可提高 ML 准确率):** ``` { "transaction_id": "TXN-20241115-001", "timestamp": "2024-11-15T14:30:00+08:00", "amount": 15000.00, "currency": "PHP", "sender_account": "1234567890", "receiver_account": "0987654321", "transaction_type": "transfer", "channel": "mobile", "is_international": false, "location_country": "PH", "merchant_category_code": "6012", "device_fingerprint": "chrome-win10-abc123", "ip_address": "192.168.1.100", "extra_fields": { "bank_reference": "BPI-2024-XYZ", "branch_code": "BGC001" } } ``` **字段参考:** | 字段 | 必填 | 值 | |-------|----------|--------| | `transaction_id` | 是 | 每笔交易的唯一字符串 | | `timestamp` | 是 | 带时区的 ISO 8601 格式 | | `amount` | 是 | 正数 | | `currency` | 是 | ISO 4217(`PHP`、`USD` 等) | | `sender_account` | 是 | 原始账号 — 存储前进行哈希处理 | | `receiver_account` | 是 | 原始账号 — 存储前进行哈希处理 | | `transaction_type` | 是 | `transfer` `payment` `withdrawal` `deposit` `purchase` `refund` | | `channel` | 是 | `online` `mobile` `atm` `branch` `pos` `api` | | `device_fingerprint` | 否 | 原始设备 ID — 后端对其进行哈希处理 | | `ip_address` | 否 | 原始 IP 地址 — 后端对其进行哈希处理 | | `is_international` | 否 | 布尔值,默认为 `false` | | `location_country` | 否 | ISO 3166-1 alpha-2(`PH`、`US` 等) | | `merchant_category_code` | 否 | ISO 18245 MCC | | `extra_fields` | 否 | 任何 JSON 对象 — 已存储但未被 ML 使用 | **响应:** ``` { "transaction_id": "TXN-20241115-001", "risk_score": 0.7823, "ml_score": 0.8910, "rule_score": 0.5000, "risk_level": "HIGH", "is_approved": false, "decision_reason": "Transaction denied — high-severity rule(s) triggered: HIGH_AMOUNT", "triggered_rules": [ { "rule": "HIGH_AMOUNT", "description": "Amount ≥ 50,000 PHP", "severity": "HIGH", "score_contribution": 0.50 } ], "processing_ms": 12, "assessed_at": "2024-11-15T06:30:00.123Z" } ``` ### 标记交易 ``` POST /api/v1/transactions/{transaction_id}/label Content-Type: application/json X-API-Key: ``` ``` { "is_fraud": true, "fraud_type": "account_takeover", "notes": "Confirmed by customer — device not recognised" } ``` `fraud_type` 选项:`account_takeover`、`identity_theft`、`card_fraud`、`phishing`、`money_laundering`、`money_mule`、`synthetic_identity`、`friendly_fraud`、`other`。 ### 错误代码 | 状态 | 含义 | |--------|---------| | `401 Unauthorized` | 缺少或无效的 `X-API-Key` | | `409 Conflict` | `transaction_id` 已被评估 | | `422 Unprocessable Entity` | 请求体验证失败 | | `429 Too Many Requests` | 超出速率限制 | | `500 Internal Server Error` | 意外的服务器错误 | ### 处理拒绝 当 `is_approved: false` 时 — 拒绝交易。存储 `transaction_id`、`risk_score` 和 `decision_reason` 以供审计日志使用。 **不要**重试被拒绝的交易。重试相同的 ID 将返回 `409 Conflict`。如果客户对拒绝提出异议,请在仪表板中查看该交易,并在适当时将其标记为合法。 ## 欺诈检测规则 | 规则 | 触发条件 | 严重性 | |------|---------|---------| | `HIGH_AMOUNT` | 金额 ≥ 阈值(默认 50,000 PHP) | 高(硬拦截) | | `VELOCITY_TX_COUNT` | 同一发送方在时间窗口内 ≥ N 笔交易 | 高(硬拦截) | | `VELOCITY_AMOUNT` | 同一发送方在时间窗口内的总金额超过限制 | 高(硬拦截) | | `KNOWN_FRAUD_RECEIVER` | 接收方出现在已确认的欺诈交易中 | 高(硬拦截) | | `KNOWN_FRAUD_DEVICE` | 设备指纹出现在已确认的欺诈交易中 | 高(硬拦截) | | `KNOWN_FRAUD_IP` | IP 地址出现在已确认的欺诈交易中 | 高(硬拦截) | | `NIGHT_TRANSACTION` | 22:00–05:59 间的交易 | 中 | | `INTERNATIONAL` | 跨境交易 | 中 | | `ROUND_AMOUNT` | 10,000 的倍数且 ≥ 50,000 | 低 | 所有阈值均可在运行时通过设置 → 规则阈值进行配置。 ## ML 模型 ### 训练流程 1. 交易被评估并存储。 2. 分析员通过标签页或 `POST /api/v1/labels/{id}` 标记已确认的欺诈/合法交易。 3. 一旦存在 ≥ 50 条标记记录,触发训练:`POST /api/v1/ml/train`(或等待 10 个新标签后的自动重新训练)。 4. XGBoost 模型在 32 个特征上进行训练。 5. 未来的评估使用综合规则 + ML 分数。 ### 快速生成训练数据 ``` # 生成 5,000 笔真实交易(10% 欺诈) curl -X POST http://localhost:8000/api/v1/ml/simulate \ -H "X-API-Key: " \ -H "Content-Type: application/json" \ -d '{"count": 5000, "fraud_rate": 0.10, "include_labels": true}' \ -o training.jsonl # 上传到数据库 curl -X POST http://localhost:8000/api/v1/ml/upload-dataset \ -H "X-API-Key: " \ -F "file=@training.jsonl" # 训练 curl -X POST http://localhost:8000/api/v1/ml/train \ -H "X-API-Key: " ``` ## 运维手册 ### 首次启动后获取 API key ``` docker compose logs backend | grep "FIRST API KEY" ``` ### 重置所有内容(完全擦除) ``` docker compose down -v && docker compose up --build ``` ### 创建额外的 API key 1. 使用管理员凭据 `POST /api/v1/auth/login` → 获取 JWT 2. 使用该 JWT `POST /api/v1/api-keys/` → 复制 key(仅显示一次) ### 常见问题 | 症状 | 修复方法 | |---------|-----| | 后端崩溃:`column … does not exist` | `docker compose down -v && docker compose up` | | 仪表板显示 "Offline" | 检查后端是否正在运行;验证 API key | | 数据库重置后提示 "Invalid API key" | 从日志中获取新的 key | | 尽管有高 (HIGH) 规则,所有交易仍被批准 | ML 尚未训练(返回中性值 0.5);标记 ≥ 50 笔交易然后训练 | | 浏览器中出现 CORS 错误 | 设置 `ALLOWED_ORIGINS` 以匹配您的前端 URL | | 训练从未开始 | 检查 `docker compose logs backend` 是否有锁/Redis 错误 | ## 安全说明 - 账号、设备指纹和 IP 地址**绝不以明文形式存储** — 仅存储 HMAC-SHA256 哈希(当设置了 `HASH_SECRET` 时)或 SHA-256 哈希。 - API key 以 SHA-256 哈希形式存储。 - 在生产环境中设置 `ENV=production` — 如果 `SECRET_KEY`、`ADMIN_PASSWORD` 或 `HASH_SECRET` 处于不安全的默认值,应用程序将拒绝启动。 - CORS 限制为 `ALLOWED_ORIGINS` 中列出的来源。从不使用通配符 `*`。 - `/assess` 端点按 API key 进行速率限制(默认 120 次/分钟)。 ## 监管说明 旨在支持遵守 **BSP Circular 1213**(菲律宾中央银行欺诈管理系统要求)。所有交易和风险评分都持久化到 PostgreSQL 中,以满足所需的审计追踪。
标签:Apex, AV绕过, FastAPI, FinTech, PostgreSQL, Python, Redis, SvelteKit, TCP/UDP协议, WebSocket, XGBoost, 云计算, 交易验证, 仪表盘, 依赖分析, 反欺诈, 实时交易监控, 异常检测, 搜索引擎查询, 无后门, 机器学习, 欺诈检测, 欺诈预防, 测试用例, 电子支付, 网络安全, 规则引擎, 请求拦截, 逆向工具, 配置错误, 金融科技, 金融风控, 隐私保护, 风险评估系统, 风险评分, 黑名单