Skip to content

fix(cua-driver-rs)(macos): permissions status never reports the caller's grants#1774

Merged
f-trycua merged 1 commit into
mainfrom
fix/permissions-status-no-caller-false-positive
May 30, 2026
Merged

fix(cua-driver-rs)(macos): permissions status never reports the caller's grants#1774
f-trycua merged 1 commit into
mainfrom
fix/permissions-status-no-caller-false-positive

Conversation

@f-trycua
Copy link
Copy Markdown
Collaborator

@f-trycua f-trycua commented May 30, 2026

Problem

cua-driver permissions status, run standalone from a terminal, prints ✅ granted even when com.trycua.driver has zero TCC grants:

% cua-driver permissions status
Accessibility:    ✅ granted
Screen Recording: ✅ granted
Source: caller

macOS attributes Accessibility / Screen-Recording to the responsible process (the LaunchServices launching app), not the executable path. With no daemon listening, run_permissions_status fell back to an in-process check_permissions that reads the calling terminal's grants. The Source: caller label was the only signal it was lying — buried under two green checkmarks. A status command that confidently reports "granted" when the driver has nothing is worse than no command.

Fix

The only process that can read com.trycua.driver's real grants is the launchd bundle daemon (driver-daemon attribution, ppid==1). So:

State Output
daemon up + driver-daemon ✅/❌ granted · Source: driver-daemon (reliable, unchanged)
no daemon ❓ unknown + guidance — no booleans in --json
terminal-spawned daemon (caller attribution) ❓ unknown — its grants are the terminal's, not the driver's

The in-process caller fallback in run_permissions_status is deleted. --json in the unknown case emits {"daemon_running": false, "status": "unknown", "reason": …} with no accessibility/screen_recording keys, so no scripted consumer can ever misread a false granted: true. A missing source (non-macOS, no TCC) is still trusted as-is.

The grant flow is unchanged — it already spawns via LaunchServices and verifies.

Verified locally

Docs

Updated autostart.mdx, installation.mdx, faq.mdx to describe daemon-or-unknown behavior and point at permissions grant as the authoritative grant+verify path.

Closes the false-positive thread from the macOS TCC attribution series (follow-up to #1765/#1773).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Documentation

    • Updated permissions guidance clarifying that cua-driver permissions verbs handle attribution via the daemon
    • Clarified behavior: permissions status returns "unknown" when no daemon is running
  • Bug Fixes

    • Improved permissions status reporting to prevent false positives by returning "unknown" when daemon is unavailable

Review Change Stack

…r's grants

`cua-driver permissions status` could print `✅ granted` even when
`com.trycua.driver` had zero TCC grants: with no daemon listening it fell
back to an in-process `check_permissions`, which reads the *calling*
terminal's grants (macOS attributes TCC to the responsible process, not the
executable path). The `Source: caller` label was the only tell, buried under
two green checkmarks — a confident lie.

Only the launchd bundle daemon (`driver-daemon` attribution, ppid==1) can
read the driver's real grants. So:

- Daemon up + `driver-daemon` attribution → report its answer (unchanged,
  reliable).
- No daemon, OR a daemon answering with `caller` attribution (someone ran
  `cua-driver serve` by hand from a terminal) → report `❓ unknown` and emit
  NO accessibility/screen_recording booleans in `--json` (just
  `daemon_running:false, status:"unknown"`). Nothing downstream — human or
  script — can ever misread a false `granted: true`.

Deletes the in-process caller fallback in `run_permissions_status`. The
`grant` flow is unchanged. Docs (autostart, installation, faq) updated to
describe the daemon-or-unknown behavior and point at `permissions grant` as
the authoritative grant+verify path.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented May 30, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docs Building Building Preview, Comment May 30, 2026 9:29pm

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 30, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c1ead22d-f412-48ed-9fdc-7f20dca58e32

📥 Commits

Reviewing files that changed from the base of the PR and between 9b5b5a9 and d364dba.

⛔ Files ignored due to path filters (1)
  • libs/cua-driver/rust/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (4)
  • docs/content/docs/cua-driver/guide/getting-started/autostart.mdx
  • docs/content/docs/cua-driver/guide/getting-started/faq.mdx
  • docs/content/docs/cua-driver/guide/getting-started/installation.mdx
  • libs/cua-driver/rust/crates/cua-driver/src/cli.rs

📝 Walkthrough

Walkthrough

Refactored cua-driver permissions status to query only a running daemon and report unknown when unavailable, removing the in-process fallback. Updated three user-facing guides to document the new daemon-only behavior and recommend the dedicated permissions grant and permissions status verbs for correct attribution.

Changes

Daemon-only permissions status and documentation

Layer / File(s) Summary
Daemon-only permissions status command
libs/cua-driver/rust/crates/cua-driver/src/cli.rs
Help text updated to describe daemon-bundle identity attribution and unknown behavior; run_permissions_cmd routing changed to call run_permissions_status(json) without registry; status implementation now queries only a listening daemon and explicitly emits unknown (with JSON reason) when no properly attributed daemon response is available, removing the prior in-process check_permissions fallback. Attribution logic trusts only driver-daemon sources; user-facing messaging condition generalized to "not both granted" check.
Documentation updates for permissions verbs guidance
docs/content/docs/cua-driver/guide/getting-started/autostart.mdx, docs/content/docs/cua-driver/guide/getting-started/faq.mdx, docs/content/docs/cua-driver/guide/getting-started/installation.mdx
Three getting-started guides updated to document daemon-only behavior: autostart.mdx instructs using cua-driver permissions status for daemon-reported grant state (including unknown when no daemon runs); faq.mdx adds guidance explaining the recommended permissions grant/status workflow with correct LaunchServices attribution; installation.mdx adds a callout preferring permissions grant for authoritative TCC dialog and permissions status for daemon-reported state.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

  • trycua/cua#1561: Directly related—both address macOS permissions-status behavior; the retrieved issue describes the incorrect in-process AXIsProcessTrusted() fallback that this PR removes by treating absent/unaligned daemon responses as unknown.

Possibly related PRs

  • trycua/cua#1760: Modifies the same cli.rs macOS check_permissions/daemon attribution path, preventing in-process terminal-attributed prompts via prompt:false constraint.
  • trycua/cua#1765: Enhances check_permissions to report source and live probe capture—related to the same permissions-attribution logic and fallback path that this PR removes.
  • trycua/cua#1767: Adds post-install hint text pointing users to the same permissions status|grant commands that this PR updates and clarifies.

Poem

🐰 A daemon's whisper, clear and true,
No falling back to what we once knew.
"Unknown" rings loud when no one's there—
The permissions status, daemon-aware! ✨

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/permissions-status-no-caller-false-positive

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@f-trycua f-trycua merged commit 6c498eb into main May 30, 2026
9 of 12 checks passed
@f-trycua f-trycua deleted the fix/permissions-status-no-caller-false-positive branch May 30, 2026 21:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant