Add Virtualization Framework Support

Nucleic-Session: 4FCF4F8B-A7C3-42F6-BE13-1979080F61C7
Co-authored-by: Nucleic <[email protected]>
This commit is contained in:
2026-07-06 02:38:50 -07:00
co-authored by nucleic
parent a052c32b02
commit ded575a22b
+14 -7
View File
@@ -311,13 +311,20 @@ present.
## 11. TCC, packaging, provisioning
- **TCC:** the agent needs `kTCCServiceAccessibility` (AX control + CGEvent) and `kTCCServiceScreenCapture`
(ScreenCaptureKit). A proper signed **`.app` bundle** is the *correct* shape on macOS 26.1+ (which
wants a real bundle for Screen Recording and attributes to the responsible process) — an improvement
over granting a bare CLI. Pre-grant both to the agent's bundle-id / code requirement via the same
SIP-off direct system-`TCC.db` write the provisioner already does for `screencapture`/`cliclick`
([MACOS_VM](MACOS_VM.md) §12.5); no other unattended path exists (PPPC can't silently grant Screen
Recording; `tccutil` can't grant).
- **TCC:** the agent needs **three** distinct grants, each a separate `TCC.db` service:
`kTCCServiceAccessibility` (AXUIElement read/control — `AXIsProcessTrusted`), `kTCCServicePostEvent`
(CGEvent input synthesis — surfaced under the "Accessibility" list but a distinct row;
`CGPreflightPostEventAccess`/`CGRequestPostEventAccess`), and `kTCCServiceScreenCapture` (ScreenCaptureKit
`CGPreflight/CGRequestScreenCaptureAccess`). A proper signed **`.app` bundle** with a **native Mach-O**
main executable is the *correct* shape (TCC mis-handles script-based executables, and macOS 26.1+ wants a
real bundle for Screen Recording, attributed to the responsible process) — an improvement over granting a
bare CLI. Pre-grant all three to the agent's bundle-id / code requirement via the same SIP-off direct
system-`TCC.db` write the provisioner already does ([MACOS_VM](MACOS_VM.md) §12.5); no other unattended
path exists (PPPC can't silently grant Screen Recording; `tccutil` can't grant). Note a grant is often
not picked up until the process **restarts** (esp. Screen Recording), so the LaunchAgent should be
bounced after provisioning writes the rows. If a grant is missing at runtime the agent reports it in the
`ping` reply (via `AXIsProcessTrusted` + the `CGPreflight*` checks) so the host can surface an actionable
"agent present but not authorized" state rather than silently failing.
- **Packaging:** build + code-sign `NucleicVMAgent.app` on the host (ad-hoc or Developer ID is fine for a
local VM; no notarization needed to run inside the guest, and no special entitlements beyond TCC).
Bake it into the base image (e.g. `/Library/Nucleic/NucleicVMAgent.app`) and install a LaunchAgent