Files
keyboard/docs/privacy-alignment-matrix-2026-03-08.md
2026-03-08 21:29:10 +08:00

255 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# KeyBoard 隐私披露对照表
更新日期2026-03-08
## 1. 这份表是干什么的
这份表专门回答一件事:
`App 内文案``隐私政策``App Store Connect 的 App Privacy` 应该如何对齐,避免三处口径打架。
你可以把它当成提审前的“隐私总对照表”。
## 2. Apple 当前口径
结合 Apple 截至 2026-03-08 的官方文档,当前需要特别记住 4 个点:
1. 你需要申报你自己和第三方 SDK 从 App 中收集的数据。
2. “收集”通常指数据离开设备,并且你或第三方可以以可读形式访问超出实时处理所需的时间。
3. 免费文本框和语音录音通常对应:
- `Other User Content`
- `Audio Data`
4. 对第三方键盘来说,开启 `Full Access` 后如果会把键入内容或语音发到服务器,必须明确告诉用户,而且文案必须和实际行为一致。
官方来源:
1. App Privacy Details
https://developer.apple.com/app-store/app-privacy-details/
2. App PrivacyApp Store Connect Help
https://developer.apple.com/help/app-store-connect/reference/app-privacy
3. App Extension Programming Guide: Custom Keyboard
https://developer.apple.com/library/archive/documentation/General/Conceptual/ExtensibilityPG/CustomKeyboard.html
## 3. 当前工程里已经看到的事实
以下结论来自当前代码,不是猜测:
1. 主 App 和键盘扩展都声明了麦克风权限。
- `keyBoard/Info.plist`
- `CustomKeyboard/Info.plist`
2. 键盘扩展开启了 `RequestsOpenAccess = true`
- `CustomKeyboard/Info.plist`
3. 主 App 存在语音录音,并把录音文件上传到服务端做转写。
- `AiVM.m` 中有 `uploadFile:API_AI_SPEECH_TRANSCRIBE`
4. AI 文本内容会发到服务端。
- `AiVM.m`
- `CustomKeyboard/VM/KBVM.m`
5. 存在账号体系,会保存 email、userId、token、用户资料。
- `KBUserSessionManager`
- `KBAuthManager`
- `KBMyVM`
6. 存在头像上传。
- `KBMyVM.m`
7. 存在购买记录 / 钱包流水 / 订阅恢复。
- `KBMyVM.m`
- 支付相关 VC / StoreKit 桥接
8. Release 下启用了 Bugly。
- `AppDelegate.m`
9. 工程里有自定义埋点上报器 `KBMaiPointReporter`,默认 Release 关闭,但如果你通过宏配置线上地址,则会真正上传。
10. 当前 [PrivacyInfo.xcprivacy](/Users/mac/Desktop/项目/公司/KeyBoard/keyBoard/PrivacyInfo.xcprivacy) 只声明了:
- `Email Address`
- `User ID`
- `Other User Content`
这和当前代码能力相比,大概率不完整。
## 4. 对照原则
每一项数据,都用同一套问题去核对:
1. 是否真的收集?
2. 是本地处理,还是上传服务端?
3. 上传只是实时处理,还是会保存?
4. 是否与账号关联?
5. 用途是功能、个性化、分析、诊断,还是别的?
只要任意一项在三处说法不一致,就有审核风险。
## 5. 核心对照表
| 数据主题 | 当前代码证据 | App 内文案应该怎么说 | 隐私政策应该怎么写 | App Privacy 建议填写 | 当前状态 |
| --- | --- | --- | --- | --- | --- |
| 账号邮箱 | 登录 / 用户信息 / `PrivacyInfo.xcprivacy` 已声明 `EmailAddress` | 明确告诉用户邮箱用于注册、登录、找回账号、账号识别 | 写明会收集邮箱,用于账号认证、登录、客服、账号找回;是否保存、保存多久、如何删除 | `Email Address`;通常 `Linked = Yes``Purpose = App Functionality` | 基本已覆盖,但要核对隐私政策正文是否真的写了 |
| 用户 ID / 账号标识 | `KBUserSessionManager``KBAuthManager``PrivacyInfo.xcprivacy` 已声明 `UserID` | 告知用户登录后会生成并使用账号标识,以维持登录态和同步功能 | 写明会保存账号 ID / token / 账号资料,用于身份验证、同步和安全 | `User ID`;通常 `Linked = Yes``Purpose = App Functionality` | 基本已覆盖,但隐私政策和后台要保持一致 |
| AI 输入文本 / 聊天内容 | `AiVM requestChatMessageWithContent``KBVM sendChatMessageWithContent`;聊天记录接口 | 如果用户主动使用 AI、改写、聊天等网络功能应明确提示“你发送的文本会被传输到服务器处理” | 写明:当用户主动触发 AI 功能时,输入文本、聊天内容和必要上下文可能被上传,用于生成回复、同步记录或安全处理;是否保存、保存多久、是否用于训练必须写清 | 至少评估 `Other User Content`;通常 `Linked = Yes``Purpose = App Functionality` | 当前 `PrivacyInfo.xcprivacy` 已有 `OtherUserContent`,但隐私政策正文和 App 内文案还需要更明确 |
| 键盘内输入文本 | 键盘扩展开启 `Full Access`,且键盘内 AI 文本请求会出网 | 不能只写“开启 Full Access 体验全部功能”;必须补一句“仅当你主动使用联网功能时,相关输入内容可能被发送到服务器处理” | 必须明确区分:普通本地输入 vs 用户主动触发的 AI / 联网功能;哪些情况下键入内容会离开设备;是否保留;是否和账号关联 | 若仅实时处理且不保留,按 Apple 口径可能不一定算“collect”但只要会保留或超出实时处理就按 `Other User Content` 申报。审核上建议按最保守口径写清 | 这是当前最敏感项,必须你和后端最终确认 |
| 语音录音 / 语音转文字 | `KBAIHomeVC` 录音后调用 `transcribeAudioFileAtURL:``AiVM` 上传 `audio/m4a``/speech/transcribe` | 麦克风权限文案不能只写“用于语音输入”,还应在功能说明里告诉用户“录音会上传到服务器进行识别/转写”,如果确实如此 | 必须写明是否上传语音文件、是否只用于转写、是否保存原始音频、保存多久、是否用于训练模型 | `Audio Data`;通常 `Linked = Yes``Purpose = App Functionality` | 当前代码层面已经能确认“主 App 语音录音会上传做转写”,但 `PrivacyInfo.xcprivacy` 还没体现 |
| AI 生成音频 / 音频 URL | `/chat/audio/{audioId}` 获取 AI 音频 URL | 可不单独强调为“用户数据”,但如果会和聊天记录一起保存,可在 AI 说明里写清 | 若服务端会保存 AI 语音内容,建议在隐私政策里说明与聊天内容的关系和保留策略 | 一般不单独作为新的用户数据类型填写,除非其中包含用户上传的语音原件或和用户行为绑定用于分析 | 需要结合服务端保留策略判断 |
| 头像上传 | `KBMyVM upLoadAvatarWithData:` 上传 `avatar.jpg` | 如果用户上传头像,界面需明确“头像将上传并用于个人资料展示” | 写明会收集用户上传的头像图片,用于个人资料展示与账号信息维护;写清删除方式 | 评估 `Photos or Videos`;通常 `Linked = Yes``Purpose = App Functionality` | 当前代码已存在上传App Privacy 很可能漏填 |
| 昵称 / 基本资料 | `updateUserInfo` 会上传 `nickName``gender``avatarUrl` | 界面上应明确这些资料用于完善个人主页、账号展示或个性化体验 | 隐私政策写清用户资料字段、用途、是否公开展示、如何删除 | `Name` 可能需要评估;`gender` 需结合业务含义进一步评估是否属于普通资料还是敏感信息 | 这项需要你最终按真实展示逻辑确认 |
| 购买记录 / 钱包流水 / 订阅状态 | `fetchWalletTransactionsWithPage`、订阅页、恢复购买 | 订阅页和个人页要清楚说明购买后会记录订阅状态和消费记录 | 写明会处理订阅状态、订单/消费记录,用于开通权益、恢复购买、客服和对账 | 评估 `Purchase History`;通常 `Linked = Yes``Purpose = App Functionality` | 当前代码已有相关能力App Privacy 大概率还没覆盖 |
| 反馈内容 | `submitFeedbackWithContent:` | 反馈页应说明“你提交的反馈内容将用于客服和问题处理” | 写明反馈内容仅用于客服、问题排查、产品支持,是否保存以及保留时长 | 可评估 `Customer Support`;若完全满足 Apple“可选披露”四条件可不申报不满足则申报 | 取决于你是否想走“可选披露”路径;为了稳,通常建议披露 |
| 举报内容 / 举报原因 / 聊天证据 | `reportCompanionWithCompanionId` 包含 `reportDesc``chatContext``evidenceImageUrl` | 举报页面应明确“举报内容和相关上下文将用于审核处理” | 写明会处理举报描述、聊天上下文、证据链接,用于安全审核与申诉处理 | 通常优先评估 `Customer Support``Other User Content`;如有用户上传图片,还要评估 `Photos or Videos` | 建议明确披露,不建议藏着不说 |
| 崩溃日志 / 诊断 | Release 启用 Bugly | App 内通常不用强提示,但隐私政策要写明使用第三方崩溃诊断服务 | 写明会收集崩溃和诊断信息,用于修复问题、提升稳定性;是否关联用户需按 SDK 实际行为确认 | 至少评估 `Crash Data`;必要时再评估 `Performance Data` / `Other Diagnostic Data` | 当前最需要你确认 Bugly 实际上传字段;如果保留 Release Bugly不能忽略 |
| 埋点 / 用户交互数据 | `KBMaiPointReporter` 会上传 `eventName / page_id / element_id / token`;默认 Release 关闭,但可被宏开启 | 如果 Release 真的开启埋点App 内至少要在隐私政策里说明会收集使用行为数据用于分析和优化 | 写明会收集页面曝光、点击、功能使用等行为数据;是否绑定账号、是否用于分析、是否与第三方共享 | 如 Release 开启,评估 `Product Interaction`;通常 `Linked = Yes``Purpose = Analytics`,必要时也可能 `App Functionality` | 当前代码默认 Release 关闭;若提审包不启用,可不按已收集算;若线上宏打开,就必须申报 |
| AppGroup / 本地缓存 / 本地文件 | `NSUserDefaults`、App Group、persona 图片、本地录音文件 | 本地缓存通常不需要单独对用户解释成“上传收集”,但可在隐私政策里说明用于本地功能和跨 App/扩展同步 | 若仅本地处理、不离开设备,通常不属于 App Privacy 的“Collected” | 通常不需要在 App Privacy 填“收集”,除非它们会再被上传或长期保存到服务端 | 这一类要和“真正上传到服务器的数据”区分清楚 |
## 6. 当前最可能不一致的地方
按当前代码和现状,以下几项最容易出现“三处不一致”:
### 6.1 语音数据
当前代码已经能看出:
1. 主 App 会录音
2. 录音文件会上传到 `/speech/transcribe`
如果你现在:
1. App 内只写“用于语音输入”
2. 隐私政策没写“上传服务器做识别”
3. App Privacy 没勾 `Audio Data`
那就是明显不一致。
### 6.2 键盘 Full Access 后的输入内容
当前代码能看出:
1. 键盘扩展启用了 `RequestsOpenAccess = true`
2. 键盘中的 AI 联网能力会把用户主动触发的文本请求发到服务端
如果你现在:
1. App 内只写“开启 Full Access 体验全部功能”
2. 隐私政策没区分“何时会把输入发送到服务端”
3. Review Notes 也没写清
这会是审核重点风险。
### 6.3 头像图片
当前代码里头像上传已经存在。
如果你现在:
1. 隐私政策没提用户上传图片
2. App Privacy 没评估 `Photos or Videos`
这也是不一致。
### 6.4 崩溃日志 / 诊断
当前 Release 有 Bugly。
如果你现在:
1. 隐私政策没提崩溃诊断
2. App Privacy 也没申报 `Crash Data`
那至少需要复核,不能直接默认没收集。
### 6.5 购买记录
当前代码里存在:
1. 订阅
2. 恢复购买
3. 钱包流水 / 消费记录查询
如果你现在:
1. 会员协议只写订阅,不写记录和恢复购买相关处理
2. App Privacy 没评估 `Purchase History`
这项也不完整。
## 7. 你现在可以直接照着改的口径
下面不是最终法律文本,而是“先把口径统一”的写法模板。
### 7.1 App 内关于 Full Access 的文案建议
当前类似文案:
`Turn on Allow Full Access to experience all features`
建议补充为类似意思:
`开启 Full Access 后,键盘可使用联网功能。仅当你主动使用 AI、账号、同步、订阅或语音等联网功能时相关文本、语音或必要账号信息可能被发送到服务器处理。`
### 7.2 App 内关于麦克风 / 语音的文案建议
当前权限文案:
`需要使用麦克风进行语音输入`
建议在功能页或权限前说明里再补一句:
`录制的语音会上传到服务器进行识别/转写,用于把语音转换为文本。`
如果你们实际不保存原始音频,再补一句:
`原始音频仅用于完成本次识别请求,不作其他用途。`
前提是这句话必须和真实后端行为一致。
### 7.3 隐私政策里 AI / 聊天 / 键盘文本的建议写法
建议至少写清 5 件事:
1. 用户主动触发哪些功能时,文本会离开设备
2. 是否会上传聊天内容和上下文
3. 是否会保留聊天记录
4. 是否用于模型训练
5. 如何删除账号和相关数据
### 7.4 App Privacy 后台填写的建议思路
按当前代码,至少应重新复核这些数据类型:
1. `Email Address`
2. `User ID`
3. `Other User Content`
4. `Audio Data`
5. `Photos or Videos`
6. `Purchase History`
7. `Crash Data`
8. `Customer Support`
9. `Product Interaction`
其中:
1. `Product Interaction` 取决于 Release 是否真正开启埋点
2. `Crash Data` 取决于 Release Bugly 是否真实上传
3. `Audio Data``Photos or Videos``Purchase History` 基本都值得重点复核
## 8. 当前我对你项目的直接判断
如果现在立刻去填 `App Privacy`,最危险的不是“完全没法填”,而是“容易少填或写得太轻”。
按当前代码,我更倾向于你至少要重点确认:
1. `Audio Data`
2. `Other User Content`
3. `Photos or Videos`
4. `Purchase History`
5. `Crash Data`
当前 [PrivacyInfo.xcprivacy](/Users/mac/Desktop/项目/公司/KeyBoard/keyBoard/PrivacyInfo.xcprivacy) 只写了 `Email / User ID / Other User Content`,明显不足以覆盖你现有功能边界。
## 9. 下一步建议
我建议你马上做两件事:
1. 让产品 / 后端 / 你自己确认“语音、键盘文本、聊天内容、头像、崩溃日志、埋点”的真实保留策略
2. 然后基于这张表去统一:
- App 内提示文案
- 隐私政策正文
- App Store Connect 的 App Privacy
如果你愿意,我下一步可以继续直接帮你出两份可提交材料:
1. 一版可直接粘到 Apple 后台的 `App Privacy 填写建议`
2. 一版可直接放到网页里的 `隐私政策补充段落`