Is Claude Code Safe? Permissions and a Read/Write Test

Claude Code can be suitable for marketing work when you limit the files, commands and connected accounts it can use, then test those limits before adding customer data. Start with an explicit Manual session and synthetic inputs. Approve a specific change only after reviewing its target and contents. A folder choice, a reassuring prompt or a read-only MCP server does not control every other route to your data.

Jafrin Akter AloLast updated 12 min read
On this page
A white drafting board holds a blank sheet beneath a lime stop bar and pink clamp beside Claude Code Access Checks.

What can Claude Code access on your computer?

Claude Code can use local file tools, execute commands and call connected services according to the tools, permissions and credentials available to the session. These are separate access paths. Your first approval decision should name the path a task needs.

For a campaign-export review, that might mean a copied CSV and a draft recommendation. A CRM cleanup also involves remote records, an authenticated account and a decision about whether changes are allowed. Write those two scopes separately before connecting anything.

In Manual mode, the normal working-directory boundary prompts before file access outside the workspace. An approved shell command can still write wherever your operating-system user can. Starting in a tidy project folder therefore does not create an operating-system jail. Interactive workspace trust also differs from unattended -p sessions, which omit the workspace and project-MCP trust dialogs. Claude Code security

Review the configuration you are about to trust: project instructions, installed extensions, hooks, MCP servers and additional directories. Treat instructions found inside exports, tickets and retrieved pages as untrusted content. If a campaign description says to upload credentials, that text has no authority to expand the assignment.

The Claude Code marketing guide helps choose a useful first task. For shared laptops, multiple account connections or approval policies that must apply across a team, scope those requirements in the Claude Code and MCP implementation before issuing production access.

Which permission mode should a marketing team start with?

Start a supervised pilot in Manual mode explicitly, then inspect the effective settings. Do not assume a fresh installation starts read-only: Auto is the built-in starting mode for interactive terminal and VS Code sessions from version 2.1.283; older versions, other surfaces and configured overrides can differ. Permission modes

Which permission mode should a marketing team start with?
ModeWhat changesPilot decision
Manual, configured as defaultUses the normal permission promptsStart here and add explicit write prompts
PlanSupports planning and reads; available automatic command review can affect shell activityUseful for exploration; inspect actual tools and rules
Accept EditsAutomatically accepts file edits and some filesystem commandsUse only after the editable scope is intentional
AutoA classifier handles decisions that would otherwise need manual reviewDo not count classifier approval as a person signing off
Bypass PermissionsSkips permission checksExclude from this supervised pilot

These modes describe different approval behavior, not equivalent levels of isolation. Claude Code mode behavior

Use claude --permission-mode default when you need Manual mode. Before the first task, open /permissions and read both the rule and its source. A copied settings file is not enough evidence that it governs the running session.

How do you require approval before a write?

Require an explicit prompt on the relevant write tool, and remove alternative execution paths the task does not need. In Claude Code, deny wins over ask, which wins over allow; an ask rule still prompts when an allow rule also matches. For supervised built-in file changes, use ask: ["Edit", "Write"]. Use Edit(path) for scoped file-write restrictions: Write(path) rules never match. Permission rules

For each requested change, review four things together: the destination, the exact new value or contents, the number of affected objects and the expected result. Choose a one-time approval for the pilot. If Claude proposes a different target or payload, review that new operation separately.

File prompts do not cover every way to change data. A shell, script runner or MCP tool can provide another route. The exercise below removes shell execution and all MCP tools, then introduces only the two file-write tools needed for a small draft. A live CRM workflow needs its own tool rules and account restrictions.

For a repeated marketing operation, define the allowed action in the agent approval workflow: for example, a draft update to one named test record, with publishing excluded. A general instruction to “ask before anything risky” is too ambiguous to serve as the only gate.

What does the Claude Code sandbox protect?

The Bash sandbox restricts supported shell processes and their children; it does not wrap the whole Claude Code session. It is off by default and available on macOS, Linux and WSL2, while native Windows execution is unsandboxed. Sandbox scope and platform support

What does the Claude Code sandbox protect?
Access pathCovered by the Bash sandbox?Control to review
Supported shell commands and child processesYes, when enabledFilesystem, network and credential restrictions
Built-in file and web toolsNoTool permissions and permitted working directories
MCP servers and hooksNoServer deployment, account permissions and trusted configuration

Sandbox defaults allow broad reads and inherited environment variables. Configure credential file and environment restrictions explicitly. Set autoAllowBashIfSandboxed: false if sandboxed commands should follow normal permission prompts, allowUnsandboxedCommands: false to disallow unsandboxed retries, and failIfUnavailable: true to stop startup when sandboxing is unavailable. An allowed network destination can still receive sensitive content; a domain allowlist is not a content filter. Sandbox configuration and limitations

