24 KiB
AI 合同平台 V2 数据安全与反爬虫方案
日期:2026-07-21
适用范围:AI 合同平台 V2 的 Contract Web、Contract API、AI Platform API、worker、Nginx/WAF、PostgreSQL、文件仓库、审计与发布质量门。
1. 背景和目标
V2 已经具备合同台账、模板起草、审查结果、条款推荐、法律全文库、知识库、AI Trace、文件仓库和报告下载等能力。上线后真正的数据安全风险不只是匿名爬虫访问公开页面,而是合法账号、被盗 Cookie、内部人员、多账号轮换或代理池持续抓取数据库中的高价值数据。
本方案目标:
- 降低合同、附件、审查报告、模板、条款规则、Prompt、知识库、AI Trace 被批量抓取和下载的概率。
- 让列表接口默认只暴露摘要,正文和敏感内容走详情接口并计量。
- 对搜索、详情、预览、下载、批量导出建立多维限流和每日出站预算。
- 对异常行为及时告警、冻结、审计,并提供管理员解封和临时放宽配额流程。
- 把反爬和数据出站控制纳入上线前 schema-check、smoke、安全扫描和接口压测。
非目标:
- 不承诺阻止用户截图、拍照或人工逐条复制。
- 不把
robots.txt、UA 黑名单或验证码作为核心防线。 - 不在本方案阶段直接删除既有业务字段或大改数据库;数据库变更需单独迁移评审。
2. 当前能力
已经具备:
- Contract Web 到 Contract API 有 proxy shared secret。
- AI Platform 有 service shared secret。
- 已有租户字段,合同、文件、知识库、AI Trace、质量动作等多数持久化查询具备租户过滤基础。
- Contract Web 使用 HMAC 签名 Cookie,HttpOnly,SameSite=Lax。
- 身份接口已有邮箱、IP、租户维度限流,主要覆盖登录、验证码、邀请。
- 合同、附件、批量附件、审查报告下载已有审计事件基础。
- 合同、文件、搜索等分页接口通常限制
page_size <= 100。 - 生产 Nginx 已有 IP 级限流、连接限制、HTTPS 和安全响应头。
- AI Trace 已有脱敏、保留、归档治理字段和 worker 基础。
3. 关键缺口
P0 缺口:
- 业务接口缺统一后端 RBAC 和对象级授权门,不能仅依赖前端菜单隐藏。
- 部分接口仍存在从请求参数传
role的兼容习惯,生产不能信任客户端角色。 - 后端需要使用可信身份上下文,不能裸信任外部传入的
X-Tenant-Id、X-User-Id。 - 缺统一业务 API 限流,当前 Nginx IP 限流只能挡粗暴洪泛,不能挡已登录慢速搬运。
- 缺按记录数、文件数、字节数计量的数据出站预算。
- 批量下载缺文件数和总字节硬限制。
- 模板、标准条款、审查规则、Prompt、知识库 chunk、法律全文等高价值资产需要摘要列表和详情计量。
- AI Trace、Prompt、知识库、审查规则属于管理资产,需要严格角色授权和低频配额。
- 下载审计需要补齐真实 user_id、tenant_id、IP 哈希、UA 哈希、字节数、trace id、数据分级。
- runtime/schema-check 尚未检查反滥用配置是否启用。
P1 缺口:
- 缺服务端 session 表、会话撤销、并发会话限制和风险会话冻结。
- 缺统一安全事件表、行为风险评分、管理员“数据安全中心”。
- Word/PDF 下载缺用户、租户、时间、trace id 水印。
- 缺异常访问告警、配额临时放宽和解封闭环。
P2 缺口:
- 可接入阿里云 WAF/Bot Management。
- 可引入设备指纹作为辅助风险信号。
- 可加入高风险导出审批、蜜罐资源标识、DLP 和泄露追踪。
4. 数据分级
| 等级 | 数据 | 访问原则 |
|---|---|---|
| S4 极高敏感 | 合同正文、附件、审查报告、签署证据、AI Trace 原始输入输出 | 详情和下载必须授权、计量、审计、限流 |
| S3 高敏感 | 模板正文、变量 schema、标准条款、审查规则、Prompt、知识库 chunk | 列表只返回摘要,正文走详情并计量 |
| S2 内部资产 | 法律全文、法规影响扫描、全局审计、质量动作 | 分页、角色限制、搜索和详情计量 |
| S1 普通元数据 | 标题、状态、分类、摘要、创建时间、负责人 | 可列表展示,但仍分页和限流 |
| S0 公开信息 | 健康检查、公开宣传内容 | 可公开,但仍走基础 WAF 和速率限制 |
原则:列表接口默认返回 S1 摘要;S3/S4 正文、完整 prompt、chunk、文件内容、报告内容都必须通过详情、预览、下载或导出接口单独授权和计量。
5. 威胁模型
重点防护对象:
- 匿名爬虫扫描公开路径。
- 已登录普通用户持续翻页下载。
- 被盗 Cookie 或共享账号批量导出合同、附件、报告。
- 同一租户多个账号轮换抓取。
- 多 IP 或代理池绕过单 IP 限流。
- 内部管理员批量导出 Prompt、AI Trace、知识库、审查规则。
- 直接调用 BFF/API 绕过前端按钮和菜单。
核心结论:只靠 Nginx IP 限流不够。必须在应用层按租户、用户、会话、IP、接口风险等级、数据分级和出站量做统一控制。
6. 高风险接口清单
Contract API:
GET /api/v1/contractsGET /api/v1/contracts/{contract_id}GET /api/v1/contracts/{contract_id}/downloadGET /api/v1/contracts/{contract_id}/review-reportGET /api/v1/filesGET /api/v1/files/{file_id}/previewGET /api/v1/files/{file_id}/downloadPOST /api/v1/files/batch-downloadGET /api/v1/searchGET /api/v1/templates/treeGET /api/v1/templates/{template_id}POST /api/v1/templates/{template_id}/draftGET /api/v1/legal-assets/*GET /api/v1/legal-fulltext/*POST /api/v1/legal-change-impacts/scanPOST /api/v1/legal/qaGET /api/v1/audit/*
AI Platform API:
GET /api/v1/audit/ai-runsGET /api/v1/audit/ai-runs/{run_id}GET /api/v1/prompt-templatesGET /api/v1/prompt-templates/{name}GET /api/v1/knowledge-documentsGET /api/v1/knowledge-documents/searchGET /api/v1/knowledge-import-batches/{batch_id}/documentsGET /api/v1/knowledge-import-batches/{batch_id}/chunksGET /api/v1/audit/quality-improvement-actionsGET /api/v1/runtime/trace-governance/*
Contract Web BFF:
/api/contract-platform/*/api/ai-platform/*
BFF 必须传递可信 session 上下文,不允许浏览器直接伪造用户、租户、角色。
7. 控制架构
建议采用十层防护:
- 可信身份上下文:Contract Web 从 HttpOnly session 解出 tenant/user/role,后端只接受 BFF 签名后的上下文。
- 后端 RBAC:每个 endpoint 绑定最小角色集合。
- 对象级授权:合同、文件、审查结果、模板草稿、AI Trace 必须检查 tenant_id 和权限关系。
- Endpoint risk policy:按接口定义数据等级、记录计量、字节计量、限流桶和默认动作。
- Redis 多维限流:按 user、tenant、session、IP 哈希、route、risk class 组合限流。
- 数据出站预算:按日统计记录数、文件数、字节数、S3/S4 详情次数。
- 下载授权:下载前创建短时 download grant,限制 jti、文件、用户、租户、过期时间和一次性使用。
- 审计和风险评分:每次 S3/S4 访问、搜索、导出、下载、429、403 都写安全事件。
- 告警与冻结:达到阈值后自动通知管理员,严重时临时冻结用户、会话或 IP 哈希。
- 水印与追踪:报告和 Word/PDF 下载增加用户、租户、时间、trace id 标记。
8. RBAC 和对象授权矩阵
| 能力 | admin | legal | business | approver | observer | 说明 |
|---|---|---|---|---|---|---|
| 合同列表摘要 | 是 | 是 | 是 | 是 | 只读 | 只能本租户 |
| 合同详情正文 | 是 | 是 | 相关合同 | 审批相关 | 可配置 | S4 计量 |
| 合同下载 | 是 | 是 | 相关合同 | 审批相关 | 默认否 | S4 计量和水印 |
| 附件预览下载 | 是 | 是 | 相关合同 | 审批相关 | 默认否 | S4 字节预算 |
| 批量下载 | 是 | 是 | 默认否 | 默认否 | 否 | 单次硬限制 |
| 模板正文 | 是 | 是 | 起草可用模板 | 否 | 只读摘要 | S3 计量 |
| 条款规则管理 | 是 | 是 | 否 | 否 | 只读摘要 | 发布下线审计 |
| 法律全文 | 是 | 是 | 是 | 是 | 只读 | S2,可较宽松 |
| Prompt | admin | 否 | 否 | 否 | 否 | S3 管理资产 |
| AI Trace 详情 | admin | 指定审计员 | 否 | 否 | 否 | S4,强脱敏 |
| 全局审计 | admin | 指定审计员 | 否 | 否 | 否 | S2 |
| 用户租户管理 | admin | 否 | 否 | 否 | 否 | 超管另行区分 |
生产环境禁止客户端通过 query/body 指定自己的 role。兼容字段如需保留,应仅用于日志观测或被后端忽略。
9. 限流和出站预算初值
以下为可配置默认值,不应写死:
| 类型 | 用户级 | 租户级 | 说明 |
|---|---|---|---|
| 普通列表 | 60 次/分钟 | 600 次/分钟 | S1 摘要 |
| 搜索 | 20 次/分钟 | 200 次/分钟 | 统一搜索、知识库检索 |
| S3/S4 详情 | 30 次/分钟 | 300 次/分钟 | 计入每日记录预算 |
| 单文件下载 | 10 次/分钟 | 100 次/分钟 | 计入字节预算 |
| 批量下载 | 2 次/小时 | 20 次/小时 | 单次最多 20 个文件、100 MB |
| 合同报告下载 | 10 次/小时 | 100 次/小时 | 计入报告预算 |
| Prompt/AI Trace 详情 | 10 次/分钟 | 100 次/分钟 | 仅管理角色 |
| 法律全文详情 | 60 次/分钟 | 600 次/分钟 | S2,可较宽松 |
| 法律问答 | 10 次/分钟 | 100 次/分钟 | 同时受 AI 成本预算约束 |
每日预算建议:
- S3/S4 详情记录:普通用户 1000 条/天,法务 3000 条/天,管理员可配置。
- 下载文件数:普通用户 50 个/天,法务 200 个/天。
- 下载字节数:普通用户 500 MB/天,法务 2 GB/天。
- 批量下载:普通用户默认关闭,法务 5 次/天,管理员 10 次/天。
- 达到 70% 提示,90% 告警,100% 阻断或要求管理员放行。
429 响应必须带 Retry-After。高风险异常可以返回 403 并写安全事件。
10. 数据库设计建议
后续迁移建议新增:
security_access_events
记录每次高风险访问。
关键字段:
idtenant_iduser_idsession_id_haship_hashua_hashroute_keyhttp_methodresource_typeresource_iddata_classrecords_countbytes_countdecisionreason_codetrace_idcreated_at
data_egress_ledger
记录每日出站预算消耗。
关键字段:
tenant_iduser_iddatedata_classrecords_countfiles_countbytes_countreports_countupdated_at
security_incidents
记录风险评分后的事件。
关键字段:
idtenant_iduser_idseverityincident_typesignalsstatusassigned_tocreated_atresolved_at
security_blocks
记录临时冻结。
关键字段:
iddimensionsubject_hashtenant_iduser_idreasonstarts_atexpires_atcreated_byreleased_byrelease_reason
tenant_security_policies
租户级安全策略。
关键字段:
tenant_idpolicy_jsonrisk_modedownload_watermark_enabledbatch_download_enabledupdated_byupdated_at
download_grants
短时下载授权。
关键字段:
jtitenant_iduser_idresource_typeresource_idscopeexpires_atused_atbytes_limitcreated_at
可选:
user_sessions:服务端会话、撤销、并发限制、设备信息、风险状态。
原始 IP 和 UA 不入库,统一使用独立 security secret 做 HMAC 哈希。
11. Redis key 设计
建议 key:
abuse:rate:{tenant}:{user}:{route}:{window}abuse:tenant:{tenant}:{route}:{window}abuse:ip:{ip_hash}:{route}:{window}abuse:session:{session_hash}:{route}:{window}egress:records:{tenant}:{user}:{date}:{data_class}egress:files:{tenant}:{user}:{date}egress:bytes:{tenant}:{user}:{date}abuse:block:{dimension}:{subject_hash}download:grant:{jti}
Redis 不可用时的策略:
- production 默认 fail closed 或 degrade strict,即高风险下载、批量下载、AI Trace、Prompt 详情不可用。
- smoke/local 可 fail open 并记录 warning,方便开发。
12. Nginx 和 WAF 建议
Nginx 不只做全站一个限流区,应按风险分区:
read_low:普通页面、摘要列表。read_search:搜索、法律全文检索、知识库检索。read_sensitive:合同详情、模板详情、Prompt 详情、AI Trace 详情。download_single:单文件、合同 Word/PDF、审查报告。download_batch:批量打包下载。auth:登录、验证码、邀请、密码重置。
建议:
- 生产只对外暴露 Contract Web 和 HTTPS edge。
- Contract API、AI Platform API 绑定内网或 loopback,经 BFF/网关访问。
- 高风险路径设置更低
rate和更小burst。 - 下载路径限制并发连接数和最大请求体。
- 记录 request id、upstream time、status、bytes_sent、user agent 哈希所需原始信号。
- 阿里云 WAF/Bot Management 可作为 P2 叠加层,拦截已知恶意 IP、代理、异常 UA 和自动化特征。
13. 下载授权和水印
下载流程:
- 用户点击下载。
- BFF 带可信 session 请求 Contract API 创建 download grant。
- Contract API 做 RBAC、对象授权、限流、预算、冻结状态检查。
- 通过后生成短时 grant,记录审计。
- 实际下载必须携带 grant jti,且一次性使用或短期有效。
- 下载完成写入
bytes_count和结果状态。
水印:
- Word/PDF 页脚或末尾加入租户名、用户邮箱脱敏、下载时间、trace id。
- 审查报告和合同导出默认启用水印。
- 原始附件如不能修改内容,至少文件名、压缩包清单、下载审计中保留 trace id。
14. 行为风险评分
风险信号:
- 短时间翻页过快。
- 合同详情命中率异常高。
- 下载量或字节数快速增长。
- 搜索关键字枚举特征明显。
- 多账号同租户同 IP 或同 UA 轮换访问。
- 同账号多 IP 快速切换。
- 访问被隐藏菜单或无 UI 入口的管理 API。
- 重复触发 429 后继续请求。
- 夜间或非工作时间大量下载。
动作:
- 低风险:提示或降低速率。
- 中风险:写 incident、通知管理员、要求重新登录。
- 高风险:冻结 session 或用户,阻断 S3/S4 接口。
- 严重风险:冻结租户批量下载、通知超级管理员。
管理员需要能查看、解封、临时放宽配额,所有操作写审计。
15. 分阶段实施计划
P0:公开 SaaS 上线前必须完成
- 建立 endpoint risk policy 注册表,覆盖 Contract API、AI Platform API 和 BFF 高风险路由。
- Contract API 和 AI Platform API 增加统一 anti-abuse middleware。
- 统一可信身份上下文,生产禁止信任客户端 role。
- 接入 Redis 多维限流,支持 user、tenant、session、IP 哈希、route。
- 建立数据出站预算,先在 Redis 计量,再落库审计。
- 文件、合同、报告、批量下载增加硬限制、预算和安全审计。
- 模板、条款、规则、Prompt、知识库 chunk、法律全文列表改为摘要优先,正文走详情。
- AI Trace、Prompt、知识库管理接口收紧到 admin/legal 指定角色。
- runtime/schema-check 增加反滥用配置检查:Redis、security secret、risk policy、download limits。
- Nginx 分风险路径限流。
- 安全测试覆盖租户隔离、越权、批量下载、配额阻断和 429。
P1:上线后第一阶段增强
- 服务端 session 表、撤销和并发会话限制。
- 数据安全中心管理页。
- Word/PDF 水印和下载 trace id。
- 安全事件、incident、block、解封流程落库。
- 告警接入邮件、企业微信或钉钉。
- 租户级安全策略配置。
P2:商业化和高安全客户增强
- 阿里云 WAF/Bot Management。
- 设备指纹风险信号。
- 高风险导出审批。
- 蜜罐资源标识和泄露追踪。
- DLP、字段级脱敏策略、客户自定义配额。
16. 灰度和回滚
灰度策略:
ANTI_ABUSE_ENABLED=false|observe|enforceDATA_EGRESS_BUDGET_ENABLED=false|observe|enforceDOWNLOAD_GRANT_REQUIRED=false|trueSENSITIVE_LIST_SUMMARY_ONLY=false|true
推荐顺序:
- 本地和 smoke 开
observe,只记录不阻断。 - smoke 压测确认 429 比例、误伤率和 Redis 性能。
- production 先对下载和 AI Trace 开 enforce。
- 再对搜索、详情、Prompt、知识库开 enforce。
回滚:
- middleware 支持环境变量快速退回 observe。
- Redis 限流异常时可临时关闭高风险接口或切 strict fallback。
- 数据库迁移只新增表和字段,不影响老业务读写。
- Nginx 分区限流可单独回滚到旧配置。
17. 验收测试
安全测试:
- A 租户用户无法访问 B 租户合同、文件、审查结果、AI Trace。
- 普通用户不能访问 Prompt、AI Trace、全局审计、规则管理详情。
- 修改 URL/ID 访问他人文件返回 403 或 404。
- 批量下载超过文件数或字节数返回 429/403。
- 达到每日预算后详情、下载被阻断,列表摘要仍可用。
- 客户端传
role=admin不影响后端授权。 - Redis 不可用时 production 高风险接口按策略阻断。
性能测试:
- 普通列表 p95 < 800ms。
- 搜索和模板树 p95 < 1200ms。
- anti-abuse middleware 单请求额外开销 p95 < 30ms。
- Redis 连接池无耗尽。
- 30 分钟压测无内存持续上涨。
误封测试:
- 正常法务连续处理 50 份合同不触发冻结。
- 正常下载 10 个附件不触发冻结。
- 达到 70%/90% 预算时只提示和告警,不提前阻断。
- 管理员临时放宽配额后立即生效且有审计。
18. 与当前上线计划关系
当前 V2 可以继续内部 UAT 或受控 smoke 验证,但如果目标是公开多租户 SaaS 或承载真实客户合同数据,不建议只靠现有 Nginx 限流直接上线。
生产上线建议门槛:
- 至少完成 P0。
- 跑安全扫描、接口压测、Docker smoke、schema-check。
- 完成租户隔离和越权测试。
- 下载、搜索、AI Trace、Prompt、知识库路径全部纳入 risk policy。
- 形成数据安全回归报告。
最建议的第一片实现:
endpoint risk policy+anti-abuse middleware。- Redis 多维限流。
- 下载和批量下载出站预算。
- Prompt、AI Trace、知识库、模板正文等 S3/S4 详情计量。
- runtime/schema-check 增加反滥用配置检查。
这片能最快把“可被批量抓取”变成“可计量、可阻断、可审计、可告警”。
19. P0 第一片落地记录
日期:2026-07-22
已完成:
- Contract API 新增 endpoint risk policy 和 anti-abuse middleware。
- AI Platform API 新增 endpoint risk policy 和 anti-abuse middleware。
- 支持
disabled / observe / enforce三种模式。 - 命中高风险接口时返回
X-Anti-Abuse-Mode、X-Anti-Abuse-Decision、X-Anti-Abuse-Policy、X-Data-Class响应头。 enforce模式下超过当前策略阈值返回 429,并带Retry-After。- 当前第一片使用进程内滑动窗口限流,适合本地、测试和 smoke 验证行为;生产长期稳定运行仍需接 Redis。
- Contract API runtime config-check 和 schema-check 已输出
anti_abuse/anti_abuse_runtime。 - AI Platform schema-check 已输出
anti_abuse_runtime,即使 memory repository 模式也会报告该安全门。 .env.example和 production compose env 示例已增加反滥用配置。
本片覆盖的高风险路径:
- Contract API:合同列表、合同详情、合同下载、审查报告、文件列表、文件详情、文件预览、文件下载、批量下载、统一搜索、模板树、模板详情、条款规则、法律全文、法律问答、审计路径。
- AI Platform API:AI Trace 列表/详情、质量动作、Prompt 列表/变更、知识库文档、知识库文档 chunk、知识库搜索、知识库批次文档/chunk、Trace governance。
下一片建议:
- 将
InMemorySlidingWindowLimiter替换为 Redis 多维限流实现,支持 user、tenant、session、IP hash、route 维度。 - 建立
security_access_events和data_egress_ledger,把当前内存事件落库。 - 给文件下载、合同 Word/报告下载、批量下载接入文件数和字节预算。
- BFF 透传可信 user/session 上下文,逐步禁止后端信任客户端传入的 role。
20. P0 第二片落地记录
日期:2026-07-22
已完成:
- Contract API 和 AI Platform API 的 anti-abuse guard 支持 Redis 滑动窗口限流。
- Redis 不可用或未配置时自动回退到进程内滑动窗口,local/test 不阻断开发;staging/production 的 runtime check 会要求反滥用配置启用并配置 Redis。
- 两个服务均新增
security_access_events和data_egress_ledger模型与 Alembic 迁移。 - middleware 命中高风险路径后会写入安全访问事件;S3/S4 访问会累计每日数据出站账本。
- Contract API schema-check 已将两张安全表纳入核心表检查。
- AI Platform schema-check 已将两张安全表纳入核心表和 tenant 列检查。
- Python 依赖增加
redis>=5.0。
新增迁移:
- Contract API:
20260722_0032_add_security_access_events.py - AI Platform API:
20260722_0022_add_security_access_events.py
当前边界:
- 本片已经做到“可计量、可审计、可 Redis 限流”。
- 数据出站预算目前先累计,不直接按每日预算阻断;预算阈值阻断应作为下一片实现。
- 安全事件查询/管理页还未做,后续可进入“数据安全中心”。
下一片建议:
- 增加每日记录数、文件数、字节数预算检查,超过阈值时返回 429/403。
- 批量下载增加单次文件数和总字节硬限制。
- BFF 透传 session id hash,安全事件补
session_id_hash。 - 增加管理端安全事件列表和租户安全策略配置。
21. P0 第三片落地记录
日期:2026-07-23
已完成:
- Contract API 与 AI Platform API 的
check_egress_budget(...)从“只看既有账本是否已达阈值”升级为“既有账本 + 本次请求投影”判断,超过每日预算时返回 403。 - S3/S4 records 预算开始按
page_size/limit估算本次出站记录数,避免分页列表、知识库检索、AI Trace 列表按 1 次请求低估爬取量。 - Contract API 文件下载、合同 Word 下载、审查报告下载接入
reserve_egress_budget(...),在返回内容前累计每日文件数与字节数。 - 批量下载保持仓储层单次硬限制:
CONTRACT_API_BATCH_DOWNLOAD_MAX_FILES,默认 20。CONTRACT_API_BATCH_DOWNLOAD_MAX_BYTES,默认 100 MiB。
- 配置示例补齐每日 records/files/bytes 预算和批量下载硬上限:
- Contract API
.env.example - AI Platform
.env.example - compose
.env.example - compose
.env.production.example
- Contract API
- 回归测试覆盖:
- S4 详情路径达到每日记录预算后返回 403。
- 文件下载成功后累计
files_count与bytes_count。 - 文件下载超过每日字节预算返回 403。
- 批量下载超过单次文件数硬上限返回 409。
- AI Platform 知识库列表按
limit投影每日记录预算。
当前边界:
- 批量下载的单次硬上限已经在仓储层前置执行;每日预算按生成后的 zip 实际字节数入账。
- 列表类 records 预算采用请求参数估算,属于偏保守策略:空页也可能计入请求额度,但能更有效阻断枚举式爬取。
- 下一片建议补“安全事件/出站账本管理页 + 租户级安全策略配置”,让运营可以查看、调整、临时放宽或封禁。