[BUG] [SECURITY] Claude binary distribution auto-installs itself to ~/.local without asking for user permission

Resolved 💬 2 comments Opened Jan 29, 2026 by ink-splatters Closed Feb 28, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

The issue

New binary distribution of CC produces unexpected side effects which cannot be (easily) suppressed.

In particular, it

  • reports error saying that despite native installer is used, ~/.local/bin/claude is missing;
  • it then installs itself to ~/.local, without asking for a permission to do so, and without providing any configuration of this behavior.

Why it's bad

Security related impact

Manifesting with unwanted behavior without obtaining a user consent raises security concerns.

It cannot be trivially suppressed

If I'm not missing anything, claude --help doesn't specify a flag or environment variable to disable this behavior.

It violates principle of least astonishment

By calling claude --help one may discover install functionality and reasonably assume that this is (the only) entry point to trigger this behavior.

Despite its lacking meaningful config options<sup>1</sup> which is separate concern, at least it implies users's clear intent to install the software, which is not the case with silent installation in background.

It's potentially breaking change of the system state

No legitimate software shall assume it may silently introduce itself into users's PATH because this has a potential of breaking user setups.

It's not compatible with environments enforcing isolation of the installed software

I'm primarily talking about nix, and in this case - primarily about FS-level isolation.

However not only nix provides such a functionality.

---
<sup>1</sup> Having just distribution flavor and --force is quite a limited choice of specifying installation behavior

Example

CC's auto installing itself to ~/.local is not compatible with nix way of installing it.

The below are

  • Claude Code nix derivation
  • manifest fetcher for Claude Code installation which adopts it for usage by nix derivation

claude-code.nix
fetch-claude-code-manifest.py

<details><summary>Or click here to expand</summary>

```claude-code.nix
{
fetchurl,
makeWrapper,
stdenvNoCC,
}: let
meta-info = builtins.fromJSON (builtins.readFile ./meta-info.json);

inherit (meta-info) platforms version;

platform = let
inherit (stdenvNoCC.hostPlatform) darwinArch linuxArch;
in
if stdenvNoCC.isDarwin
then "darwin-${darwinArch}"
else if stdenvNoCC.isLinux
then "linux-${linuxArch}"
else "unknown";
in
assert (platform != "unknown");
stdenvNoCC.mkDerivation {
pname = "claude-code";
inherit version;

src = fetchurl {
inherit (platforms."${platform}") url sha256;
};

dontUnpack = true;

nativeBuildInputs = [makeWrapper];

installPhase = ''
runHook preInstall

install -Dm755 $src $out/bin/claude

runHook postInstall
'';

# TODO: find a way to disable automatic installation to ~/.local
postInstall = ''
wrapProgram $out/bin/claude \
--set DISABLE_AUTOUPDATER 1 \
--unset DEV
'';
}


```fetch-claude-code-manifest.py
#!/usr/bin/env -S uv run --script
# /// script
# dependencies = ["requests"]
# ///

import dataclasses as d
import json
import logging
import re
import sys

import requests

logging.basicConfig(stream=sys.stderr, level=logging.INFO)
logger = logging.getLogger("fetch-meta")

gcs_bucket = "https://storage.googleapis.com/claude-code-dist-86c565f3-f756-42ad-8dfa-d59b1c096819/claude-code-releases"

_version_re = re.compile(r"^\d+\.\d+\.\d+$")


@d.dataclass(frozen=True, slots=True)
class PlatformEntry:
    checksum: d.InitVar[str]
    size: int
    url: str = ""
    sha256: str = d.field(init=False)

    def __post_init__(self, checksum: str) -> None:
        object.__setattr__(self, "sha256", checksum)


@d.dataclass(frozen=True, slots=True)
class Manifest:
    version: str
    build_date: str
    platforms: dict[str, PlatformEntry]


def fetch_latest_version() -> str:
    url = f"{gcs_bucket}/latest"
    logger.debug(f"fetching latest version from {url}")

    r = requests.get(url)
    r.raise_for_status()

    version = r.text.strip()
    if not _version_re.match(version):
        raise ValueError(f"invalid version format: {version!r}")

    logger.debug(f"latest version: {version}")
    return version


def manifest_with_urls() -> Manifest:
    version = fetch_latest_version()
    url = f"{gcs_bucket}/{version}/manifest.json"

    logger.debug(f"fetching manifest from {url}")
    r = requests.get(url)
    r.raise_for_status()

    data: dict = r.json()
    logger.debug(f"raw manifest: {data}")

    platforms = {
        platform.replace("-x64", "-x86_64"): PlatformEntry(
            url=f"{gcs_bucket}/{version}/{platform}/claude",
            **entry,
        )
        for platform, entry in data["platforms"].items()
    }

    return Manifest(
        version=data["version"],
        build_date=data["buildDate"],
        platforms=platforms,
    )


if __name__ == "__main__":
    try:
        logger.info("Getting meta info...")
        manifest = manifest_with_urls()
        print(json.dumps(d.asdict(manifest), indent=2))
    except Exception as e:
        logger.error(str(e))

</details>

What Should Happen?

  1. Despite I acknowledge that CC installing itself to ~/.local might be acceptable behavior for users who don't have a strong opinion about it and just "want things to work", it MUST request explicit user consent to do so
  1. This behavior MUST be suppressible via, ideally, an environment variable or in any other reasonable way

Error Messages/Logs

Not applicable

Steps to Reproduce

Given the artifacts above:

1.

nix shell nixpkgs#uv
chmod +x ./fetch-claude-code-manifest.py
./fetch-claude-code-manifest.py | tee meta-info.json
nix-build claude-code.nix
./result/bin/claude
  1. Observe the described behavior

Claude Model

None

Is this a regression?

Yes, this worked in a previous version

Last Working Version

npm-based distributions

Claude Code Version

2.1.23

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Other

Additional Information

_No response_

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