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.