[{"content":"Many companies are evaluating Anthropic\u0026rsquo;s Claude Code as their AI Companion. Installing Claude Code CLI is straightforward. But as easy as it is, it also provides by default unrestricted access to the entire filesystem. This is a first approach to implementing some secure by default configurations and guardrails to limit what actions Claude can perform at the macOS level. Despite the fact I\u0026rsquo;m including useful considerations for companies deploying Claude Code CLI for the first time, this guide is intended for personal usage.\nNote on personal usage. I strongly recommend to run claude code CLI using devcontainers to reduce attack surface\n1. Understanding configuration scope There are primarily 4 layers based on 3 different files. The files themselves accept the same settings, and have the same structure. What differentiates them is precedence (and location). Layer Configuration File Precedence Enforced Purpose 1 /Library/Application Support/ClaudeCode/managed-settings.json Highest Yes Organization-wide enforced policies 2 ~/.claude/settings.json Below Layer 1 No Personal defaults across all projects 3 .claude/settings.json Below Layers 1–2 No Project-specific configuration 4 .claude/settings.local.json Lowest No User-specific settings for a single project 2. Base Security Guardrails: Sandbox 2.1 Anthropic Sandbox The sandbox restricts what Claude can read, write, and reach on the network, preventing it from accessing sensitive files or exfiltrating data even if manipulated. It is enforced at the OS level, in macOS using SeatBelt, below Claude\u0026rsquo;s own judgment layer.\nWhen enabled it can restrict: Command execution Directory reading/listing Network access Access to specific Marketplaces only Access to specific MCPs only It is recommended to enable the sandbox in the above mentioned [[#1. Understanding configuration scope]], the managed-settings.json file and deploy this file globally using MDM tools.\nAn example version of this file could look like\n{ \u0026#34;permissions\u0026#34;: { \u0026#34;defaultMode\u0026#34;: \u0026#34;default\u0026#34;, \u0026#34;deny\u0026#34;: [ \u0026#34;Bash(osascript *)\u0026#34;, \u0026#34;Bash(osacompile *)\u0026#34;, \u0026#34;Bash(security *)\u0026#34;, \u0026#34;Bash(screencapture *)\u0026#34;, \u0026#34;Bash(tclsh *)\u0026#34;, \u0026#34;Bash(launchctl *)\u0026#34;, ], \u0026#34;disableBypassPermissionsMode\u0026#34;: \u0026#34;disable\u0026#34;, \u0026#34;allowManagedPermissionRulesOnly\u0026#34;: true }, \u0026#34;sandbox\u0026#34;: { \u0026#34;enabled\u0026#34;: true, \u0026#34;allowUnsandboxedCommands\u0026#34;: false, \u0026#34;filesystem\u0026#34;: { \u0026#34;denyRead\u0026#34;: [ \u0026#34;~/.ssh\u0026#34;, \u0026#34;~/.gnupg\u0026#34;, \u0026#34;**/.env\u0026#34;, \u0026#34;**/.env.*\u0026#34;, \u0026#34;~/.bashrc\u0026#34;, ], \u0026#34;allowWrite\u0026#34;: [ ], \u0026#34;denyWrite\u0026#34;: [ \u0026#34;/etc/cron*\u0026#34;, \u0026#34;/etc/periodic/**\u0026#34;, \u0026#34;/var/spool/cron/**\u0026#34;, \u0026#34;~/Library/LaunchAgents/**\u0026#34;, \u0026#34;~/Library/LaunchDaemons/**\u0026#34;, \u0026#34;/Library/LaunchAgents/**\u0026#34;, \u0026#34;/Library/LaunchDaemons/**\u0026#34;, \u0026#34;/System/Library/LaunchAgents/**\u0026#34;, \u0026#34;/System/Library/LaunchDaemons/**\u0026#34;, ] }, \u0026#34;network\u0026#34;: { \u0026#34;allowedDomains\u0026#34;: [ \u0026#34;localhost\u0026#34;, \u0026#34;127.0.0.1\u0026#34;, \u0026#34;::1\u0026#34;, \u0026#34;*.your_safe_domain.com\u0026#34;, \u0026#34;*.anthropic.com\u0026#34;, ], \u0026#34;allowManagedDomainsOnly\u0026#34;: true, } }, \u0026#34;allowManagedMcpServersOnly\u0026#34;: false, \u0026#34;extraKnownMarketplaces\u0026#34;: { \u0026#34;{your_trusted_mkt}\u0026#34;: { \u0026#34;source\u0026#34;: { \u0026#34;source\u0026#34;: \u0026#34;url\u0026#34;, \u0026#34;url\u0026#34;: \u0026#34;https://{your_trusted_mkt}.com/claude-code/marketplace.json\u0026#34; } } }, \u0026#34;strictKnownMarketplaces\u0026#34;: [ { \u0026#34;source\u0026#34;: \u0026#34;github\u0026#34;, \u0026#34;repo\u0026#34;: \u0026#34;anthropics/claude-plugins-official\u0026#34; }, { \u0026#34;source\u0026#34;: \u0026#34;url\u0026#34;, \u0026#34;url\u0026#34;: \u0026#34;https://{your_trusted_mkt}.com/claude-code/marketplace.json\u0026#34; } ], \u0026#34;disableAllHooks\u0026#34;: false } Claude use cases vary from individual and organizations, so you will need to find the right set of settings that most accurately captures your use case\nOne considerations on the file above is that It is set on Blocklist mode, meaning that what it is not explicitly deny it is allowed. The other mode, allowlist, would be safer but it will require a significant operational work for a company environment (recommended for personal usage)\n2.2 Permission Rules I introduced here commands which usage could be risky. Inspiration came from Living off the Land binaries for macOS\nRationale behind some of the commands I choose to introduce in the file (you can do this process as detail as you needed).\nCommand Risk osascript / osacompile Arbitrary code execution via AppleScript security Keychain access and credential extraction screencapture Screen capture and potential data exfiltration swift / tclsh Alternative code execution paths that bypass python/bash restrictions nscurl Alternative HTTP client that can bypass curl deny rules launchctl Persistence through Launch Agents and Launch Daemons dscl / dscacheutil Local user and directory service enumeration sysadminctl / systemsetup Account management and system configuration changes streamzip Archive creation that may facilitate file exfiltration denyWrite. Basically restricting write operations to common directories used for establishing persistence 2.23 Network control layers in Claude First, lets understand how Claude CLI performs network calls. There are primarily two ways:\nWebFetch. It is the native Claude Code CLI tool for retrieving web pages and docs Subprocess commands. Any subprocess command, like curl/wget, run via bash WebSearch (not covered here) The network section on the managed-settings file has impact only on the subprocess commands egress request.\nFor instance, let\u0026rsquo;s say that this is my network section\n\u0026#34;network\u0026#34;: { \u0026#34;allowedDomains\u0026#34;: [ \u0026#34;github.com\u0026#34;, \u0026#34;anthropic.com\u0026#34; ] } If I run within Claude Code CLI:\n!curl bitbucket.com it will be blocked as curl is a subprocess of bash.\nNow if I ask Claude to run it\nAccess gitlab.com it will work, as this request is handled by the webFetch Tool. For blocking webfetch add it in the permissions section\n{ \u0026#34;permissions\u0026#34;: { \u0026#34;deny\u0026#34;: [ \u0026#34;WebFetch\u0026#34;, ] } } or, with more granularity, allow only domain1 and domain2 as follows\n{ \u0026#34;permissions\u0026#34;: { \u0026#34;allow\u0026#34;: [ \u0026#34;WebFetch(domain:domain1.com)\u0026#34;, \u0026#34;WebFetch(domain:domain2.com)\u0026#34; ], \u0026#34;deny\u0026#34;: [ \u0026#34;WebFetch\u0026#34; ] } } As a final note, for non-personal environments, it is recommended to pair this strategy with independent Egress filtering controls (at the host layer)\n3 Additional Recommendation for Enterprise deployments 3.1 Verify Enterprise SSO Accounts Organizations deploying Claude Code through enterprise SSO might want to ensure that there are no Claude Code instances that are not authenticated with non-enterprise accounts,. The risks are:\nPotential data exfiltration Endpoint compromise (unrestricted Claude code CLI) Logging and monitoring failures (no visibility of what it is being done) One possible check you could run is to identify who is running a non-company Claude code account:\ncat ~/.claude.json | jq \u0026#39;.oauthAccount\u0026#39; { \u0026#34;accountUuid\u0026#34;: , \u0026#34;emailAddress\u0026#34;: , \u0026#34;organizationUuid\u0026#34;: , \u0026#34;hasExtraUsageEnabled\u0026#34;: , \u0026#34;billingType\u0026#34;: , \u0026#34;subscriptionCreatedAt\u0026#34;: , \u0026#34;displayName\u0026#34;: , \u0026#34;organizationRole\u0026#34;: , \u0026#34;workspaceRole\u0026#34;: null, \u0026#34;organizationName\u0026#34;: } 3.2 Logging, and Monitoring Claude Code can be configured to use an OpenTelemetry (OTEL) to ship both logs and metrics\n{ \u0026#34;env\u0026#34;: { \u0026#34;CLAUDE_CODE_ENABLE_TELEMETRY\u0026#34;: \u0026#34;1\u0026#34;, \u0026#34;OTEL_METRICS_EXPORTER\u0026#34;: \u0026#34;otlp\u0026#34;, \u0026#34;OTEL_LOGS_EXPORTER\u0026#34;: \u0026#34;otlp\u0026#34;, \u0026#34;OTEL_EXPORTER_OTLP_PROTOCOL\u0026#34;: \u0026#34;grpc\u0026#34;, \u0026#34;OTEL_EXPORTER_OTLP_ENDPOINT\u0026#34;: \u0026#34;http://collector.example.com:4317\u0026#34;, \u0026#34;OTEL_EXPORTER_OTLP_HEADERS\u0026#34;: \u0026#34;Authorization=Bearer example-token\u0026#34; } } 3.3 Deployment phases and considerations Consider\nDeploying to a test group first Gathering feedback, identify security gaps, issues and fine-tune the managed-settings file Version-controlling managed-settings.json in git. Validating configuration changes through CI (linting, JSON Schema validation, etc) Using a CI/CD pipeline to distribute updated managed-settings.json file to managed endpoints. ","permalink":"https://nicocarusso.pages.dev/articles/claude-implementation/","summary":"\u003cp\u003eMany companies are evaluating Anthropic\u0026rsquo;s Claude Code as their AI Companion. Installing Claude Code CLI is straightforward. But as easy as it is, it also provides by default unrestricted access to the entire filesystem. This is a first approach to implementing some secure by default configurations and guardrails to limit what actions Claude can perform at the macOS level.\nDespite the fact I\u0026rsquo;m including useful considerations for companies deploying Claude Code CLI for the first time, this guide is intended for personal usage.\u003c/p\u003e","title":"Initial setup for a Secure Claude Code implementation"},{"content":"$ whoami Hi, Security is definitely my thing.\nMy work sits at the intersection of Detection Engineering, Cloud Security, Security Architecture and AI Security. I enjoy understanding how technologies work under the hood, challenging my own assumptions, and turning complex security problems into practical engineering solutions.\nThis blog is where I share technical deep dives, lessons learned, and original research, hopefully useful (and interesting) to anyone building or securing modern software.\nOutside of work, you\u0026rsquo;ll usually find me running, reading, or learning something new. I should also point out that I like writing, perhaps a natural outcome from reading a lot, which is another good reason to blog :)\n","permalink":"https://nicocarusso.pages.dev/whoami/","summary":"\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e$ whoami\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eHi, Security is definitely my thing.\u003c/p\u003e\n\u003cp\u003eMy work sits at the intersection of Detection Engineering, Cloud Security, Security Architecture and AI Security. I enjoy understanding how technologies work under the hood, challenging my own assumptions, and turning complex security problems into practical engineering solutions.\u003c/p\u003e\n\u003cp\u003eThis blog is where I share technical deep dives, lessons learned, and original research, hopefully useful (and interesting) to anyone building or securing modern software.\u003c/p\u003e","title":"whoami"}]