Skip to content

.claudeignore and Ignore Rules

Control what Claude can and cannot see. The difference between .claudeignore and .gitignore, and what belongs in each.

You ask Claude Code to help refactor a module. It helpfully reads your .env file while exploring the codebase. Your database password is now sitting in the context window. Great.

Preventable. You've got control over what Claude Code can and can't touch. Most people just never bother setting it up.

Permission Deny Rules

Quick clarification: Claude Code does not have a .claudeignore file. If you've been searching for one, stop. File access is controlled through permission deny rules in your settings.

Two flavors:

  • Read deny rules block Claude Code from reading specific files
  • Edit deny rules block Claude Code from modifying specific files

They go in your CLAUDE.md or settings:

Read(.env)
Read(~/.ssh/**)
Read(/etc/shadow)
Edit(/migrations/**)
Edit(*.lock)

Standard gitignore-style glob patterns. Nothing new to learn.

Four Path Types

The patterns support four path prefixes, and they behave differently enough that getting them wrong causes problems:

//etc/shadow     → absolute path (note the double slash)
~/path           → relative to your home directory
/path            → relative to the project root
path             → relative to the current working directory

Single * matches within one directory level. Double ** matches recursively.

Read(~/.ssh/**) blocks everything inside .ssh, no matter how deep. Read(~/.ssh/*) only blocks files directly in .ssh, not subdirectories. That distinction will bite you.

Sandbox Filesystem Rules

There's a second layer. Sandbox filesystem rules control what happens when Claude Code runs shell commands (as opposed to using its built-in Read/Edit tools):

  • sandbox.filesystem.denyWrite blocks Bash commands from writing to specified paths
  • sandbox.filesystem.denyRead blocks Bash commands from reading specified paths

Permission deny rules guard Claude Code's own tools. Sandbox rules guard the shell. You need both, because Claude Code can use cat just as easily as its built-in Read tool.

Setting Up Your Rules

By default, Claude Code can only write within its starting directory and subfolders. Can't modify parent directories without explicit permission. It can read outside the working directory, which is useful for checking system libraries or referencing other projects.

Decent defaults, but tighten them.

Try it

Open your project CLAUDE.md and add rules for common sensitive paths:

# File Access Rules
 
Read(.env)
Read(.env.*)
Read(**/credentials.json)
Read(~/.ssh/**)
Edit(*.lock)
Edit(/migrations/**)

Test it. Ask Claude Code to read your .env file. Refused. Ask it to modify package-lock.json. Refused. Exactly what you want.

The .gitignore Connection

People assume .gitignore protects them here. It doesn't.

.gitignore tells Git which files to skip tracking. It has zero effect on what Claude Code can see. Your node_modules is in .gitignore, sure, but Claude Code can still happily read all 47,000 files in it, flooding your context window with noise.

The VS Code extension has a respectGitIgnore setting that excludes those patterns from file searches. Nice convenience, but it doesn't replace deny rules for security-sensitive files. Version control and access control are different concerns.

Best Practices

Always Block Secrets

Any file with credentials, API keys, tokens, or passwords gets a Read deny rule. No exceptions.

Read(.env)
Read(.env.local)
Read(.env.production)
Read(**/secrets.*)
Read(**/*credentials*)
Read(~/.aws/**)
Read(~/.ssh/**)

Block Large Binaries

Claude Code is a text tool. A 50MB image or compiled binary in the context window burns tokens for nothing.

Read(**/*.zip)
Read(**/*.tar.gz)
Read(**/*.wasm)
Read(**/dist/**)

Protect Generated Files

Lock files, migrations, build output. Read-only at most. You really don't want Claude Code rewriting your yarn.lock or editing a migration that already ran in production.

Edit(*.lock)
Edit(*-lock.json)
Edit(/migrations/**)
Edit(/dist/**)
Edit(/.next/**)

Skip Noise Directories

Vendor and dependency folders add nothing but token cost.

Read(/node_modules/**)
Read(/vendor/**)
Read(/.next/**)
Read(/__pycache__/**)

Layer Your Rules

Rules go in multiple CLAUDE.md files. Project root for project-wide rules. ~/.claude/CLAUDE.md for global rules like blocking ~/.ssh.

The Short Version

No .claudeignore file exists. Read and Edit deny rules in CLAUDE.md and settings handle access control. Four path types: absolute (//), home-relative (~/), project-root-relative (/), cwd-relative (no prefix), with ** for recursive and * for single level.

Block secrets first. Environment files, SSH keys, AWS credentials, API tokens. These should never enter the context window. .gitignore doesn't protect you here. And remember the sandbox filesystem rules as the second layer, specifically for Bash commands.

Mastering Claude Code

Lesson 33 of 70