[Bug] macOS: 硬运行时缺少麦克风 entitlement,语音输入被永久拒绝且不弹授权窗(无用户侧绕过方案) #7989
Unanswered
Theeffortman
asked this question in
Q&A
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
EN · 中文见下
Summary
On macOS, the shipped 0.1.7-rc.2 build is signed with Hardened Runtime but does not declare the
com.apple.security.device.audio-inputentitlement. As a result, macOStccdtreats microphone access as a hardened-runtime policy violation: it refuses to even show the permission prompt, and every capture request is denied outright. The user can never grant the permission — the toggle in System Settings → Privacy & Security → Microphone never appears.I verified that this is not a stale/missing TCC row: manually inserting an allow row into the user TCC database for the app's bundle id (
auth_value=2) does not help, because the hardened-runtime entitlement check happens before the database is consulted. So this cannot be worked around from the user side.Environment
DeepSeek Harness.app0.1.7-rc.2 (official notarized build)com.deepseek.dshNAN929V4UMdsh-experimental-voice-input-bundle)Evidence
1. Hardened runtime is enabled
2. The entitlements do not include audio input
Note that
Info.plistdoes containNSMicrophoneUsageDescriptionandNSAudioCaptureUsageDescription— so the intent to use the microphone is clearly there; only the entitlement is missing.3. tccd denies without prompting (decisive)
Reproduced 15 times within a few minutes of normal UI usage (just invoking voice input). Both the main process and the
audio.mojom.AudioServicehelper trigger it.4. A TCC database entry is not sufficient (tested)
I added an allow row for
kTCCServiceMicrophone/com.deepseek.dsh(client_type=0, auth_value=2, auth_reason=4) with acsreqblob compiled from the app's actual designated requirement:The row is structurally identical to working rows for other apps (e.g. Chrome's), and it survived a
tccdreload — yet the app is still denied. That confirms the gate is the entitlement, not the database. (I removed the row afterwards to leave the machine in stock state.)Suggested fix
Add the entitlement when packaging the macOS build, for both the main process and the helper that performs capture:
then re-sign and re-notarize. After that, the normal macOS prompt will appear once, and the app will be listed under System Settings → Privacy & Security → Microphone.
For Electron specifically, the actual capture happens in a helper process (
…/Frameworks/<App> Helper.app), so the entitlement must be present there as well — the log above showstccdblaming the responsible process (com.deepseek.dsh) while the accessing process iscom.deepseek.dsh.helper, so both need it.中文
摘要
macOS 官方构建 0.1.7-rc.2 启用了硬运行时(Hardened Runtime),但没有声明麦克风所需的
com.apple.security.device.audio-inputentitlement。macOS 的tccd会把这种情况判定为「硬运行时策略违规」:连授权弹窗都不允许弹出,每次采集请求都被直接拒绝。用户永远无法授权——系统设置 → 隐私与安全性 → 麦克风 里根本不会出现这个 App。已排除「TCC 数据库缺行」这一可能:手动为 App 的 bundle id 写入一条 允许 行(
auth_value=2)同样无效,因为硬运行时的 entitlement 检查发生在查数据库之前。也就是说,这个 bug 用户侧无法绕过。环境
DeepSeek Harness.app0.1.7-rc.2(官方公证包),bundle idcom.deepseek.dsh,TeamNAN929V4UMdsh-experimental-voice-input-bundle)证据
codesign -dv --verbose=2→flags=0x10000(runtime),硬运行时已开codesign -d --entitlements -→ 只有allow-jit/allow-unsigned-executable-memory/disable-library-validation三条,没有com.apple.security.device.audio-input(但Info.plist里NSMicrophoneUsageDescription是有的,说明只是漏了 entitlement)tccd日志:requires entitlement com.apple.security.device.audio-input but it is missing→Policy disallows prompt→denied,几分钟内复现 15 次csreq由该 App 的真实 designated requirement 编译而来,结构与其他可用 App 完全一致)仍然被拒 → 瓶颈是 entitlement,不是数据库修复建议
打包时为主进程与执行采集的 helper 进程都加上:
然后重新签名并公证。之后正常的系统授权弹窗会出现一次,App 也会出现在「隐私与安全性 → 麦克风」列表中。
Electron 场景要注意:实际采集发生在 helper 进程(
…/Frameworks/<App> Helper.app),而日志显示tccd追责的是 responsible 进程(com.deepseek.dsh)、实际访问者是com.deepseek.dsh.helper,所以两边都需要这条 entitlement。All reactions