Skip to content

[Bug] macOS integrated terminal audio capture is denied because the app lacks audio-input entitlement #1483

Closed

Description

@mao13811364454

Bug Summary

FFmpeg launched from VMark's integrated terminal writes all-zero audio while macOS TCC denies audio input to the responsible app, app.vmark. No permission prompt appears. This prevents audio-recording CLI workflows from working in the terminal.

Environment

  • VMark 0.9.87 (the latest release checked on 2026-09-29)
  • macOS 26.6.2 (25G83)
  • FFmpeg 8.1.2, AVFoundation input
  • BlackHole 2ch; the current default multi-output device includes BlackHole and the built-in speakers
  • Installed app at /Applications/VMark.app; installation method not confirmed
  • Upstream configuration inspected at 241a25302e35b6a142aa16a7eba531cbf2046a0e

Reproduction context

  1. Open VMark's integrated terminal.
  2. Run an AVFoundation recording command targeting BlackHole 2ch. Our observed process chain was VMark → shell → CLI agent → FFmpeg; a separate short capture from this environment reproduced the silent output.
  3. Play sound through the output routed to BlackHole while recording. Our controlled check used a one-second 880 Hz test tone during a short capture.
  4. Inspect PCM samples and macOS TCC logs.

Equivalent commands for a maintainer to try (not separately verified as a direct, agent-free reproduction):

ffmpeg -hide_banner -f avfoundation -list_devices true -i ''
# Replace AUDIO_INDEX with the index in the AUDIO device section, not the video section.
ffmpeg -n -hide_banner -f avfoundation -i ':AUDIO_INDEX' -t 5 -c:a pcm_s16le /tmp/vmark-audio-test.wav

Play known sound through the selected input path during the capture. Do not infer success just from file size.

Expected behavior

A recording command can request audio input permission, with the user retaining the choice to allow or deny it. After permission and routing are correct, the captured file contains the known sound.

Actual behavior and evidence

  • The original 616.6506875-second recording contained 9,866,411 PCM samples, all zero.
  • The controlled short capture also contained only zero samples in both channels.
  • TCC attributed the original FFmpeg process to app.vmark and logged the following excerpts (process IDs, addresses and unrelated attribution details omitted):
Prompting policy for hardened runtime; service: kTCCServiceMicrophone requires entitlement com.apple.security.device.audio-input but it is missing
Policy disallows prompt ... access to kTCCServiceMicrophone denied
AUTHREQ_RESULT: ... authValue=0, authReason=5 ...

Read-only inspection:

codesign -d --entitlements - /Applications/VMark.app
/usr/libexec/PlistBuddy -c 'Print :NSMicrophoneUsageDescription' /Applications/VMark.app/Contents/Info.plist

The installed app uses Hardened Runtime. Its signature has the three existing JIT/library-validation entitlements but no com.apple.security.device.audio-input; the usage-description key is also absent.

This establishes a permission blocker. A corrected, locally ad-hoc-signed release build was subsequently tested as a separate app (app.vmark.audio-test): macOS displayed an audio-input prompt, the user allowed it, and FFmpeg captured the known 880 Hz signal from BlackHole in both channels. Each channel contained 128,422 nonzero samples, peak 1200, and FFmpeg exited 0. The original installed app was not changed. This is local test evidence, not a claim that the maintainer-signed/notarized release has been validated.

Possible fix / contribution

I have prepared a small local candidate that adds the audio-input entitlement and microphone usage description, and documents terminal audio permission. VMark currently shares sidecar-entitlements.plist between the main app and sidecar signing; the candidate preserves this layout, so the new entitlement is shared too. Maintainer review of that scope is welcome.

The candidate has passed plist checks, website build, all 46 pre-delta gates, a Rust release build, signed-bundle verification, MCP sidecar health check, and the allowed-input capture above. On 2026-09-30 the candidate was rebased onto upstream 4b1641c; all 46 pre-delta gates and the full pnpm check:all passed (exit 0). The signed-build and allowed-capture evidence above comes from the earlier baseline; the three patched files did not change upstream. With microphone access then switched off and the test app restarted, TCC returned denial for its microphone requests and FFmpeg could not create the BlackHole capture input. No audio file was produced; FFmpeg remained running and the probe terminated it at its timeout. The user subsequently restored permission. It adds no recording/transcription UI and does not bypass macOS user consent.

References:

Existing issues/PRs were searched for audio-input and microphone; no matching report was found in those searches.

Daily-use acceptance

After restoring permission, the reporter ran the usual local recording script from the test app’s integrated terminal, recorded a spoken-audio segment, and completed local Whisper transcription. The WAV contained 107.5 seconds of audio and 1,474,263 nonzero samples. The reporter checked the transcript and confirmed its opening and ending matched the played segment. This verifies the recording-to-transcription workflow; it does not claim error-free transcription. No course audio or transcript is attached.

Activity

  1. xiaolai commented on Sep 30, 2026

    @xiaolai
    Owner

    Fixed in #1487, which ships in the next release (0.9.89). Programs run in VMark's integrated terminal can now ask for the microphone, the camera and Apple Events, and macOS shows a prompt under VMark's name instead of silently denying access. You can manage the permissions in System Settings → Privacy & Security.

    已在 #1487 修复,将随下一个版本(0.9.89)发布:在 VMark 集成终端中运行的程序现在可以请求麦克风、摄像头和 Apple 事件权限,macOS 会以 VMark 的名义弹出提示,而不再静默拒绝。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions