DEV Community

Claude code
Claude code

Posted on

The complete guide to claude code configuration settings

What Is Claude Code Configuration Settings?

Claude Code configuration settings is the system of JSON-based configuration files, environment variables, permission flags, and hook definitions that control how the Claude Code CLI agent operates within a development environment — including which tools it can invoke, which shell commands it may execute, what environment variables it can read, and how it responds to pre- and post-action events. Configuration lives primarily in settings.json files at three scopes: global (~/.claude/settings.json), project-level (.claude/settings.json in the repo root), and enterprise-managed policy overlays.

This is not a preferences file. It is an access control surface. Every default you leave unchecked is an implicit grant of permission to an autonomous agent that writes and executes code on your behalf.

The Three Scopes of settings.json

Global settings apply to every Claude Code session for a given user. Project settings apply only when Claude Code is launched from within that directory tree and can override or narrow global defaults. Enterprise policy files, when deployed via MDM or a managed config path, take highest precedence and cannot be overridden by project or user config. Understanding which scope is active during a given session is the first thing to verify when auditing an environment.

A minimal project-level settings file looks like this:

{
  "permissions": {
    "allow": ["Bash(git:*)", "Read(**/*.ts)"],
    "deny": ["Bash(curl:*)", "Bash(wget:*)"]
  }
}
Enter fullscreen mode Exit fullscreen mode

That deny list is doing real security work. Without it, Claude Code can make outbound HTTP requests from your shell by default in versions prior to 1.x policy hardening updates documented in Anthropic's Claude Code security reference.

Why Claude Code Configuration Settings Matters in 2026

Autonomous Agents Have a Larger Attack Surface Than Chatbots

Claude Code is not a chatbot with a text box. It is an agent loop that reads files, writes files, executes shell commands, calls external APIs via MCP servers, and spawns subprocesses. That loop runs with the same OS-level permissions as the developer who launched it. If you are running it as a user with access to AWS credentials in ~/.aws/credentials, or with SSH keys loaded in an agent, Claude Code can read and potentially exfiltrate those secrets unless you explicitly restrict what it can access.

Anthropic's published model card for Claude 3.x and Claude 4.x both note that large language models remain susceptible to prompt injection attacks — a class of vulnerability where malicious content in a file or web response hijacks the model's instruction context. When Claude Code reads a repository that contains a crafted CLAUDE.md or a poisoned dependency's README, a prompt injection payload in that file can redirect the agent's actions. Configuration settings are one of the few controls that constrain what the agent can do even after injection occurs.

Default Permissions Are Broader Than Most Teams Realize

Out of the box, Claude Code's permission model is interactive: it will ask before executing unfamiliar commands. But "ask" is not the same as "deny." In automated CI pipelines, non-interactive sessions, or when users habitually approve prompts, the interactive gate provides minimal protection. The --dangerously-skip-permissions flag, which appears in Anthropic's own documentation as a flag for containerized environments, completely bypasses the interactive check — and its usage has been observed in developer dotfiles published to GitHub without the surrounding container context that would make it safe.

At CLaude Coe, we work specifically with teams deploying Claude Code at scale, and the pattern we see most often is not malicious use — it's accidental over-permissioning driven by developers who want the tool to "just work" and approve every prompt without reading it.

Hooks Execute Arbitrary Shell Commands

The hooks system, introduced to let teams run linters, log tool calls, or enforce pre-commit checks, is a shell execution surface embedded in your configuration file. A hook defined in settings.json runs as a shell command on the host system when triggered by agent events. If your project settings file is committed to a shared repository without review, a malicious contributor can add a hook that exfiltrates data or establishes persistence. This is not hypothetical: the mechanism is identical to the postinstall supply chain attack pattern documented in dozens of npm CVEs.

How to Approach Claude Code Configuration Settings

Tool Permissions

The permissions.allow and permissions.deny arrays accept glob-style tool patterns. Bash(git:*) allows all git subcommands. Bash(*) allows everything. Start from deny-all and add back only what your workflow requires. For a TypeScript project doing code review, you likely need Read, Grep, Glob, and Bash(git:*). You almost certainly do not need Bash(curl:*), Bash(ssh:*), or unrestricted Write access outside your project directory.

The Claude Code Security documentation covers the full permission grammar, including how to write tool-specific patterns versus broad shell patterns and which tools are implicitly granted versus explicitly required.

Hook Definitions

Every hook entry in settings.json should be treated as a shell script. Review hook definitions in pull requests with the same scrutiny you would apply to a GitHub Actions workflow. If you use a shared project settings file, consider moving hooks to a separate file that is in .gitignore or managed through a controlled deployment process rather than committed directly.

Environment Variables

Claude Code inherits the full environment of the shell that launched it. That means every API key, cloud credential, and database URL in your shell environment is potentially readable by the agent and by any MCP server it connects to. Scope your launch environment: use a wrapper script that unsets credentials not needed for the current task, or launch Claude Code from a dedicated shell profile with minimal exported variables.

Model Controls and API Configuration

The model key in settings controls which Claude model is used. In enterprise deployments, locking this to a specific model version prevents prompt behavior changes from a model upgrade from silently altering how the agent interprets its own permissions or how it handles sensitive content in files. Version-pin your model in production automation the same way you version-pin dependencies.

Best Claude Code Configuration Settings Tools and Solutions

Anthropic's Built-In Policy System

The native three-tier configuration hierarchy (global, project, enterprise) is sufficient for most teams if used correctly. The key tool Anthropic provides is the enterprise policy overlay, which allows a platform team to set a non-overridable baseline — for example, a permanent deny on Bash(rm:*) or a restriction to specific MCP servers. This works without requiring every developer to maintain their own settings file correctly.

The Claude Code Security product overview describes how to layer organizational policy on top of the native configuration system, including audit logging for configuration changes and alerting when project settings attempt to override enterprise policy.

Git Pre-Commit Hooks for Settings Validation

Commit a JSON Schema validation step to your pre-commit hooks that rejects .claude/settings.json changes that introduce wildcards in allow lists or add hooks without a required comment field. This is a 20-line shell script, not a product you need to buy. It will catch the most common class of accidental over-permissioning before it reaches your main branch.

MCP Server Allowlisting

Each MCP server connected to Claude Code gets its own tool namespace and can make network requests, read files, and execute operations within its defined scope. The mcpServers key in settings.json defines which servers Claude Code can connect to. Treat this list like a firewall allowlist: every entry is a potential lateral movement path if the server is compromised or if a prompt injection redirects the agent to use it unexpectedly.

Claude Code Configuration Settings Best Practices

Start Restrictive, Expand Deliberately

The worst time to audit your Claude Code permissions is after an incident. Start every project configuration with an explicit deny list for network tools, file operations outside the project root, and any Bash command not required by your specific workflow. Document why each allow entry exists in a comment next to it. When a developer asks to expand permissions, that request should go through the same review as any other infrastructure change.

Separate CI and Developer Configurations

Your CI pipeline's Claude Code session does not need the same permissions as a developer's interactive session. In CI, you know exactly what commands will be run — scope the settings file to exactly those commands. Use a CI-specific settings file injected at runtime, not committed to the repository, so that the CI token's permissions cannot be inferred from the source code.

Audit Hooks Independently of the Codebase

Hooks run as shell commands triggered by agent events. A hook that logs tool calls to a file looks safe. The same hook, if the log path is world-writable or the log is shipped to an external endpoint, is a data exfiltration path. Review every hook for what it reads, what it writes, and where it sends data. If a hook makes a network request, treat it with the same scrutiny as any other outbound call.

Use the Permissions Audit Trail

Claude Code's verbose logging mode (--verbose or the equivalent settings key) outputs every tool call and permission decision to stderr. In production deployments, pipe this output to your SIEM or at minimum to a log file that is not in the project directory. If an incident occurs, that log is your reconstruction path. Without it, you have no visibility into what the agent actually did during a session.

For teams that need centralized visibility across multiple developers and projects without manual log aggregation, the Claude Code Security pricing page outlines managed audit options that feed into existing security tooling.

Frequently Asked Questions

Where does settings.json live for Claude Code?

Claude Code reads configuration from three locations in order of precedence: ~/.claude/settings.json for user-global settings, .claude/settings.json in the project root for project-specific settings, and an enterprise policy file at a path configurable by your organization's deployment. Project settings override global settings; enterprise policy overrides both. If you are unsure which file is active, run Claude Code with --verbose — it logs the resolved configuration path at startup.

Can Claude Code access my AWS credentials by default?

Yes. Claude Code inherits the full shell environment of the process that launched it, including environment variables like AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and any credentials in ~/.aws/credentials if the agent is allowed to read files in that path. There is no automatic credential scrubbing. If you launch Claude Code from a shell with AWS credentials loaded, the agent can read and use them unless you explicitly restrict file access to the project directory and block environment variable access to sensitive keys.

How do I restrict Claude Code to a single directory?

Add a deny rule for Read and Write operations outside your project root. In practice this looks like setting "deny": ["Read(../)", "Write(../)", "Bash(cd:*)"] in your project's .claude/settings.json. Note that shell commands can still traverse directories unless you also restrict the Bash tool to specific subcommands. A belt-and-suspenders approach runs Claude Code inside a container or chroot that enforces the directory boundary at the OS level, regardless of what the settings file says.

What is the difference between the allow list and the deny list?

Allow and deny lists both use glob-style tool patterns. Deny takes precedence over allow — if a tool matches both lists, it is denied. This means you can use a broad allow like Bash(*) for legacy compatibility while layering specific denies for dangerous subcommands, or use a minimal allow list with no deny list for maximum restrictiveness. For new deployments, the minimal allow list approach is safer because it fails closed: unlisted tools are denied by default.

How do I get started with Claude Code configuration settings safely?

Generate a baseline settings file before your first session, not after. At minimum: deny outbound network tools (curl, wget, ssh), restrict file operations to your project directory, and define a hook that logs all tool calls to a local audit file. Anthropic's official settings reference documents every supported key and its default value — read through the defaults section before you start, because "default allowed" items will surprise you.

What are common Claude Code configuration settings mistakes to avoid?

The most common mistake is committing .claude/settings.json with "allow": ["Bash(*)", "Read(*)", "Write(*)", "WebFetch(*)"] because a developer added those during initial setup to stop the approval prompts and forgot to narrow them down. Second most common: enabling --dangerously-skip-permissions in a non-containerized environment and then committing that invocation to a Makefile or CI script. Third: defining hooks that make external HTTP calls without reviewing what data is in the request body. Fourth: assuming that because Claude Code "asked permission" once and you approved it, the permission is scoped — interactive approvals in a session are not logged and do not appear in your settings file for later audit. Fix all four of these before you treat your Claude Code deployment as production-ready.

Top comments (1)

Collapse
 
claude_code_security profile image
Claude code

Great breakdown. The point about scoping tool permissions by directory really resonates — least-privilege is underrated for agentic setups.