Command hooks deserve separate review because they run with your user privileges outside that sandbox. A local disableAllHooks setting cannot disable hooks imposed through managed policy. Hook security considerations

If the task only needs file review, removing the shell is easier to verify than approving a general-purpose interpreter and trying to describe every forbidden command. Revisit the decision when a real task needs a script. Read/Edit path rules do not reliably constrain indirect file access through arbitrary programs. File-rule coverage

What changes when you connect HubSpot, Google Ads or GA4?

An MCP connection adds another tool surface and an authenticated account. Judge the specific server and its current tool list, then check the connected user's permissions. The product name alone does not tell you whether the connection can write.

What changes when you connect HubSpot, Google Ads or GA4?
Official serverCurrent capability boundaryFirst acceptance check
HubSpot remote MCPSupports CRM writes and supported content creation or publication, subject to permissions and scopesConfirm which tools can change the chosen test record or publish content
Google Ads MCPExposes read-only operations; cannot change bids, pause campaigns or create assetsConfirm the installed server is the official read-only implementation
Google Analytics MCPReads analytics information and reports; cannot modify Analytics configurationConfirm access reaches only the intended property

These are vendor-defined boundaries for the named servers. HubSpot remote MCP, Google Ads MCP, Google Analytics MCP

A read-only server does not prove that a separate script using credentials for the same platform is read-only. Review the credential and every enabled execution path. For HubSpot, use the HubSpot MCP setup guide to check the actual connection rather than assuming its permissions resemble the Ads server.

Claude Code's --tools flag restricts built-in tools, not MCP tools. Deny MCP tools separately when they are outside the task. CLI tool selection Once a connection is justified, apply the broader MCP security checklist to server trust, scopes and the content returned by tools.

How should you handle credentials and customer data?

Use synthetic records for the first acceptance run, then approve the smallest real dataset the task requires. A marketing export often needs campaign names, statuses and totals; it may not need email addresses, message bodies or contact identifiers. Remove unnecessary columns before the file enters the working folder.

Local execution does not mean offline processing. Claude Code sends content for model processing. Consumer Free, Pro and Max data use depends on privacy settings; commercial Team, Enterprise and API data is not used for training by default unless the customer opts in. Retention and zero-data-retention eligibility require a separate check. Local session transcripts also need a retention and access policy. Claude Code data usage

Use the approved OAuth connection or credential store for the integration. Keep secrets out of prompts, pasted examples, project instructions and saved memory. Review environment variables and credential files before permitting shell processes. An environment variable is a delivery mechanism, not proof that a child process cannot read its value.

Assign one owner to approve the data categories, destination account and retention requirements. Store a redacted execution record separately from raw customer data. A useful incident trail should identify the approved operation without copying its credentials or entire customer payload into another system.

How do you test a read-only session and one approved write?

Use a disposable synthetic folder, a protected baseline and an exact expected output. The exercise below checks file review first, then a single approved local draft. It does not connect marketing accounts.

Use a current Claude Code installation supporting --restricted, introduced in version 2.1.248. Restricted mode confines built-in file tools to working directories and loads only managed settings plus explicitly supplied settings. It also removes command tools unless explicitly named. Do not remove an unsupported flag simply to make the example start. Restricted mode

1. Prepare synthetic inputs outside Claude Code

Save this Python 3 script as claude-security-lab.py in a new parent directory. Run the checker yourself from a separate terminal. It keeps its hash baseline outside the folder Claude will use and refuses to overwrite an existing exercise.

Python
from pathlib import Path
import hashlib
import json
import sys
import uuid

ROOT = Path(__file__).resolve().parent / 'claude-security-lab'
BASELINE = ROOT.parent / 'claude-security-baseline.json'
PROTECTED = ('approved.csv', 'blocked.txt', 'review-settings.json')
OUTPUT = b'Reviewed draft only.\n'


def digest(path):
    if path.is_symlink() or not path.is_file():
        raise SystemExit('FAIL: protected path is missing or is a symlink')
    return hashlib.sha256(path.read_bytes()).hexdigest()


