Workspace trust dialog shows a fraction of the pre-approved permissions and offers no way to review them
Summary
Since 2.1.232 removed trust inheritance from parent directories, every repository asks for its own trust
confirmation. That change is correct. But it exposed a gap in the dialog it now shows far more often: the
dialog asks me to accept a set of pre-approved permissions while showing me only a fraction of them, with
no way to expand the list, and no option other than accept everything or quit.
In practice the prompt asks for informed consent while withholding most of the information.
What the dialog looks like
⚠ This folder pre-approves 35 tool permissions in .claude/settings.local.json:
Bash(pdftotext -layout "<file-1>.pdf" -), Bash(pdftotext -layout "<file-2>.pdf" -),
Bash(apt list *), Bash(dpkg -l), Bash(sudo -n apt-get install -y poppler-utils),
Bash(pdftotext -layout "<file-3>.pd…, and 26 more
These will apply without asking. Only proceed if you trust this configuration.
❯ 1. Yes, I trust this folder
2. No, exit
8 of 35 shown (~23%). The rest is summarised as "and 26 more". Entries are also truncated mid-string.
One of the eight visible entries is sudo -n apt-get install, so the 26 hidden ones cannot be assumed
harmless.
The three gaps
- The list is truncated and cannot be expanded. No "show all", no pager, no scroll. To read what I am
approving I have to quit, open the settings file in another tool, and start over.
- There is no third option. The choice is "trust this configuration as it stands" or "exit". What is
missing is the obvious middle: review and approve individually, or *trust the folder but drop the stored
pre-approvals and ask again as they come up*. Both are safe; neither exists.
- The dialog does not mention everything trust unlocks. It names
settings.local.jsonpermissions only.
Nothing about .claude/settings.json hooks (which execute without any tool call), .mcp.json servers,
or CLAUDE.md. Hooks are the highest-impact item and go unmentioned.
Why this matters at scale
I audited my own machine after hitting this:
| | |
|---|---|
| Projects with a .claude config | 57 |
| Pre-approved permissions in total | 1325 |
| Broad ones (arbitrary code execution, sudo, ssh *, generic cd *, paths outside the project) | 52 |
| Projects still untrusted, i.e. that will show this dialog | 45 |
These accumulated over months, one "always allow" at a time, each reasonable in its moment. Nobody audits
them as a set — which is exactly what the dialog now asks for, at a glance, 35 at a time.
The most interesting category the audit surfaced was not the arbitrary-execution entries, but permissions
reaching outside their own project — Read() patterns pointing at unrelated directories, and arm -rf targeting another project's cache. Those break the per-project isolation that folder-level trust
assumes, and they are invisible in a dialog that shows eight lines.
No timestamps, and the only reconstruction path expires
settings.local.json stores a plain array. There is no record of when each permission was granted, or by
which session, so "is this configuration still what I intended?" cannot be answered.
The only reconstruction path is the session transcripts under ~/.claude/projects/<project>/*.jsonl — finding
the first tool call each permission covers. That works, but transcripts roll off after roughly 30 days: on my
machine the oldest surviving one is 30 days old and 28 of 50 project directories are already empty. I could
date 82 of 1325 permissions. The rest are unknowable.
Suggested fixes
- Show the whole list — scrollable/pageable, or a "press
vto view all" key. Never truncate individual
entries.
- Add the missing third option:
3. Review permissions individually(accept/reject each), and/or3. Trust folder, discard stored pre-approvals(start clean, re-prompt on demand).
- Rank what is shown. With limited space, surface the broadest entries first — arbitrary code
execution, sudo, paths outside the project, wildcards — rather than the first eight in file order.
- Name hooks, MCP servers and
CLAUDE.mdin the dialog when present. Hooks especially. - Record a timestamp (and ideally a session id) per entry when a permission is stored, so the set can be
audited later. Small change, lasting value.
- Optionally, a
claude permissions reviewcommand for the same job outside the launch path.
Note
The 2.1.232 change itself is right — a cloned third-party repo silently inheriting a parent's trust, and with
it its own pre-approvals, is a real hole. This report is about the dialog that now carries that decision.
---
Environment: Claude Code 2.1.232, native install, Linux (WSL2).
3 Comments
Following up with new evidence, and with a note on what has changed since I filed this.
What has improved. On 2.1.234 the dialog now offers a third path:
> 1. Yes, I trust this folder
When I filed this, the options were
1. Yes, I trust this folder/2. No, exit— accept thewhole set or quit. That addition is a real improvement, and I'm glad to see it.
What still stands. The list itself is still not reviewable. From the dialog I filed against,
with 35 rules in
.claude/settings.local.json:This folder pre-approves 35 tool permissions in .claude/settings.local.json:
Bash(pdftotext -layout "<file-1>.pdf" -), Bash(pdftotext -layout "<file-2>.pdf" -),
Bash(apt list *), Bash(dpkg -l), Bash(sudo -n apt-get install -y poppler-utils),
Bash(pdftotext -layout "<file-3>.pd..., and 26 more
Eight rules named, 26 hidden, and the eighth truncated mid-rule. I reproduced the same shape on
2.1.234 with a synthetic 35-rule config. There is no way to scroll, expand, or print the full set
before choosing, and resizing the terminal doesn't help — the cap is fixed, not overflow.
This matters because of what the docs say about this dialog:
— https://code.claude.com/docs/en/permissions
23% of them are listed. And the new option 2 sharpens the point rather than settling it: the choice
is now "accept 26 rules I have not seen, or decline all 35" — still with no informed middle.
Worth noting where these rules come from:
settings.local.jsonaccumulates from "Yes, don't askagain" approvals over months. By the time the dialog appears, the user is being asked to re-consent
in bulk to a set they never reviewed as a set.
The ask. This looks like a gap between documented and actual behaviour rather than a feature
request, so I'd like to ask whether the
enhancementlabel (applied automatically about a minuteafter filing) could be reconsidered. Either the dialog should allow the full set to be reviewed —
scroll, an expand key, or printing it on request — or the documented sentence should be corrected.
Environment: Claude Code 2.1.232, native install, Linux (WSL2).
Happy to test a fix on WSL2.
A correction to my own opening premise, prompted by @wshallwshall's trace in #90638.
I wrote that 2.1.232 "removed trust inheritance from parent directories". That is too flat. Their reading of the shipped code shows the ancestor walk is still present in the trust lookup, and is skipped only when the target folder carries settings the app treats as execution-granting — a non-empty
hooks.<Event>array, or apermissions.allowrule forBashorPowerShell. So inheritance was narrowed, not removed, and my framing of why the dialog now appears so often was wrong.What the report rests on is unaffected: when the dialog does fire, it names 8 of 35 rules and collapses the rest into
and 26 more, with no way to review them before choosing.If anything the correction sharpens it. The ancestor walk is skipped precisely for folders that carry hooks or Bash/PowerShell allow rules — which is to say, precisely the folders with the largest and most consequential permission sets. My own case is one: 35 rules in
.claude/settings.local.json, includingsudo -n apt-get install. So the truncated dialog is not shown at random. It is shown, by design, on the folders where the list most needs reading, and it is on exactly those folders that inheritance stops covering for you.The ask is unchanged: let the full set be reviewed, scroll, an expand key, or printing it on request — or correct the documented sentence that says the dialog "lists the rules and directories the folder would grant so you can review them first".
Rechecked on 2.1.278 today, since my original report was against 2.1.232 and I did not want this to sit here describing behaviour that had already been fixed. It has not been. And the recheck turned up one thing I did not expect.
The cap is still eight, and it is a fixed cap. A throwaway directory with 35 synthetic rules in
.claude/settings.local.json, run at 200 columns — far more width than the list needs:At 80 columns the eighth rule is cut mid-token; at 200 it renders in full. Either way the list stops at eight and the remaining 27 are collapsed. So this is not terminal overflow, and widening the terminal does not help, which is what I claimed in August without having measured it. Now measured: same eight rules at 80×24, at 200×60, and in a git repo at 120×40.
Something has also gone backwards. In August I noted, with thanks, that 2.1.234 had added a third option:
On 2.1.278 that option is gone. All three of my runs today show:
@flo-az's paste in #94277, captured on 2.1.270, shows the same two. So it disappeared somewhere between 2.1.234 and 2.1.270. One real improvement did survive, and it is worth saying: the destructive option is no longer the default —
No, exitnow carries the cursor, where in AugustYes, I trust this folderwas listed first. But the informed middle path is gone, and the choice is back to what it was when I filed: accept 27 rules I have not seen, or quit.This is now the third report on this dialog. Alongside this issue:
bug,area:security) — the desktop trust modal names thecwdpassed tospawn_task, while the session runs in a worktree the click creates elsewhere. One directory approved, another executed in.bug,has repro,area:security) — the startup trust dialog omits the hook warning that the/cddialog shows for the very same directory. Hooks run commands on the first tool call, before any further approval is asked for.Three platforms (WSL, Windows, macOS), three people who arrived at this independently, one surface. And the shape is the same in all three: the trust dialog is the consent gate, and what it displays is not what accepting it grants. Truncated in mine, absent in @flo-az's, wrong in @wshallwshall's.
#94277 is the closest to this one — same dialog, same settings file, same read of that file. The dialog already parses
.claude/settings.local.jsondeeply enough to count 35 permission rules. It just does not report what it found there, or reports a fraction of it.Which brings me back to the label. This issue carries
enhancement, applied by the bot a minute after filing. The other two, on the same dialog and the same class of defect, carrybug, and #94277 carrieshas reproas well. I would ask again thatenhancementbe reconsidered here, for consistency with the two issues this one now sits alongside, and because the documented behaviour is this:— https://code.claude.com/docs/en/permissions
The ask is unchanged, and unchanged in scope: let the full set be reviewed — scroll, an expand key, or printing it on request — or correct that sentence.
Environment: Claude Code 2.1.278, native install, WSL2 (Ubuntu 24.04, kernel 5.15.133.1-microsoft-standard-WSL2).