setup-claude-guardrails
Installs guardrails in this project's .claude/ (and its git worktrees) that keep Claude Code from reading, writing or running commands on paths outside a…
Skill by Lichens-Innovation
Chalk Labs
Need help deploying setup-claude-guardrails?
Chalk Labs sets up agents like this inside real teams: connected to your tools, tested on your data, with a human in the loop where it matters.
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/lichens-innovation-setup-claude-guardrails
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: security, writing, agent-building
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
- Runs as
- Node.js package
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/setup-claude-guardrails
What's inside
- Skill name
setup-claude-guardrails- Description
- Installs guardrails in this project's .claude/ (and its git worktrees) that keep Claude Code from reading, writing or running commands on paths outside a scoped directory (the project, or a chosen parent like ~/Documents/gits), and block env files (.env, .env.local, ...) except .env*.example. Combines permission deny rules, blockReadsOutsideWorkingDirectories, an optional Bash sandbox and a PreToolUse hook. Use when the user wants to sandbox Claude to the repo, protect secrets from Claude, add safety hooks, or invokes /setup-claude-guardrails.
- License
- MIT
- Instructions
- 170 lines in SKILL.md · view on GitHub
Before installing
- Ships executable scripts
- Instructions read files in your home folder (~/.ssh, ~/.aws…)
Agent Skills spec issues
- body: contains an absolute path from the author's machine
Files (5)
- README.md
- SKILL.md
- guardrails.md · assets/
- guardrails.mjs · scripts/
- test-guardrails.sh · scripts/
SKILL.md (first lines)
# Setup Claude Guardrails
Install layered guardrails into `.claude/settings.local.json`. They are personal: nothing is committed (`settings.local.json` is ignored by Claude Code, the hook and rule via `.git/info/exclude`). Use `.claude/settings.json` only if the user asks to share them with the team.
| Layer | Enforced by | Covers |
| ----- | ----------- | ------ |
| `blockReadsOutsideWorkingDirectories` | Claude Code | `Read`, `Grep`, `Glob`, `LSP` outside the project + `additionalDirectories` |
| `deny` `Read(...)` / `Edit(...)` rules | Claude Code | env files and Claude Code's credentials, for every file tool (also fed into the sandbox) |
| `sandbox` (optional) | the OS (Seatbelt / bubblewrap) | what Bash commands and their children can read and write |
| `PreToolUse` hook `scripts/guardrails.mjs` | heuristic on tool input | out-of-scope writes and Bash paths, env files (wildcards, case, symlinks), and asks before edits to the guardrails; with the sandbox, denies calls that can't leave it |
| `PostToolUseFailure` hook (same script) | matches error text | after a sandbox failure, tells Claude the cause and the fix, and to suggest improving the guardrail if it keeps costing steps |
The native layers are the real enforcement; the hook catches mistakes where nothing else would (e.g. `bypassPermissions`).
## Checkouts and worktrees
Everything is installed per checkout; each has its own untracked `.claude/`. `.git/info/exclude` is in the git common dir, shared by all.
- **Main checkout:** the parent of `git rev-parse --path-format=absolute --git-common-dir`. Install here first.
- **Claude Code worktrees** (`<main>/.claude/worktrees/<name>`, from `claude --worktree`, subagent `isolation: worktree`, desktop parallel sessions): a session that creates one keeps the main checkout's settings. For sessions opened inside one later, `.worktreeinclude` (step 6) copies the guardrail files into each new one.
- **Other linked worktrees** (`git worktree list --porcelain`): install into each; re-run after adding one.
## Files per checkout
- `.claude/hooks/guardrails.mjs`, from this skill's `scripts/guardrails.mjs`
- `.claude/rules/guardrails.md`, from `assets/guardrails.md`: tells Claude how to work with the hook (loads every session)
- `.claude/settings.local.json`: permissions, optional sandbox, hook registration
- shared `.git/info/exclude`: the hook and rule paths, and on Linux with the sandbox its mount stubs (step 7)
- `<main>/.worktreeinclude`: the hook, the rule and `settings.local.json`
## Workflow
1. **Check for an existing install** (read-only, before asking anything). If the session is already sandboxed, run `echo ok` first: on `apply-seccomp` every other check would fail too, so ask step 7's seccomp question now, then continue. Resolve the main checkout and linked worktrees, and say which one the session is in. In each, check:
- the hook and rule exist and are identical to this skill's copies;
- settings have the hook entry (`PreToolUse` and `PostToolUseFailure`) with the same `command`, all 18 `deny` entries from step 5, `blockReadsOutsideWorkingDirectories`, and Claude's temp dir in `additionalDirectories`;
- with the sandbox on: the sandbox entries step 5 would add for this machine (step 3's tool lookup), and `echo ok` runs (step 7);
- on Linux with the sandbox: every mount stub step 7 lists is in the shared exclude;
- `git check-ignore -q` passes for the hook, the rule and `settings.local.json`;
- once, in the main checkout: `.worktreeinclude` lists all three.
**All in place:** report the setup (roots from `additionalDirectories`, sandbox on/off, git hosting and `open` exclusions, hook up to date, which checkouts). Ask one question: keep it as is (recommended; stop, no tests), suggest allow rules only (step 2's allow-rules part, then merge the picks as in step 5; no other step), or reconfigure (step 2, current values as defaults). **Partial:** list the gaps and fill only those, current values as defaults. **None:** continue.
2. **Ask** in one `AskUserQuestion` call:
- "Which directories may Claude access?": project only (recommended), or project + others (e.g. `~/Documents/gits`). If none are named, ask for the paths before writing.
- "Enable the Bash sandbox?": Yes, strict (recommended: OS-enforced; network needs per-domain approval, no unsandboxed fallback), or No (hook heuristics only).
- Sandbox only: "Run git hosting commands outside the sandbox?": Yes (`gh`, `glab`, `git push`/`pull`/`fetch` use your Keychain, SSH agent and network; risky subcommands prompt), or No (they fail in the sandbox; run them with `!`). No recommendation: it trades isolation for convenience.
- Sandbox only: "Run `open` outside the sandbox?": Yes (recommended on macOS: the sandbox blocks `open`, so skills like `/claude-light` can't open a page; apps and URLs still prompt), or No (run `! open <path>` yourself).
- Sandbox and a JS lockfile (`pnpm-lock.yaml`, `package-lock.json`, `yarn.lock`, `bun.lock*`) only: "Let sandboxed commands reach the package registry?": Yes (only `registry.npmjs.org`; postinstall downloads such as Electron's from GitHub stay blocked), or No. No recommendation: lint and test runs rarely need it, installs are better run with `!` (step 8).
- Sandbox and `electron` in a `package.json` (any workspace) only: "Let Claude launch a desktop GUI app (Electron) for testing?" Default No, never preselected, no recommendation. Why it's asked: inside the sandbox Electron aborts at startup. On Linux: `FATAL:setuid_sandbox_host.cc ... The SUID sandbox helper binary was found, but is not configured correctly`, because Chromium's own sandbox can't start in bubblewrap (the namespace sandbox is refused by the sandbox's seccomp filter and the setuid helper isn't root-owned). On macOS: `FATAL:base/apple/mach_port_rendezvous_mac.cc: bootstrap_check_in com.github.Electron.MachPortRendezvousServer...: Permission denied (1100)`, then SIGTRAP: the Seatbelt profile refuses the Mach port check-in. `--no-sandbox` is not an acceptable fix. The display itself is no separate blocker to grant: on Linux `allowUnixSockets` is ignored (seccomp can't filter by path), so there is no per-socket grant, and the only switch, `allowAllUnixSockets`, is never added for this. If Yes, ask for the exact launch command, one per entry (e.g. `apps/desktop/node_modules/.bin/electron --remote-debugging-port=9333 *`). Find the binary with `find . -path '*/node_modules/.bin/electron' -not -path '*/node_modules/*/node_modules/*'`: in a pnpm workspace it sits under the workspace that depends on Electron, not the root. State the risk before writing: the command runs **with no sandbox at all**, so the app and anything it spawns can read and write everything the user can, and reach the network. The hook and permission rules still see the call, but the OS no longer enforces them for it. Only that exact command prefix is excluded: never `electron *`, `node *`, `npx *`, `pnpm *` or a wildcard on the whole binary directory. Then ask a second, separate question (Default No, no recommendation): "Also let sandboxed commands reach local ports (`sandbox.network.allowLocalBinding`)?" Without it the app opens but nothing can drive it: the sandboxed probe (`node`, `curl` to `127.0.0.1:<port>`) is refused instantly. The cost: any sandboxed command can then reach every local port (databases, dev servers), not just the app's.
- Linked worktrees only: "Install in which checkouts?": all (recommended), or the current one.
`AskUserQuestion` takes at most 4 questions: put any extra in a second call.
**Allow rules** (separate `AskUserQuestion` call, after the questions above). Each parallel or spawned session asks for permission on its own, so N sessions mean N prompts for the same `pnpm lint`. Run `node scripts/suggest-allow-rules.mjs <main checkout>` from this skill's directory. It only reads: package.json scripts (in the lockfile's package manager's forms), justfile recipes, Makefile targets, turbo.json tasks and commands named in `CLAUDE.md`, and prints JSON `candidates` (`command`, `kind`, `source`, `rules`) and `skipped` (`command`, `source`, `reason`). It proposes only lint, typecheck, test, format-check and verify commands whose name and body (followed through the scripts, recipes or targets they call) don't install, push, publish, deploy, fix/write files, delete, or run in watch mode, and leaves out rules already in `permissions.allow`.
- No candidates: say so and skip.
- Otherwise list every candidate (command, source, rules) and the skipped ones with their reason, then ask "Which commands may run without a prompt?" with `multiSelect: true`: one option per command (label the command, description the source and rules), up to 4 options per question and 4 questions. More than 16: one option per `kind`, its commands in the description. No recommendation and nothing preselected.
- Write only what the user picked. None picked, or the question dismissed: write no allow rules. Never add a rule the script didn't propose (an install, `git push`, publish, deploy or destructive command), even if the user names one under "Other": say why and leave it out.
3. **Prerequisites.**
- `node --version` >= 18, else stop: the hook would fail closed on every call.
- `claude --version` >= 2.1.257 for `blockReadsOutsideWorkingDirectories`; if older, skip that key and say to upgrade. If it fails with `operation not permitted` (the session's sandbox, before step 5's exclusion applies), ask the user to run `! claude --version`.
- Linux/WSL2 with the sandbox: tell the user to run `/sandbox` afterwards to check bubblewrap. Native Windows: no sandbox.
- Sandbox only: find where `node` and the project's package manager (from its lockfile: `pnpm`, `npm`, `yarn`, `bun`) are installed. The sandbox can't read `/home`, so a tool installed under it is "command not found" inside, and every `node` call fails (the hook still runs: hooks aren't sandboxed). Run `command -v node <pm>`; in an already sandboxed session it finds nothing, so read `echo $PATH` instead (it still lists the dirs). Record the install root of each one under `/home` that isn't already a root: `~/.nvm`, `~/.local/share/fnm`, `~/.volta`, `~/.bun`, `$PNPM_HOME` (default `~/.local/share/pnpm`) for pnpm, and `/home/linuxbrew/.linuxbrew` for Linuxbrew. If `PATH` leaves it unclear which dir holds the tool, ask the user to run `! command -v node <pm>`.
4. **Copy** the hook to `.claude/hooks/guardrails.mjs` and the rule to `.claude/rules/guardrails.md` in each chosen checkout. If a copy exists and differs, show the diff and ask first. In an already sandboxed session, `cp` can't write `.claude/hooks` (Claude Code protects it): copy with Read + Write (the hook asks once) or ask the user to run `! cp`. Don't suggest making the path writable.
In a git repo, append both paths to `$(git rev-parse --git-common-dir)/info/exclude` unless listed. Then in each checkout run `git check-ignore -q` on them and on `.claude/settings.local.json`, and add any that isn't ignored. If a path is tracked (`git ls-files --error-unmatch`), ignoring it does nothing: ask whether to `git rm --cached` it.
5. **Merge `.claude/settings.local.json`** in each chosen checkout (`{}` if absent). Never replace: keep other keys, append to arrays without duplicates, 2-space indentation.
```json
{
"permissions": {
"blockReadsOutsideWorkingDirectories": true,
"additionalDirectories": ["/tmp/claude-<uid>", "<extra roots, as given, ~ allowed>"],
"deny": [
"Read(.env)", "Read(.env.*)", "Read(*.env)",
"Read(!.env*.example)", "Read(!.env*.sample)", "Read(!.env*.template)", "Read(!.env*.dist)",
"Edit(.env)", "Edit(.env.*)", "Edit(*.env)",
"Edit(!.env*.example)", "Edit(!.env*.sample)", "Edit(!.env*.template)", "Edit(!.env*.dist)",
"Read(~/.claude/.credentials.json)", "Edit(~/.claude/.credentials.json)",
"Read(~/.claude.json)", "Edit(~/.claude.json)"
]
},
"sandbox": { "enabled": true, "allowUnsandboxedCommands": false },
"hooks": {
"PreToolUse": [
{
"matcher": "Read|Write|Edit|MultiEdit|NotebookEdit|Glob|Grep|LSP|Bash|Monitor",
"hooks": [{ "type": "command", "command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/guardrails.mjs\"" }]
}
],
"PostToolUseFailure": [
{
"matcher": "Bash",
"hooks": [{ "type": "command", "command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/guardrails.mjs\"" }]
}
]
}
}
```
Also merge, depending on the answers:
| When | `permissions.ask` | `sandbox.excludedCommands` |
| ---- | ----------------- | -------------------------- |
| Git hosting outside the sandbox | `Bash(gh api *)`, `Bash(gh auth *)`, `Bash(gh secret *)`, `Bash(gh repo delete *)`, `Bash(glab api *)`, `Bash(glab auth *)`, `Bash(glab variable *)`, `Bash(glab repo delete *)` | `gh *`, `glab *`, `git push`, `git push *`, `git pull`, `git pull *`, `git fetch`, `git fetch *` |
| Sandbox on (always, read-only: the sandbox blocks the `claude` binary, breaking step 3) | | `claude --version`, `claude -v` (exact forms only, so no unsandboxed agent session) |
| `open` outside the sandbox | `Bash(open -a *)`, `Bash(open -b *)`, `Bash(open *://*)` | `open`, `open *`, `xdg-open`, `xdg-open *` |
| GUI app testing: yes | | only the launch commands the user gave in step 2, verbatim. No `allowAllUnixSockets`, no `XDG_RUNTIME_DIR` or display socket in `allowRead`/`allowWrite` |
| GUI app testing: yes, and local ports: yes | | `"allowLocalBinding": true` in `sandbox.network` (not an excluded command) |
| When | `permissions.allow` |
| ---- | ------------------- |
| Allow rules picked (step 2) | every rule of each picked candidate (`Bash(pnpm lint)`, `Bash(pnpm lint *)`, ...), unchanged |
And with the sandbox on:
| When | Merge |From Lichens-Innovation/ai-dev-tools, MIT.
More from Lichens-Innovation/ai-dev-tools
- 0.570score
setup-claude-auto-lint-format
Lichens-Innovation
Installs a PostToolUse hook that runs the project's linter and formatter on every file Claude Code or one of its subagents writes or edits, and speaks up only…
SkillAFreshness: AClaude Code +9 - 0.570score
design-palette
Lichens-Innovation
Creates or migrates the canonical CSS theme palette: light/dark inputs, generated scales, semantic tokens shared by web and React Native, hand-authored…
SkillAFreshness: AClaude Code +9 - 0.570score
design-refresh
Lichens-Innovation
The one skill for updating Claude Design from the code: checks whether the synced components are behind their code, rebuilds stale screen mockups, offers…
SkillAFreshness: AClaude Code +9 - 0.570score
claude-light
Lichens-Innovation
Applies a lightweight Claude Code configuration to this project's .claude/settings.local.json: optional auto-compact window, connectors, workflows, bundled…
SkillAFreshness: AClaude Code +9 - 0.570score
react-flow-canvas-geometry
Lichens-Innovation
Compute React Flow (@xyflow) canvas geometry correctly — edge label anchors, bezier control points, handle coordinates, node bounds — so labels and edges land…
SkillAFreshness: AClaude Code +9 - 0.570score
react-coding-standards
Lichens-Innovation
Enforces internal React and TypeScript coding standards using avoid/prefer rules.
SkillAFreshness: AClaude Code +9 - 0.570score
setup-claude-just-usage
Lichens-Innovation
Reads the justfiles of a repository and, for each level that has one (root, apps/frontend, packages/ui, ...), writes a .claude/rules/use-just-commands.md…
SkillAFreshness: AClaude Code +9 - 0.570score
chromatic-init
Lichens-Innovation
Adds Chromatic visual testing to a Storybook project.
SkillAFreshness: AClaude Code +9 - 0.570score
design-loop
Lichens-Innovation
Runs the Claude Design -> React implementation loop: takes an approved component or screen proposal (or the palette card) from a Claude Design project…
SkillAFreshness: AClaude Code +9 - 0.566score
storybook-init
Lichens-Innovation
Installs and configures Storybook in a React or React Native project.
SkillAFreshness: AClaude Code +9 - 0.565score
react-hook-form
Lichens-Innovation
Guide for setting up react-hook-form with Zod validation in React.
SkillAFreshness: AClaude Code +9 - 0.565score
generate-pr-description
Lichens-Innovation
Generates pull request descriptions by comparing current branch with parent branch.
SkillAFreshness: AClaude Code +9
Signals
- Stars
- 0
- Forks
- 0
- Open issues
- 6
- Last commit (this folder)
- Oct 24, 2026 (7 days ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from Lichens-Innovation
- 0.570score
claude-light
Lichens-Innovation
Applies a lightweight Claude Code configuration to this project's .claude/settings.local.json: optional auto-compact window, connectors, workflows, bundled…
SkillAFreshness: AClaude Code +9 - 0.570score
design-loop
Lichens-Innovation
Runs the Claude Design -> React implementation loop: takes an approved component or screen proposal (or the palette card) from a Claude Design project…
SkillAFreshness: AClaude Code +9 - 0.570score
chromatic-init
Lichens-Innovation
Adds Chromatic visual testing to a Storybook project.
SkillAFreshness: AClaude Code +9 - 0.570score
setup-claude-auto-lint-format
Lichens-Innovation
Installs a PostToolUse hook that runs the project's linter and formatter on every file Claude Code or one of its subagents writes or edits, and speaks up only…
SkillAFreshness: AClaude Code +9 - 0.570score
setup-claude-just-usage
Lichens-Innovation
Reads the justfiles of a repository and, for each level that has one (root, apps/frontend, packages/ui, ...), writes a .claude/rules/use-just-commands.md…
SkillAFreshness: AClaude Code +9 - 0.570score
design-palette
Lichens-Innovation
Creates or migrates the canonical CSS theme palette: light/dark inputs, generated scales, semantic tokens shared by web and React Native, hand-authored…
SkillAFreshness: AClaude Code +9
Done for you
Rather not set it up yourself?
Chalk Labs scopes, builds and runs agents for your team: the task audit, the eval harness, the integrations and the weekly ops report. Fixed scope, priced before we start.
See how we build AI agents →Read the case studies
Chalk Labs is a two-founder AI and growth studio. We build AI agents, CRMs and MVPs for Web3 and AI companies, and have shipped 50+ product and token launches.
- launches shipped
- 50+
- launches shipped
- media placements
- 500+
- media placements
- founders on every account
- 2
- founders on every account
Press we've placed: Forbes · CoinDesk · Decrypt · Cointelegraph · The Block
Rahil Jain, Co-founder, Chalk Labs. Ex-Goldman Sachs engineer. You talk to the person who builds it.
Get setup-claude-guardrails running in your business
Tell us what you want to automate. A founder replies within one working day with a plan, not a pitch deck.
Cite this page
setup-claude-guardrails skill. Agent Mart. https://agentmart.dev/skills/lichens-innovation-setup-claude-guardrails (last updated 2026-10-24)