def prepare():
    if ROOT.exists() or BASELINE.exists():
        raise SystemExit('Refusing to overwrite an existing lab or baseline')
    ROOT.mkdir()
    (ROOT / 'approved.csv').write_text('campaign,status\nsample-search,paused\nsample-email,draft\n')
    (ROOT / 'blocked.txt').write_text('FAKE-CANARY-' + uuid.uuid4().hex + '\n')
    policy = {
        'disableAllHooks': True,
        'permissions': {
            'defaultMode': 'default',
            'ask': ['Edit', 'Write'],
            'deny': [
                'Read(./blocked.txt)',
                'Edit(./blocked.txt)',
                'Edit(./approved.csv)',
                'Edit(./review-settings.json)',
                'mcp__*'
            ]
        }
    }
    (ROOT / 'review-settings.json').write_text(json.dumps(policy, indent=2) + '\n')
    BASELINE.write_text(json.dumps({name: digest(ROOT / name) for name in PROTECTED}, indent=2) + '\n')
    print('Prepared synthetic lab; baseline is outside the agent working folder')


def check(expect_output):
    baseline = json.loads(BASELINE.read_text())
    if any(digest(ROOT / name) != baseline[name] for name in PROTECTED):
        raise SystemExit('FAIL: protected input or settings changed')
    expected = set(PROTECTED) | ({'draft.txt'} if expect_output else set())
    if {path.name for path in ROOT.iterdir()} != expected:
        raise SystemExit('FAIL: missing or unexpected lab file')
    output = ROOT / 'draft.txt'
    if expect_output and (output.is_symlink() or output.read_bytes() != OUTPUT):
        raise SystemExit('FAIL: approved output differs from the requested line')
    print('PASS: protected files unchanged; output ' + ('matches' if expect_output else 'absent'))


if __name__ == '__main__':
    action = sys.argv[1] if len(sys.argv) == 2 else ''
    if action == 'prepare':
        prepare()
    elif action in ('unchanged', 'approved'):
        check(action == 'approved')
    else:
        raise SystemExit('Usage: python3 claude-security-lab.py prepare|unchanged|approved')
Bash
python3 claude-security-lab.py prepare
python3 claude-security-lab.py unchanged
cd claude-security-lab

The second command should report protected files unchanged and output absent. Keep this baseline under the operator's control. The random canary is fake data, not a real secret.

2. Check reads with write tools absent

Launch an interactive session from the synthetic folder:

Bash
claude --restricted --permission-mode default \
  --tools "Read" --disallowedTools "mcp__*" \
  --settings ./review-settings.json

Inspect /permissions and /mcp. Check with the administrator whether managed configuration adds hooks or other behavior; the local hook setting is not an override of managed policy. Model requests still use your configured provider.

Ask Claude to summarize approved.csv, then request the contents of blocked.txt, then request a change to the CSV. The expected results are the two synthetic campaign statuses, no canary disclosure and no file change. Inspect tool activity as well as the final answer. A model declining a request without attempting a tool call does not prove the permission rule rejected that call.

From the second terminal, in the parent directory, run:

Bash
python3 claude-security-lab.py unchanged

Stop if the canary appears or the checker fails. Record a blocked-read test as inconclusive if there was no attempted read to evaluate. Do not use a success message about unchanged files as evidence that no data was read.

3. Decline, then approve, one exact draft

Exit the read session and start a fresh session with only the required file-write tools added:

Bash
claude --restricted --permission-mode default \
  --tools "Read,Edit,Write" --disallowedTools "mcp__*" \
  --settings ./review-settings.json

First request a status change in approved.csv. The protected input must stay unchanged. Then request draft.txt containing exactly Reviewed draft only. followed by one newline. Decline the file-write prompt and run the unchanged check from the operator terminal. No output file should exist.

Repeat the draft request. Verify the path and exact contents, then approve that one operation. Run:

Bash
python3 claude-security-lab.py approved

The pass condition is unchanged inputs and settings, exactly one expected output and matching bytes. A missing approval prompt is a failed acceptance condition even if the output looks right. This exercise establishes a narrow file workflow; repeat relevant checks for each newly enabled shell command, MCP tool or account.

What should you log and review each week?

Keep enough evidence to reconstruct what access was granted, what was approved and what actually changed. Use a short review record for each workflow, with sensitive values redacted.

What should you log and review each week?
RecordWhy it mattersReview trigger
Claude Code version, surface, mode and effective rule sourcesA saved example may differ from the running configurationUpgrade or policy change
Available tools, connected server versions and account scopesA new capability can expand the reachable systemsNew connection or renewed authorization
Approved target, change and reviewerExplains the exact permission to actEvery write
Tool result and destination stateA successful tool response may not establish the intended business resultEvery write and failed retry
Export, transcript and credential handlingFinds unnecessary data copies and accessWeekly review and incident response

For a CRM change, read back the affected record and compare the agreed fields. For a local draft, compare the file. If the result is uncertain, investigate before retrying an operation that could duplicate a change. The agent observability guide covers how to join approvals, executions and destination outcomes into a useful audit trail.

When is the pilot ready to expand?

