---
title: "Permissions reloaded, building a tight allow-list | Recipe — StudioMeyer Academy"
description: "Beyond the safe defaults from Recipe 1.4: a project-scoped allow-list that pre-clears 90% of routine prompts without giving up the dangerous-command guardrails."
canonical: "https://studiomeyer.academy/en/recipes/3.2-permissions-plus"
language: en
markdown_versions: ["https://studiomeyer.academy/en/recipes/3.2-permissions-plus.md"]
publisher: "StudioMeyer Academy, https://studiomeyer.academy (llms.txt: https://studiomeyer.academy/llms.txt)"
---

[← Alle Recipes](https://studiomeyer.academy/recipes)

Phase 3 · Basic Workflows·5 steps

# Permissions reloaded, building a tight allow-list

Beyond the safe defaults from Recipe 1.4: a project-scoped allow-list that pre-clears 90% of routine prompts without giving up the dangerous-command guardrails.

5 steps0%

Du liest ohne Account. Mit [Login](https://studiomeyer.academy/login?next=/recipes/3.2-permissions-plus) speichern wir Step-Fortschritt + Notes.

# Permissions reloaded

Recipe 1.4 set up the safe defaults. Bash blocked, file edits scoped, network calls reviewed. That keeps you out of trouble. But after a few weeks of real use you start clicking "allow" on the same five commands every session: `npm test`, `git status`, `git diff`, `ls`, `cat package.json`. Each click costs three seconds and your concentration.

This recipe builds a tight allow-list that pre-clears those routines without re-opening the gates the safe defaults closed.

### Step 1: Spot the prompts you keep approving

Open `~/.claude/transcripts/` (or use the `/fewer-permission-prompts` skill if you have it installed) and skim the last week. You're looking for tool calls you approved more than three times. Those are candidates for an allow-rule.

The skill is the lazy path:

```
/fewer-permission-prompts
```

It scans your transcripts, ranks the most-clicked commands, and produces a JSON snippet ready to paste. If you don't have it, do it manually, `grep "Allow this" ~/.claude/transcripts/*.jsonl | head -50` is enough.

### Step 2: Add a project-scoped allow-list

Project-scoped lives in `<repo>/.claude/settings.local.json`. Things in here only apply when Claude is launched from that directory:

```json
{
  "permissions": {
    "allow": [
      "Bash(npm test)",
      "Bash(npm run build)",
      "Bash(git status)",
      "Bash(git diff)",
      "Bash(git log:*)",
      "Read(./*)",
      "Edit(./src/**)",
      "Glob(./*)",
      "Grep(./*)"
    ]
  }
}
```

Two things to note:

- `Bash(git log:*)`, the `:*` suffix lets any flag through (`--oneline`, `-10`, `--graph`). Without it only the bare `git log` is allowed.
- `Edit(./src/**)`, scopes edits to your source tree. `./node_modules/**` won't auto-approve.

### Step 3: Deny rules for hard limits

Allow-list is offense. Deny-list is defense. Even when an allow-rule technically matches, a deny-rule can override:

```json
{
  "permissions": {
    "allow": [
      "Bash(*)"
    ],
    "deny": [
      "Bash(rm -rf*)",
      "Bash(git push --force*)",
      "Bash(git reset --hard*)",
      "Bash(prisma migrate reset*)",
      "Bash(docker system prune --volumes*)"
    ]
  }
}
```

The point is not to stop a malicious agent (the model is on your side). The point is to add friction in front of the few commands that destroy hours of work in one keystroke.

### Step 4: Verify settings parse

The validator on this step parses `~/.claude/settings.json` (the global file). For project-scoped checks Claude reads `.claude/settings.local.json` automatically the next time you launch it from that directory.

Run `academy_validate_step`. If it fails, fix the JSON, a stray comma is the usual cause.

Client check · run on your machine

python3 -m json.tool ~/.claude/settings.json > /dev/null && echo "valid" || echo "invalid or missing"

**Expect:** Prints "valid".

**If stuck:** Fix the JSON syntax — settings.json must parse, even if it is just \`{}\`.

### Step 5: Reload and watch

In an open Claude session, type `/permissions` to see the merged allow-list (global + project + session-level). The project rules should appear when you launch from that repo.

Test by running `npm test` once. No "Allow this?" prompt → you saved a click forever.

Re-audit every two months. Three signals that you need to revisit:

- A new command shows up in the top-five "Allow this" list. Add it.
- A command in the allow-list hasn't been used in a month. Remove it.
- You added a deny rule because something scared you. Keep that. Promote it to global if it would scare you in any project.

[← Slash commands and built-in sh](https://studiomeyer.academy/recipes/3.1-slash-commands) [Subagents 101, when to delegat →](https://studiomeyer.academy/recipes/3.3-subagent-basics)

Phase 3

Permissions, slash commands, project layout, multi-tool setup

[Alle Phasen →](https://studiomeyer.academy/recipes)

Concepts

[~/.claude/settings.json](https://studiomeyer.academy/concepts/settings_json) [Permissions](https://studiomeyer.academy/concepts/permissions)

## Sitemap

Public pages of this site as Markdown: [sitemap](https://studiomeyer.academy/sitemap.md). Curated entry point: [llms.txt](https://studiomeyer.academy/llms.txt), full text: [llms-full.txt](https://studiomeyer.academy/llms-full.txt).
