github →

New request

#1485: bug(macos): repeated TCC 'Terminal would like to access data from other apps' prompts during agent file searches

We'll provision a sandbox, run an agent against the issue, and open a draft PR. You can pull the branch and iterate from there.

Issue
bugupstream-change

Summary

On macOS, users hosting the WebUI / running the Mac app see repeated TCC permission prompts like:

"Terminal" would like to access data from other apps. Keeping app data separate makes it easier to manage your privacy and security. [Don't Allow] [Allow]

Reported by @Cygnus on Discord (May 02 2026):

"I'm trying to figure out what code keeps on giving me this several times in a row, but I can't expand and see the code it's running when it does"

(The "can't expand and see the code" part is the rendering bug captured in #1484 — separate fix. This issue is about why the prompt fires at all and how to stop the repetition.)

Root cause

macOS's TCC (Transparency, Consent, and Control) framework fires a permission prompt when a process touches files inside an app's protected container — typically:

  • ~/Library/Containers/<bundle.id>/ — every sandboxed Mac App Store app
  • ~/Library/Group Containers/<group.id>/
  • ~/Library/Mail/, ~/Library/Messages/, ~/Library/Calendars/, ~/Library/Reminders/
  • ~/Library/Application Support/<vendor>/<app>/ for some vendors
  • ~/Library/Mobile Documents/ (iCloud Drive)
  • ~/Pictures/Photos Library.photoslibrary/
  • Under macOS Sequoia (15.x) and later, additional ~/Library subtrees

The TCC prompt is per-container, so a single user-initiated file walk that touches 30 apps' containers fires up to 30 prompts. If the user clicks "Don't Allow" once, the prompt re-fires on the next unrelated container the same scan happens to traverse. A single broad "find a file in my home directory" can produce a deluge.

The shape of our trigger (verified in code):

tools/file_operations.py (in hermes-agent, used by WebUI as the file-search engine) calls rg --files (or rg for content search) with the user's path as the root. Two paths today exclude only dot-prefixed hidden directories (line 975 for find fallback, line 1169 for grep fallback) — ~/Library/Containers is not dot-prefixed and is not excluded.

So when a search runs with a wide path:

  • search_files(target='files', path='~') — walks all of $HOME including ~/Library/Containers/* etc. → many TCC prompts
  • search_files(target='content', path='~') — same
  • Even path='~/Library' directly (some skills do this, e.g. credential auditing) → guaranteed to hit containers

Workspace-rooted searches (path is the active workspace) usually don't hit this — most users' workspaces are outside ~/Library. So the trigger is wide-scope user paths, not the workspace.

The TCC prompt that fires says "Terminal" because Hermes runs as a child of the user's terminal session under launchd / bash and inherits the terminal's TCC identity. (Or the Mac app's identity if running under that wrapper — depends on how it was launched.)

What to fix

1. Default-exclude TCC-protected paths from file walks (primary fix)

tools/file_operations.py — extend the existing hidden-dir exclusion list with a macOS-specific TCC-protected path list. Apply across all four search paths (rg --files, rg content, find fallback, grep fallback).

Default exclude list (only on macOS — sys.platform == 'darwin', gated):

_MACOS_TCC_EXCLUDED_GLOBS = [
    '!Library/Containers/**',
    '!Library/Group Containers/**',
    '!Library/Mail/**',
    '!Library/Messages/**',
    '!Library/Calendars/**',
    '!Library/Reminders/**',
    '!Library/Mobile Documents/**',
    '!Library/Application Support/com.apple.sharedfilelist/**',
    '!Library/Application Support/AddressBook/**',
    '!Pictures/Photos Library.photoslibrary/**',
    '!Library/CloudStorage/**',  # iCloud, Dropbox, Google Drive sync mounts
]

For rg, these become --glob '!Library/...' flags. For find, -not -path '*/Library/Containers/*' predicates. For grep, --exclude-dir=Library/Containers (note: grep's --exclude-dir is per-component, not path; need find-prefilter or skip-grep-fallback for these).

2. Make the exclusion overridable

Some workflows legitimately want to read inside containers (e.g. agent inspecting iMessage exports the user dropped there). Two override paths:

  • Per-call: new include_tcc_paths=True arg to search_files() / search_content() — when explicitly true, skip the TCC exclusion. Document in the tool description that this triggers macOS prompts.
  • Per-config: agent.search.include_tcc_paths: true in config.yaml for the rare user who wants the old behavior.

Default is exclusion. Opting in is loud.

3. Pre-emptive guidance in the agent

Inject into the agent's system context on macOS only:

macOS file-search note: searches inside ~/Library/Containers, ~/Library/Group Containers, ~/Library/Mail, ~/Library/Messages, ~/Library/Calendars, and similar protected paths are excluded by default to avoid TCC permission prompts. If the user needs to inspect those, ask them to grant Full Disk Access to their terminal or pass include_tcc_paths=True explicitly.

~5 lines added to the macOS branch of agent context. Prevents the agent from repeatedly attempting the same scan and re-triggering prompts.

4. Document the fix in our README

A "macOS permission prompts" section explaining:

  • TCC prompts are macOS-level, not Hermes-controlled
  • Default behavior excludes TCC-protected paths
  • To grant access permanently: System Settings → Privacy & Security → Full Disk Access → add Terminal (or the Mac app)
  • To opt in per-call: explicit include_tcc_paths=True

What this is NOT

  • Not a request to suppress TCC at the OS level. We can't and shouldn't.
  • Not a hard refusal. If the user wants the access, the override path exists.
  • Not breaking workspace searches (workspace is normally outside ~/Library, unchanged).

Cross-repo note

The actual code change lives in hermes-agent (tools/file_operations.py) since that's where the file-search runs. The WebUI inherits the fix automatically. Filing here because:

  1. WebUI is the user-visible product where Cygnus hit it
  2. The Mac-app + WebUI combo is a primary affected configuration
  3. We track parity issues that fix with us

Once accepted, mirror the fix to the agent repo or coordinate the change there. May also want a short "macOS prompts" note in our docs even if the underlying fix is upstream.

Reproducer

On any macOS machine running the WebUI / Mac app:

  1. Have at least one Mac App Store app installed (creates ~/Library/Containers/<bundle>)
  2. In a session, ask the agent: "Find any file named config.yaml in my home directory"
  3. Agent calls search_files(target='files', pattern='config.yaml', path='~')
  4. ripgrep walks ~/Library/Containers/com.apple.X/, ~/Library/Containers/com.somevendor.app/, etc.
  5. macOS fires TCC prompt for the first protected container
  6. User dismisses; ripgrep walks the next container; prompt re-fires
  7. Repeat N times where N = number of distinct TCC-protected containers in the user's $HOME

After fix: zero prompts for the same call.

Files

  • tools/file_operations.py (in hermes-agent) — exclude-list constants, gating, plumbing through _search_with_rg, _search_with_grep, _find_files, _find_content
  • tools/registry.py (in hermes-agent) — extend tool schema for include_tcc_paths arg
  • agent/system_context.py or wherever macOS-specific context goes (in hermes-agent) — note injection
  • README + Mac install docs (in hermes-webui and hermes-agent) — TCC explanation
  • Tests covering: default-exclude on darwin, no-exclude on linux, override flag, override config

Estimated effort

~80 LOC code + ~120 LOC tests + docs. Most of the complexity is in plumbing the override flag through 4 search paths consistently. Single PR. P2 — not user-blocking but high annoyance for any macOS user who runs a wide search.

Reporter / context

  • @Cygnus, Discord #testers-talk, May 02 2026
  • Surfaced as one of two screenshots in the same morning's batch (other was the tool-card-args readability bug → #1484)
  • Affects every macOS user; severity proportional to how often they run wide-scope searches
Assessmentadvisory
bug●● medium75% confidence

macOS-specific TCC permission bug in agent file-search logic requires protected-path exclusions and possibly build-configuration or entitlement updates.

Likely files
  • api/agent_tools.py
  • api/file_search.py
  • infra/config/macos-entitlements.plist
  • tests/file_search_regression.py
Create the request

This opens a fresh agent run and a draft PR for issue #1485.

Cancel