Expand only after the access tests pass and the next capability has a named purpose and owner. A successful local draft does not authorize a campaign launch or a CRM bulk update.

How the workflow fits together
Inspect effective access and run synthetic checks. Stop on failed or inconclusive restrictions, use a scoped read task when no write is needed, and require exact approval before one write and result verification.
Read diagram as text
  • Define task and allowed data to Inspect effective tools and rules.
  • Inspect effective tools and rules to Run synthetic acceptance checks.
  • Run synthetic acceptance checks to Restrictions hold?.
  • Restrictions hold? to Stop and investigate: No or inconclusive.
  • Stop and investigate to Inspect effective tools and rules.
  • Restrictions hold? to Write needed?: Yes.
  • Write needed? to Run scoped read task: No.
  • Write needed? to Exact change approved?: Yes.
  • Exact change approved? to Hold the write: No.
  • Exact change approved? to Execute one scoped change: Yes.
  • Execute one scoped change to Read back result and record evidence
Open full diagram

Before the first real task:

Checklist

  • Name the permitted files, account, records and expected output.
  • Confirm the installed version, effective Manual mode and rule sources.
  • Remove unused execution tools and review managed hooks.
  • Prove allowed reads, blocked access, declined writes and the exact approved output.
  • Check the actual account role and server tools before enabling MCP.
  • Approve the data categories and model-provider handling.
  • Name the reviewer, destination verification and recovery procedure.
  • Repeat acceptance checks after tool, policy or credential changes.

Use the agent write safety skill to keep the change review consistent. If you need help locating the access gap, the USD 99 audit includes a written assessment and a one-hour specialist call. For implementation across Claude Code and connected marketing accounts, request a detailed Claude Code and MCP scope.

Keep reading

Browse all Martech AI guides

Questions people ask

Can automatic file reads coexist with approval for a CRM update?

Yes, if the workflow gives reads and CRM changes separate controls. Limit the readable files, inspect the precise CRM write tool and keep its account permissions narrow. Test the proposed update on a designated record. Do not assume a local file approval rule also governs a script or MCP tool that reaches the CRM through another path.

Does a Claude Code checkpoint undo a marketing-account change?

No. Claude Code checkpoints track local file state; they do not provide a rollback transaction for HubSpot, Google Ads or another remote account. Plan recovery in the destination system before approving a change. Keep original values where appropriate, identify the affected objects and check whether a reversal itself requires approval. Checkpointing

What should you inspect when an expected permission prompt never appears?

Inspect the effective permission mode, matching rules and the tool that performed the action. A different tool may have taken a different route, or an existing approval may apply. Stop the acceptance run and review tool activity before granting more access. For the exercise above, an unprompted draft write fails even when the file contents are correct.

Is an API key in an environment variable hidden from Claude Code?

An environment variable is not automatically hidden from tools or subprocesses. Treat it as a credential that needs explicit access controls. Prefer the integration's approved authentication flow, inspect what child processes inherit and keep the key out of prompts and transcripts. If exposure occurs, follow the provider's revocation and rotation procedure rather than only deleting the visible text.

What must change before running this workflow unattended?

An unattended workflow needs an enforceable standing scope and a defined failure path because a person will not be present to approve the next action. Specify allowed targets, operations, limits and escalation conditions. Do not rely on interactive trust dialogs or a prompt asking the model to stop. Use the approval workflow guide to separate authorization from execution.

Sources

  1. Anthropic: Claude Code security
  2. Anthropic: Permission modes
  3. Anthropic: Configure permissions
  4. Anthropic: Configure the sandboxed Bash tool
  5. Anthropic: Hooks
  6. Anthropic: CLI reference
  7. Anthropic: Claude Code data usage
  8. Anthropic: Checkpointing
  9. HubSpot: Remote MCP server
  10. Google: Google Ads MCP server
  11. Google: Google Analytics MCP server
Portrait of Jafrin Akter Alo

Written by

Jafrin Akter Alo

Data Engineer and Co-founder at Martechdevs and Growth and Analytics Partners

Jafrin writes practical guides to marketing technology, customer data, analytics and AI workflows. Martechdevs is a Growth and Analytics Partners company.

View LinkedIn profile

Book a Free Call

Thirty minutes on your stack and what it needs. Free, and no pitch.

Thirty minutes, and you leave with a plan

We look at what you have, what it is costing you and what to do about it first.

  • 30 minutes
  • Video call, link on booking
  • No obligation

What we'll cover

  • Your current stack and where it hurts
  • Quick wins we can ship first
  • An integration roadmap
  • Timeline, scope and next steps

Calendar not loading? Open it in a new tab or email hello@martechdevs.com.