@deployxai/dxc 0.1.0
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.
- package/README.md +131 -0
- package/dist/chunks/chunk-I6VZLNRZ.js +2118 -0
- package/dist/chunks/chunk-XIHX5YAF.js +16391 -0
- package/dist/chunks/knowledge-Q6MHPG6I.js +1248 -0
- package/dist/chunks/monitor-VPRVRQIS.js +694 -0
- package/dist/index.js +32367 -0
- package/docs/00-project-context.md +125 -0
- package/docs/01-north-star-architecture.md +234 -0
- package/docs/02-mvp-technical-design.md +553 -0
- package/docs/03-domain-state-api.md +599 -0
- package/docs/04-security-and-operations.md +413 -0
- package/docs/05-delivery-plan.md +407 -0
- package/docs/README.md +44 -0
- package/docs/decisions/0001-initial-architecture.md +57 -0
- package/docs/decisions/0002-mongodb-environment-boundary.md +42 -0
- package/docs/decisions/0003-staged-production-topology.md +33 -0
- package/docs/decisions/0004-local-first-agent-research-runtime.md +71 -0
- package/docs/decisions/0005-official-skill-orchestration-and-local-content-memory.md +97 -0
- package/docs/decisions/0006-separate-wechat-user-login-from-account-authorization.md +87 -0
- package/docs/decisions/0007-explicit-personal-wechat-start.md +67 -0
- package/docs/decisions/0008-end-to-end-content-workflow-continuity.md +115 -0
- package/docs/decisions/0009-privileged-multitenant-draft-scheduling.md +36 -0
- package/docs/decisions/0009-versioned-cloud-template-catalog.md +39 -0
- package/docs/eight-stage-implementation-audit.md +62 -0
- package/docs/first-user-guide.md +187 -0
- package/docs/history/content-forge-prd-v0.2-summary.md +81 -0
- package/docs/local-development.md +511 -0
- package/docs/references/aliyun-oss-production-setup.md +89 -0
- package/docs/references/legacy-content-to-wechat-contract.md +223 -0
- package/docs/references/renderer-compatibility-report.md +68 -0
- package/docs/references/source-inventory.md +179 -0
- package/docs/references/wechat-renderer-platform-validation.md +92 -0
- package/docs/references/wechat-third-party-platform-setup.md +159 -0
- package/docs/references/wechat-website-login-setup.md +137 -0
- package/docs/references/wemd-template-attribution.md +25 -0
- package/docs/research-monitoring-design.md +235 -0
- package/docs/todo-preview-local-first.md +31 -0
- package/docs/workbuddy-first-user-runbook.md +246 -0
- package/docs//345/221/230/345/267/245BCDE/347/232/204skill/employee-b-research-analyst/SKILL.md +230 -0
- package/docs//345/221/230/345/267/245BCDE/347/232/204skill/employee-c-outline-architect/SKILL.md +194 -0
- package/docs//345/221/230/345/267/245BCDE/347/232/204skill/employee-d-content-writer/SKILL.md +296 -0
- package/docs//345/221/230/345/267/245BCDE/347/232/204skill/employee-e-visual-designer/SKILL.md +268 -0
- package/package.json +25 -0
- package/skills/dxc-article-outline/SKILL.md +82 -0
- package/skills/dxc-article-outline/agents/openai.yaml +6 -0
- package/skills/dxc-article-outline/references/outline-methods.md +38 -0
- package/skills/dxc-article-write/SKILL.md +85 -0
- package/skills/dxc-article-write/agents/openai.yaml +6 -0
- package/skills/dxc-article-write/references/writing-methods.md +42 -0
- package/skills/dxc-content-brief/SKILL.md +81 -0
- package/skills/dxc-content-brief/agents/openai.yaml +6 -0
- package/skills/dxc-content-brief/references/brief-method.md +34 -0
- package/skills/dxc-content-review/SKILL.md +84 -0
- package/skills/dxc-content-review/agents/openai.yaml +6 -0
- package/skills/dxc-content-review/references/review-checklist.md +35 -0
- package/skills/dxc-content-workflow/SKILL.md +190 -0
- package/skills/dxc-content-workflow/agents/openai.yaml +6 -0
- package/skills/dxc-content-workflow/references/catalog.json +136 -0
- package/skills/dxc-content-workflow/references/onboarding-questions.md +107 -0
- package/skills/dxc-content-workflow/references/stage-contract.md +70 -0
- package/skills/dxc-research/SKILL.md +110 -0
- package/skills/dxc-research/agents/openai.yaml +6 -0
- package/skills/dxc-research/references/research-method.md +53 -0
- package/skills/dxc-title-write/SKILL.md +112 -0
- package/skills/dxc-title-write/agents/openai.yaml +6 -0
- package/skills/dxc-title-write/references/title-methods.md +26 -0
- package/skills/dxc-visual-plan/SKILL.md +119 -0
- package/skills/dxc-visual-plan/agents/openai.yaml +6 -0
- package/skills/dxc-visual-plan/references/visual-methods.md +35 -0
- package/skills/dxc-wechat-publisher/SKILL.md +157 -0
- package/skills/dxc-wechat-publisher/agents/openai.yaml +6 -0
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
# 安全、隐私与运维边界
|
|
2
|
+
|
|
3
|
+
更新日期:2026-07-27
|
|
4
|
+
|
|
5
|
+
## 1. 安全目标
|
|
6
|
+
|
|
7
|
+
DxC 必须同时保护:
|
|
8
|
+
|
|
9
|
+
- 平台级微信第三方平台凭据;
|
|
10
|
+
- 每个租户的 authorizer token;
|
|
11
|
+
- 微信支付商户凭据和订单;
|
|
12
|
+
- 用户文章、图片和预览;
|
|
13
|
+
- 设备会话;
|
|
14
|
+
- 多租户数据边界;
|
|
15
|
+
- 草稿创建等不可逆副作用。
|
|
16
|
+
|
|
17
|
+
安全设计默认假设:Agent 上下文、终端输出、日志系统、对象存储 URL 和数据库备份都有被误分享的可能。因此敏感数据不应依赖“大家不会看到”来保护。
|
|
18
|
+
|
|
19
|
+
## 2. 数据分类
|
|
20
|
+
|
|
21
|
+
| 级别 | 示例 | 处理规则 |
|
|
22
|
+
|---|---|---|
|
|
23
|
+
| S0 公开 | 官网文案、公开安装说明、模板版本 | 可公开 |
|
|
24
|
+
| S1 内部 | 聚合指标、无正文任务状态、非敏感配置 | 认证访问 |
|
|
25
|
+
| S2 租户内容 | Markdown、图片、预览、公众号展示信息 | 租户隔离、传输/存储加密、保留期限 |
|
|
26
|
+
| S3 凭据 | authorizer refresh token、本地设备 refresh token、支付通知解密材料 | authorizer 字段级加密;设备明文只在 `0600` 本地文件、Server 仅存哈希;绝不记录 |
|
|
27
|
+
| S4 平台根秘密 | Component AppSecret、网站应用 AppSecret、EncodingAESKey、微信 API 对称密钥/RSA 私钥、支付私钥、KMS 权限 | 只在 Secret/KMS Provider 中,禁止进入数据库和应用日志 |
|
|
28
|
+
|
|
29
|
+
## 3. 密钥管理
|
|
30
|
+
|
|
31
|
+
### 3.1 平台根秘密
|
|
32
|
+
|
|
33
|
+
以下内容不得写入 Mongo:
|
|
34
|
+
|
|
35
|
+
- 微信第三方平台 AppSecret;
|
|
36
|
+
- 微信网站应用 AppSecret;
|
|
37
|
+
- Token;
|
|
38
|
+
- EncodingAESKey;
|
|
39
|
+
- 微信 API 安全对称密钥和应用 RSA 私钥;
|
|
40
|
+
- SkillHub 开发者私钥;
|
|
41
|
+
- 微信支付 API 私钥和证书材料;
|
|
42
|
+
- Mongo 口令;
|
|
43
|
+
- 对象存储访问密钥;
|
|
44
|
+
- 加密主密钥。
|
|
45
|
+
|
|
46
|
+
应用只通过 `SecretProvider` 获取逻辑名称,例如:
|
|
47
|
+
|
|
48
|
+
```text
|
|
49
|
+
wechat/component/app-secret
|
|
50
|
+
wechat/website-login/app-secret
|
|
51
|
+
wechat/component/encoding-aes-key
|
|
52
|
+
wechat/api-security/aes-key
|
|
53
|
+
wechat/api-security/rsa-private-key
|
|
54
|
+
skillpay/developer-private-key
|
|
55
|
+
wechat-pay/api-private-key
|
|
56
|
+
storage/access-credential
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
生产绑定到受控 Secret Manager/KMS。开发环境使用无真实值的 `.env.example` 和本地测试替身;真实 `.env` 永不提交。
|
|
60
|
+
|
|
61
|
+
### 3.2 租户凭据加密
|
|
62
|
+
|
|
63
|
+
authorizer refresh/access token 使用 envelope encryption(信封加密):
|
|
64
|
+
|
|
65
|
+
1. 每条授权记录生成随机 DEK(数据密钥);
|
|
66
|
+
2. 内容使用 AES-256-GCM 加密;
|
|
67
|
+
3. DEK 由 KMS/KeyProvider 管理的 KEK(密钥加密密钥)封装;
|
|
68
|
+
4. 数据库存储密文、IV、认证标签、封装 DEK 和 `keyVersion`;
|
|
69
|
+
5. AAD(附加认证数据)绑定 `tenantId + authorizationId + fieldName`。
|
|
70
|
+
|
|
71
|
+
解密只允许在 token service 内完成,明文不返回路由层、不进入领域事件。
|
|
72
|
+
|
|
73
|
+
密钥轮换:
|
|
74
|
+
|
|
75
|
+
- 新写入立即使用当前版本;
|
|
76
|
+
- 读取旧版本后可以后台重加密;
|
|
77
|
+
- 轮换任务记录数量和版本,不记录明文;
|
|
78
|
+
- 旧 KEK 在确认所有记录迁移和备份过期前不能删除。
|
|
79
|
+
|
|
80
|
+
## 4. 微信回调安全
|
|
81
|
+
|
|
82
|
+
第三方平台回调必须按顺序:
|
|
83
|
+
|
|
84
|
+
1. 限制方法、Content-Type 和最大 Body;
|
|
85
|
+
2. 读取原始请求体;
|
|
86
|
+
3. 校验时间戳在允许窗口内;
|
|
87
|
+
4. 校验 nonce/replay key 未被处理;
|
|
88
|
+
5. 校验 `msg_signature`;
|
|
89
|
+
6. 解密 AES 内容;
|
|
90
|
+
7. 校验解密后的 AppID 等于本平台 Component AppID;
|
|
91
|
+
8. 解析白名单事件类型;
|
|
92
|
+
9. 使用事件业务键幂等落库;
|
|
93
|
+
10. 在微信要求的时间内返回固定响应。
|
|
94
|
+
|
|
95
|
+
步骤 4 的 replay claim(重放占位)只有在验签、解密、白名单解析和同步持久化均成功后才保留;在形成可恢复的持久化结果前失败时必须释放本次占位,让微信可以安全重试。持久化成功后的异步任务失败不得释放占位或要求微信重推。
|
|
96
|
+
|
|
97
|
+
网页授权回跳另有一次性授权码边界:Server 必须先用 compare-and-set(比较并更新)把本地会话从 `URL_READY` 认领为 `EXCHANGING`,再调用 `api_query_auth`。授权结果只以应用层加密形式写入 `AUTHORIZED` 检查点;账号、授权记录和设备身份随后幂等投影。若进程在微信已消费授权码、但检查点尚未确认时中断,重放回调不得盲目再次交换;会话保持 `EXCHANGING`,到期后标记 `FAILED` 并提示重新扫码。
|
|
98
|
+
|
|
99
|
+
个人微信网站登录使用另一条回调和状态机。Server 先原子认领 OAuth code,再向网站登录
|
|
100
|
+
接口交换身份;微信返回的 OAuth access/refresh token 只停留在适配器内存中,解析
|
|
101
|
+
openid/unionid 后立即丢弃。`IDENTIFIED` 检查点只保存由 Website AppID 作用域化的
|
|
102
|
+
SHA-256 摘要。回调重放不得再次交换 code;同一摘要只能关联一个 `userId + tenantId`。
|
|
103
|
+
普通 `purpose=login` 对未关联身份固定失败,只有用户主动执行、页面明确说明会创建内容
|
|
104
|
+
空间的 `purpose=start` 才可首次建租户;同一摘要的并发 start 使用确定性候选 UUID 和
|
|
105
|
+
Mongo 原子 bootstrap 收敛。网站应用 AppID/AppSecret、URL 和 OAuth token 不得与
|
|
106
|
+
第三方平台 Component 凭据、公众号 authorizer token 或 API 安全 RSA/AES 材料混用。
|
|
107
|
+
|
|
108
|
+
禁止:
|
|
109
|
+
|
|
110
|
+
- 在验签前解析并信任业务字段;
|
|
111
|
+
- 将完整 XML 写入日志;
|
|
112
|
+
- 因内部异步任务失败而反复让微信重推同一已接收事件;
|
|
113
|
+
- 把未知事件当作授权成功。
|
|
114
|
+
|
|
115
|
+
支付通知同样需要官方签名验证、证书序列号校验、报文解密、重放保护和幂等事件 ID。
|
|
116
|
+
|
|
117
|
+
### 4.1 微信出站 API 安全
|
|
118
|
+
|
|
119
|
+
第三方平台在微信后台开启“全部 API 加密及签名校验”后,所有支持该协议的 JSON API 必须使用安全模式:
|
|
120
|
+
|
|
121
|
+
1. 用微信要求的 AAD(附加认证数据)和 AES-256-GCM 加密最终 JSON 正文;
|
|
122
|
+
2. 用应用 RSA 私钥按 RSA-SHA256-PSS 对最终请求原文签名,PSS salt(盐值)长度固定为 32 字节;
|
|
123
|
+
3. 只携带 `Wechatmp-AppId`、`Wechatmp-TimeStamp`、`Wechatmp-Signature` 三个安全请求头,不发送 `Wechatmp-Serial`;
|
|
124
|
+
4. 响应按平台证书序列号选取受信证书,轮换窗口同时识别当前和 Deprecated(即将弃用)签名头,再验证 RSA-PSS 签名;
|
|
125
|
+
5. 只有验签成功后才解析、解密或信任响应业务字段。
|
|
126
|
+
|
|
127
|
+
`Wechatmp-AppId`、加密正文中的 `_appid`、AAD 和签名基串必须统一使用第三方平台 Component AppID。即使 URL query 中携带 authorizer access token,也不能切换为公众号 AppID。第三方平台管理接口是否使用安全模式不按 `component_access_token` 推断,而按官方端点契约显式选择。
|
|
128
|
+
|
|
129
|
+
2026-07-26 根据官方端点契约和真实平台探测确定的支持矩阵:
|
|
130
|
+
|
|
131
|
+
| 接口类别 | 传输协议 |
|
|
132
|
+
| --- | --- |
|
|
133
|
+
| `api_component_token`、`api_create_preauthcode`、`api_query_auth`、`api_get_authorizer_info`、`api_authorizer_token` | 普通 HTTPS JSON;不发送或要求 `Wechatmp-*` |
|
|
134
|
+
| `draft/add`、`draft/get` | RSA-PSS 签名、AES-256-GCM 正文加密、响应验签解密 |
|
|
135
|
+
| `material/add_material` | 普通 HTTPS multipart;不发送或要求 `Wechatmp-*` |
|
|
136
|
+
| `media/uploadimg` | 普通 HTTPS multipart;不发送或要求 `Wechatmp-*`;返回的 HTTPS URL 只用于当前快照正文替换 |
|
|
137
|
+
|
|
138
|
+
未在矩阵中的接口必须先查官方契约并完成假服务测试和真实无副作用探测,不能自动归入任一模式。
|
|
139
|
+
|
|
140
|
+
当前现场直接探测证据包括:
|
|
141
|
+
|
|
142
|
+
- `api_component_token` 对加密信封返回普通 JSON 错误响应,且没有 `Wechatmp-*` 响应头;
|
|
143
|
+
- `batchget_material` 使用 authorizer AppID 签名时返回无安全响应头的明文 `40237`,改用 Component AppID 后返回可验签、可解密的成功响应。
|
|
144
|
+
- `material/add_material` 对空文件和截断 PNG 发送无效载荷:按完整含零字节正文签名返回 `40234`,改为签首个零字节前缀后返回 `40097`;完全不带 `Wechatmp-*` 的同一截断 PNG 返回 `40113` 文件类型错误,证明普通 multipart 能进入正确的素材解析路径。两次有效 PNG 的签名上传均返回 `40097`,只读对账确认素材总数和同名新增均未变化。
|
|
145
|
+
|
|
146
|
+
因此安全模式身份固定为 Component AppID,与 query 中的 token 类型无关。完全缺少全部安全响应头时,仅明文 JSON `errcode` 位于 `40230`–`40240` 的安全层拒绝可作为确定性未执行;客户端只保存错误码,不传播 `errmsg`。其他无签名 JSON 中的整数 `errcode` 只允许作为不可验证错误的脱敏诊断后缀保留,不能改变不确定状态、触发重试或驱动业务决策。无签名成功响应、非 JSON 或只缺部分安全头的响应仍不可验证。其余四个第三方平台管理接口按同组官方契约实现,仍需在各自首次真实调用时保留安全失败闸门和脱敏观测。
|
|
147
|
+
|
|
148
|
+
截至 2026-07-26,DxC 依据微信官方服务端 API 签名指南的请求头表和 RSA 示例,只发送 AppID、时间戳和签名。应用非对称密钥编号保留为本地受控配置,不作为 RSA 请求头发送;API AES 密钥序列号只进入 AAD;响应中的 `Wechatmp-Serial` 始终用于识别微信平台证书,不能与前两类编号混用。
|
|
149
|
+
|
|
150
|
+
资源上传使用 `multipart/form-data`(多部分表单)。微信规则明确资源上传类 API 不支持
|
|
151
|
+
正文加密;2026-07-26 真实平台又确认,对 `material/add_material` 添加 RSA 安全头会让含
|
|
152
|
+
零字节的二进制 multipart 在安全网关后变成 `40097`,而同一无效文件不带安全头时能被
|
|
153
|
+
业务端识别为 `40113`。因此永久封面的 `material/add_material` 和正文图片的
|
|
154
|
+
`media/uploadimg` 都按各自官方端点契约使用普通 HTTPS multipart:完整发送文件和
|
|
155
|
+
boundary(边界),只携带标准内容头,不发送或要求 `Wechatmp-*`。成功和业务错误响应
|
|
156
|
+
仍必须经过大小限制和运行时 schema(结构)校验;`media/uploadimg` 还必须返回 HTTPS
|
|
157
|
+
URL,且该 URL 只能替换当前不可变快照中匹配的逻辑路径。网络错误、超时、不可解析响应
|
|
158
|
+
或无法证明上传结果时进入 `ASSET_UPLOAD_UNVERIFIED`,停止 `draft/add` 且不自动重试。
|
|
159
|
+
`media/uploadimg` 已完成假服务契约测试,但截至 2026-07-30 尚未做真实公众号现场验证;
|
|
160
|
+
生产启用前必须关闭这一闸门。
|
|
161
|
+
|
|
162
|
+
同日真实 `draft/add` 已通过 RSA 验签和 AES 解密进入业务层。固定作者“DeployX 内容工作台”返回确定性 `45110 author size out of limit`;只读 `draft/batchget` 确认草稿箱总数仍为 1 且没有同标题测试草稿。受控联调文章因此将作者缩短为 `DxC`,并生成新的不可变快照重新请求用户确认。此前已经确认上传成功的固定联调封面 MediaID 只能由同一租户、同一账号且 `coverHash` 相同的新意图复用,避免因正文元数据修正而重复上传永久素材,也防止把旧封面带入新快照;旧记录缺少 `coverHash` 时只允许在核对原文件字节后做一次有审计事件的精确回填,禁止无哈希通配复用。该内部恢复游标不进入公开 API。
|
|
163
|
+
|
|
164
|
+
用户随后对新快照做了明确确认;受控 Worker 复用同账号、同封面哈希的永久素材,真实 `draft/add` 成功,并经 `draft/get` 验证 media ID、标题、作者、摘要和正文一致,意图进入 `SUCCEEDED`。本次只创建公众号草稿,没有调用正式发布或群发接口;该结果只关闭受控联调切片,不代表完整 P6 或生产部署闸门已经关闭。
|
|
165
|
+
|
|
166
|
+
平台证书虽然不是秘密,仍是验签信任根的一部分:证书文件、序列号和轮换必须来自受控配置。应用私钥文件只能由运行用户读取;日志和错误只能记录逻辑配置名、序列号或失败分类,不能记录私钥、对称密钥、完整签名基串或解密后的完整响应。
|
|
167
|
+
|
|
168
|
+
这套协议与第三方平台事件回调的 `msg_signature + EncodingAESKey` 是两条独立安全边界。于 2026-07-26 核验:
|
|
169
|
+
|
|
170
|
+
- [微信 API 签名加密指南](https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/getting_started/api_signature.html)
|
|
171
|
+
- [新增永久素材](https://developers.weixin.qq.com/doc/service/api/material/permanent/api_addmaterial)
|
|
172
|
+
- [上传图文消息内图片](https://developers.weixin.qq.com/doc/service/api/material/permanent/api_uploadimg)
|
|
173
|
+
- [新增草稿](https://developers.weixin.qq.com/doc/service/api/draftbox/draftmanage/api_draft_add)
|
|
174
|
+
- [获取草稿](https://developers.weixin.qq.com/doc/service/api/draftbox/draftmanage/api_getdraft)
|
|
175
|
+
|
|
176
|
+
## 5. Token 生命周期
|
|
177
|
+
|
|
178
|
+
- component ticket:保存最近有效值和接收时间;
|
|
179
|
+
- component access token:提前刷新,使用分布式单飞租约;
|
|
180
|
+
- authorizer access token:按授权维度提前刷新,失败退避;
|
|
181
|
+
- authorizer refresh token:每次授权信息返回后加密覆盖,保留最小必要历史元数据;
|
|
182
|
+
- 设备访问 token:24 小时,只保存 SHA-256;
|
|
183
|
+
- 设备 refresh token:30 天,Server 只保存 SHA-256;刷新同时要求 Ed25519 签名并轮换下一组 token;
|
|
184
|
+
- 同一设备刷新 `rotationId` 允许恢复同一轮响应丢失,其他旧 token 重放拒绝;
|
|
185
|
+
- 撤销授权:立即标记授权不可用,清除 token 缓存,阻止新草稿任务;
|
|
186
|
+
- 日志只记录授权 ID、token 类型、过期时间和结果码。
|
|
187
|
+
|
|
188
|
+
同一授权只允许一个刷新者。其他请求等待刷新结果或使用仍在安全窗口内的旧 access token,避免并发刷新覆盖。
|
|
189
|
+
|
|
190
|
+
### 5.1 草稿副作用结果分类
|
|
191
|
+
|
|
192
|
+
Worker 在发出 `draft/add` 前进入 `CREATING_DRAFT`。此后:
|
|
193
|
+
|
|
194
|
+
- 永久素材上传结果无法确认时进入 `ASSET_UPLOAD_UNVERIFIED`,停止调用 `draft/add`,不自动重复上传;
|
|
195
|
+
- 已验签、已解密且明确返回业务拒绝的响应可以进入 `FAILED`;
|
|
196
|
+
- 超时、断线、证书序列号未知、验签失败、响应解密失败或无法确认微信是否接收请求时进入 `CREATED_UNVERIFIED`;
|
|
197
|
+
- `CREATED_UNVERIFIED` 不自动重试 `draft/add`,只允许回读、对账或人工核验;
|
|
198
|
+
- `draft/add` 返回 media ID 后仍要调用 `draft/get`;回读未确认前不能记为 `SUCCEEDED`。
|
|
199
|
+
|
|
200
|
+
安全校验失败不能被降级成“可重试网络错误”,否则可能同时绕过验签和重复创建草稿。
|
|
201
|
+
|
|
202
|
+
## 6. 多租户隔离
|
|
203
|
+
|
|
204
|
+
### 6.1 应用层
|
|
205
|
+
|
|
206
|
+
- 每个认证请求产生不可变 `TenantContext`;
|
|
207
|
+
- 仓储层自动注入 `tenantId`;
|
|
208
|
+
- 资源 ID 查询之后仍校验返回记录的 `tenantId`;
|
|
209
|
+
- Worker 任务携带 `tenantId`,领取后再次核对业务资源;
|
|
210
|
+
- 只有 Worker 内部的特权调度仓储可以跨租户原子领取或有界恢复意图;该边界不接受
|
|
211
|
+
用户提供的租户参数,不返回正文、令牌或授权,只返回包含 `tenantId` 的受控任务;
|
|
212
|
+
- 任务领取后,授权、账号、快照、素材、状态转移和审计查询必须显式带任务自带的
|
|
213
|
+
`tenantId`,不得把特权调度能力暴露给 Server 路由或普通仓储;
|
|
214
|
+
- 预签名对象 key 包含不可猜测 ID,不把租户名作为安全边界。
|
|
215
|
+
|
|
216
|
+
### 6.2 数据库
|
|
217
|
+
|
|
218
|
+
- 本地 Docker MongoDB 和生产 `worker_vps` MongoDB 均使用独立 `dxc` 数据库;
|
|
219
|
+
- 本地开发和自动化测试不得连接生产数据库;
|
|
220
|
+
- 生产 URI、账号和口令仅通过安全环境配置提供;
|
|
221
|
+
- DxC 使用最小权限账号,账号只能访问 `dxc` 数据库;
|
|
222
|
+
- 应用账号不能管理 Mongo 用户、读取其他数据库或执行服务器管理命令;
|
|
223
|
+
- 索引中的唯一性按租户或明确的全局业务键定义;
|
|
224
|
+
- 备份访问和恢复演练遵循同样的权限边界。
|
|
225
|
+
|
|
226
|
+
MVP 不为每个租户创建独立数据库,但领域代码不得阻止未来高敏租户独立部署。
|
|
227
|
+
|
|
228
|
+
## 7. 日志和审计
|
|
229
|
+
|
|
230
|
+
### 7.1 运行日志
|
|
231
|
+
|
|
232
|
+
允许记录:
|
|
233
|
+
|
|
234
|
+
- request/job/intent/order/tenant 的内部 ID;
|
|
235
|
+
- 状态转移;
|
|
236
|
+
- 第三方错误码;
|
|
237
|
+
- 耗时、重试次数和大小指标;
|
|
238
|
+
- 经过过滤的响应分类。
|
|
239
|
+
|
|
240
|
+
禁止记录:
|
|
241
|
+
|
|
242
|
+
- token、cookie、Authorization Header;
|
|
243
|
+
- Component/支付/对象存储密钥;
|
|
244
|
+
- 完整回调或支付通知;
|
|
245
|
+
- 文章正文、摘要全文和图片二进制;
|
|
246
|
+
- 预签名 URL;
|
|
247
|
+
- 用户本地绝对路径;
|
|
248
|
+
- Agent 对话全文。
|
|
249
|
+
|
|
250
|
+
Pino 配置必须同时使用字段路径 redaction 和值模式过滤。异常对象序列化前进行清洗。
|
|
251
|
+
|
|
252
|
+
### 7.2 审计日志
|
|
253
|
+
|
|
254
|
+
`AuditEvent` 记录:
|
|
255
|
+
|
|
256
|
+
- 谁:用户、设备、系统、Worker;
|
|
257
|
+
- 何时;
|
|
258
|
+
- 在哪个租户;
|
|
259
|
+
- 对什么资源;
|
|
260
|
+
- 执行什么动作;
|
|
261
|
+
- 前后状态;
|
|
262
|
+
- request/intent/job/order 关联 ID;
|
|
263
|
+
- 脱敏结果和原因。
|
|
264
|
+
|
|
265
|
+
审计是追加式记录。更正通过新增事件完成,不在原地改历史。
|
|
266
|
+
|
|
267
|
+
## 8. 文章、图片和预览
|
|
268
|
+
|
|
269
|
+
- 传输只使用 HTTPS;
|
|
270
|
+
- 对象存储 bucket 不公开;
|
|
271
|
+
- 上传和下载使用短时、限定方法/对象/大小的签名;
|
|
272
|
+
- Server 对 CLI 声明的哈希和实际对象重新核对;
|
|
273
|
+
- Markdown 先解析再 allowlist 清洗;
|
|
274
|
+
- 预览 HTML 不允许执行用户脚本;
|
|
275
|
+
- 预览 token 是随机、高熵、短时、一次范围的能力票据;
|
|
276
|
+
- 预览页面不允许被搜索引擎索引;
|
|
277
|
+
- 外部图片默认抓取失败,MVP 优先要求本地导入,避免预览泄露访问者 IP。
|
|
278
|
+
|
|
279
|
+
### 8.1 本地研究与浏览器边界
|
|
280
|
+
|
|
281
|
+
- DxC Server、Worker 和其他 DxC Cloud 组件不得向第三方内容源发起研究抓取请求;改变该边界必须新增 ADR。
|
|
282
|
+
- Agent/适配器每次运行记录 `executionLocation: local-device | agent-hosted | unknown` 和 `dataTransit: local-only | agent-provider | unknown`,并在首次使用对应数据路径时向用户说明。
|
|
283
|
+
- 登录态页面只允许用户确认的 `local-device` 适配器;登录、验证码和权限授予由用户本人完成。
|
|
284
|
+
- 页面能力只返回受控证据,不返回 Cookie、Token、密码、请求头、浏览器 Profile 路径或本地凭据存储内容。
|
|
285
|
+
- 页面正文、DOM、截图 OCR 和下载内容都是不可信数据,不能覆盖系统/Skill 指令、触发工具、读取文件或访问凭据。
|
|
286
|
+
- URL 只允许 HTTP(S);每次 DNS 解析和重定向都重新检查,默认拒绝 loopback(回环)、私网、链路本地、Unix socket 和云元数据地址。
|
|
287
|
+
- 本地任务必须显式启用,设置域名白名单、并发锁、频率/CPU/内存/磁盘上限、错过任务策略、失败通知、暂停/删除和保留期限。
|
|
288
|
+
- 可选工具包必须有签名清单、SHA-256、固定版本、回滚与卸载;不得运行任意安装脚本,并能清理自己创建的浏览器/Profile 缓存和撤销权限。
|
|
289
|
+
- 研究 Markdown 使用 `dxc-content-stage@1` 轻量元数据,只保存必要摘要、来源、观点、
|
|
290
|
+
证据引用和哈希。用户确认观点不自动授权上传第三方全文;DxC Cloud 不接收本地研究
|
|
291
|
+
完整包。
|
|
292
|
+
|
|
293
|
+
Agent 宿主或模型提供方是否处理 DOM、截图和抽取文本由其自身数据政策决定,DxC 不能替第三方宿主承诺“内容不离机”。详细架构见 [ADR-0004](decisions/0004-local-first-agent-research-runtime.md)。
|
|
294
|
+
|
|
295
|
+
### 8.2 本地画像与历史内容记忆
|
|
296
|
+
|
|
297
|
+
- `~/.dxc` 必须由当前用户拥有,目录权限 `0700`;画像、项目索引和 SQLite 主文件权限
|
|
298
|
+
`0600`。读取时拒绝符号链接、非普通文件、其他用户所有或组/其他用户可读的文件。
|
|
299
|
+
- `content-projects.json` 只登记用户明确初始化过的项目标题、ID、绝对目录和更新时间;
|
|
300
|
+
不保存文章正文,不递归扫描任何目录。绝对目录只在本机 `project resolve` 结果中返回,
|
|
301
|
+
不进入云端日志。
|
|
302
|
+
- 历史文章只接受用户明确列出的 Markdown/文本文件,不递归扫描主目录、浏览器、笔记库、同步盘或其他项目。
|
|
303
|
+
- SQLite 只保存本地文章元数据、分段、哈希和向量;不保存原始绝对路径,结构化输出只返回文件 basename(基本文件名)。
|
|
304
|
+
- 嵌入在本机通过固定模型 ID、revision、q8 类型和维数完成。模型下载不携带文章正文;模型缓存不是凭据,但仍放在用户级 `~/.dxc/models/`。
|
|
305
|
+
- 混合召回只输出不超过 420 字的片段和来源标识,不输出整篇文章。内容 Skill 必须保留引用,不能把向量相似度当作事实或原作者逐字引语证明。
|
|
306
|
+
- SQLite、画像和检查点默认不上传 DxC Cloud。若 Agent 把片段放入对话,宿主/模型提供方可能处理该片段,首次使用必须披露。
|
|
307
|
+
- `dxc knowledge remove <article-id>` 必须同时删除文章分段、FTS5 行和向量。当前没有云同步,因此不会产生远端知识库删除任务。
|
|
308
|
+
- 本地模型或切分规则升级不得静默混用旧向量;必须显式迁移/重建并提供回退说明。
|
|
309
|
+
|
|
310
|
+
详细决策见 [ADR-0005](decisions/0005-official-skill-orchestration-and-local-content-memory.md)。
|
|
311
|
+
|
|
312
|
+
### 8.3 公网绑定入口容量保护
|
|
313
|
+
|
|
314
|
+
- 设备挑战创建/证明、个人微信登录创建/刷新和公众号预授权创建分别使用固定窗口限流;任何微信调用前必须先通过相应设备或短时绑定身份校验,429 不调用微信平台。
|
|
315
|
+
- 组合限流必须先检查低基数的来源 IP,再检查 `IP + 会话/Token 指纹`;所有应用内窗口设置固定 bucket(桶)上限并优先清理过期项,达到上限时拒绝未知新键,避免未认证请求制造无界内存增长。
|
|
316
|
+
- API Server 只信任 loopback(回环)Nginx 提供的来源地址,不信任公网客户端自行提交的 `X-Forwarded-For`。
|
|
317
|
+
- 当前应用内限流仅适用于单进程首切片,进程重启会清空计数,多实例之间也不共享。正式部署身份版本前还必须增加 Nginx 限流、Mongo 容量/TTL 告警和异常指纹审计;应用内窗口不能替代生产边缘闸门。
|
|
318
|
+
- 设备 Ed25519 proof 只证明请求方持有刚登记的私钥,不代表受信任用户身份,也不能单独作为反滥用依据。
|
|
319
|
+
- `dxc auth login` 只有在个人微信摘要已经关联 owner 后才允许为新设备建立会话;
|
|
320
|
+
`dxc auth start` 可显式创建或恢复,`dxc wechat connect` 不得绕过任一边界接管已有
|
|
321
|
+
租户。
|
|
322
|
+
- 已登录设备发起的在途公众号授权必须在微信交换前、检查点前和恢复前重验设备会话;logout(注销)或到期后进入 `FAILED`,不能继续绑定账号或保存租户凭据。
|
|
323
|
+
|
|
324
|
+
## 9. 数据保留和删除
|
|
325
|
+
|
|
326
|
+
初始建议值,正式上线前写入隐私政策并允许配置:
|
|
327
|
+
|
|
328
|
+
| 数据 | 默认保留 |
|
|
329
|
+
|---|---|
|
|
330
|
+
| 设备绑定/授权短时会话 | 授权入口 15 分钟;仅已交换结果的恢复记录最长 24 小时 TTL |
|
|
331
|
+
| 个人微信登录会话 | 扫码入口 10 分钟;`IDENTIFIED`/终态恢复记录最长 1 小时 TTL |
|
|
332
|
+
| 设备访问/刷新 token | 24 小时/30 天;注销或撤销后由 TTL 清理记录,明文只保留在本地 |
|
|
333
|
+
| 未完成上传 | 24 小时 |
|
|
334
|
+
| 预览链接 | 30 分钟;创建响应和 CLI 同时展示到期时间与剩余秒数,过期后必须重建 |
|
|
335
|
+
| 原始文章和图片 | 最后任务后 30 天 |
|
|
336
|
+
| 渲染快照 | 最后任务后 30 天 |
|
|
337
|
+
| 成功交付元数据 | 1 年 |
|
|
338
|
+
| 安全/审计事件 | 1 年或法律要求期限 |
|
|
339
|
+
| token | 授权有效期间;撤销后尽快删除密文 |
|
|
340
|
+
| 支付订单和财务记录 | 按财税和支付合规要求 |
|
|
341
|
+
| 本地创作画像 | 用户删除或重置前;仅本机 |
|
|
342
|
+
| 本地内容项目索引 | 用户删除项目登记或索引文件前;仅本机,不含正文 |
|
|
343
|
+
| 本地历史文章索引 | 用户单篇删除或删除数据库前;仅本机 |
|
|
344
|
+
| 本地嵌入模型缓存 | 用户清理或版本迁移前;不含文章正文 |
|
|
345
|
+
|
|
346
|
+
用户删除流程:
|
|
347
|
+
|
|
348
|
+
1. 停止新任务;
|
|
349
|
+
2. 按用户选择删除本地知识文章、画像或整个本地状态目录;
|
|
350
|
+
3. 撤销设备会话;
|
|
351
|
+
4. 标记并删除/匿名化云端文章和对象;
|
|
352
|
+
5. 删除 authorizer token 密文;
|
|
353
|
+
6. 保留法律要求的最小支付和安全记录;
|
|
354
|
+
7. 记录不含正文/凭据的删除审计事件。
|
|
355
|
+
|
|
356
|
+
取消 DxC 绑定不能替代用户在微信侧取消第三方平台授权;产品必须同时提供说明和状态核验。
|
|
357
|
+
|
|
358
|
+
## 10. 网络与部署
|
|
359
|
+
|
|
360
|
+
### 10.1 入站
|
|
361
|
+
|
|
362
|
+
- Nginx/边缘层只暴露必要路由;
|
|
363
|
+
- 回调、预览和 API 分别限速;
|
|
364
|
+
- 内部管理接口不暴露公网;
|
|
365
|
+
- 请求体大小按用途限制;
|
|
366
|
+
- CORS 默认拒绝,只有明确 Web 页面需要时开放精确来源;
|
|
367
|
+
- 健康检查不返回版本细节、密钥状态或连接串。
|
|
368
|
+
|
|
369
|
+
### 10.2 出站
|
|
370
|
+
|
|
371
|
+
- 微信 API 只由 Worker/Token Service 从固定出口访问;
|
|
372
|
+
- 当前阶段 `worker_vps` 上的 Worker 只通过 `172.25.84.202:3128` 受限 CONNECT 代理访问 `api.weixin.qq.com:443`;
|
|
373
|
+
- 代理必须同时使用 Squid ACL、私网监听和 nftables 来源限制,不缓存、不解密 TLS,并设置 128 MiB 内存硬上限;
|
|
374
|
+
- Server/Worker 的其他出站域名按最小范围控制;
|
|
375
|
+
- 生产前现场核实 `alivps` 当前出口 IP;
|
|
376
|
+
- 不把历史 `120.76.172.59` 当作当前事实;
|
|
377
|
+
- 不访问 `puzhi-prod` 或 `puzhi_ecs`。
|
|
378
|
+
|
|
379
|
+
### 10.3 供应链
|
|
380
|
+
|
|
381
|
+
- CLI/Skill 发布物固定版本和 SHA-256;
|
|
382
|
+
- 本地嵌入模型固定仓库 revision、量化类型和向量维数;首次下载和重建索引对用户可见;
|
|
383
|
+
- 安装清单通过 HTTPS 获取并签名;
|
|
384
|
+
- 不执行未经固定版本的远程脚本;
|
|
385
|
+
- 依赖锁文件必须提交;
|
|
386
|
+
- CI 做依赖审计、秘密扫描和构建可重复性检查;
|
|
387
|
+
- `alivps` 和 `worker_vps` 禁止执行依赖安装、仓库构建、测试或镜像构建,只部署本地或 CI 已验证的构建产物;
|
|
388
|
+
- 生产镜像使用非 root 用户、只读根文件系统和最小权限;
|
|
389
|
+
- 更新不能在一次草稿交付中途替换 Worker/renderer 语义。
|
|
390
|
+
|
|
391
|
+
## 11. 备份、恢复和对账
|
|
392
|
+
|
|
393
|
+
- Mongo 每日备份,定期验证恢复到隔离环境;
|
|
394
|
+
- 对象存储启用版本/生命周期策略或等价保护;
|
|
395
|
+
- 备份同样包含加密数据,密钥备份和数据备份分开管理;
|
|
396
|
+
- 没有对应 KEK 的备份不可恢复,因此密钥灾备是发布闸门;
|
|
397
|
+
- 每日对账支付成功但未履约订单;
|
|
398
|
+
- 定期扫描 `CREATED_UNVERIFIED`、冻结额度和过期租约;
|
|
399
|
+
- 重要状态保留可重放的业务事件摘要,不保留敏感原报文。
|
|
400
|
+
|
|
401
|
+
## 12. 生产变更规则
|
|
402
|
+
|
|
403
|
+
以下操作必须在单独任务中获得明确授权:
|
|
404
|
+
|
|
405
|
+
- 访问或修改生产 Nginx;
|
|
406
|
+
- DNS、证书、防火墙或安全组变更;
|
|
407
|
+
- 在 `alivps`/`worker_vps` 安装、启动或重启服务;
|
|
408
|
+
- 创建 Mongo 用户、数据库或索引;
|
|
409
|
+
- 配置对象存储 bucket;
|
|
410
|
+
- 写入任何真实微信、SkillHub 或支付凭据;
|
|
411
|
+
- 执行真实公众号授权、支付或草稿创建。
|
|
412
|
+
|
|
413
|
+
执行前先只读核实现状,执行后提供可复验的健康、日志、网络和回滚证据。
|