Claude Code is a powerful local agent. By default it can read most files on your machine. Here is how to lock it down and extend it for your workflow.
Block access to credential files
Put this in your global Claude settings at ~/.claude/settings.json. Claude will refuse to read any of these paths — even if you accidentally ask it to.
{
"permissions": {
"deny": [
"Read(~/.aws/**)",
"Read(~/.config/gcloud/**)",
"Read(~/.azure/**)",
"Read(~/.ssh/**)",
"Read(~/.gnupg/**)",
"Read(~/.git-credentials)",
"Read(~/.config/gh/hosts.yml)",
"Read(~/.pip/pip.conf)",
"Read(~/.gradle/gradle.properties)",
"Read(~/.docker/config.json)",
"Read(~/.kube/config)",
"Read(~/.kube/**)",
"Read(~/.helm/**)",
"Read(~/.npmrc)",
]
}
}
When blocked, Claude tells you clearly what happened and why, and suggests alternatives that don’t require reading the sensitive file directly.
CLAUDE.md - context files Claude reads automatically
Claude picks up CLAUDE.md files and uses them as persistent context. There are three levels:
| File | Scope |
|---|---|
~/.claude/CLAUDE.md |
All projects on your machine |
CLAUDE.md |
This project, committed and shared with the team |
CLAUDE.local.md |
This project, not committed - your personal notes |
Run /init in Claude Code to generate a project CLAUDE.md from your codebase automatically. Put things in there that Claude should always know: project conventions, where things live, what to avoid.
Hooks - run code before or after Claude actions
Hooks let you intercept Claude’s tool calls. They are defined in settings.json and can block actions, log them, or modify behavior.
There are two levels, same as the settings file:
| Defined in | Scope |
|---|---|
~/.claude/settings.json |
All projects (global) |
.claude/settings.json |
This project only |
.claude/settings.local.json |
This project, not committed |
Write hooks by hand or use the /hooks command inside Claude.
Example: block Claude from reading .env files
.claude/hooks/read_hook.js:
async function main() {
const chunks = [];
for await (const chunk of process.stdin) {
chunks.push(chunk);
}
const toolArgs = JSON.parse(Buffer.concat(chunks).toString());
const readPath =
toolArgs.tool_input?.file_path || toolArgs.tool_input?.path || "";
if (readPath.includes(".env")) {
console.error("You cannot read the .env file");
process.exit(2);
}
}
main();
Exit code 2 blocks the action and shows the error to Claude. Exit code 0 allows it through.
Wire it up in .claude/settings.json:
{
"hooks": {
"Read": [
{
"command": "node .claude/hooks/read_hook.js"
}
]
}
}
Custom slash commands
You can add your own /commands that Claude runs on demand. Create markdown files under .claude/commands/:
.claude/commands/audit.md
Content of audit.md:
run date
Now type /audit in Claude and it runs date. You can make commands as complex as you want - multi-step instructions, checklists, or reminders of your team’s audit procedure.
To apply settings changes without restarting, use the /update-config command inside Claude Code.