Skip to content

claude-docker: add --registry flag for private package registries (uv / pnpm / pip) - #57

Merged
stefanwb merged 5 commits into
stefanwb:mainfrom
carlovoSBP:artifact-repo
Jul 13, 2026
Merged

stefanwb merged 5 commits into
stefanwb:mainfrom
carlovoSBP:artifact-repo

Conversation

@carlovoSBP

Copy link
Copy Markdown
Contributor

Summary

Adds a --registry opt-in flag to claude-docker so in-container uv, pnpm,
and pip-based tools (pip/pipenv) resolve against a private package feed —
AWS CodeArtifact, Artifactory, Nexus, GitLab/Azure — the same way the team's
pipelines do, instead of always hitting public npm / PyPI.

The approach is deliberately a thin wrapper concern: rather than invent any
claude-docker-specific registry config, --registry surfaces the package
managers' own native config
from the host (read-only mounts + native env-var
forwarding), exactly mirroring how --aws / --gh / --glab / --tfe already
surface other host credentials. This inherits every registry vendor for free —
they all speak the npm/PyPI dialect — and means a host that already runs
aws codeartifact login works with zero extra steps.

Off by default; nothing reaches the container without the flag.

What it does

When --registry is passed, run.sh:

  • Mounts read-only (silent no-op when absent): the host npm config
    (~/.npmrc, or the npm_config_userconfig target if relocated) → /root/.npmrc,
    ~/.config/uv/uv.toml, and the platform-appropriate pip.conf
    (macOS ~/Library/Application Support/pip/pip.conf, Linux ~/.config/pip/pip.conf).
  • Forwards native env vars when set: npm_config_registry /
    NPM_CONFIG_REGISTRY / NODE_AUTH_TOKEN / NPM_TOKEN, UV_INDEX_URL /
    UV_DEFAULT_INDEX / UV_EXTRA_INDEX_URL / UV_INDEX / UV_KEYRING_PROVIDER
    plus any UV_INDEX_<NAME>_USERNAME / _PASSWORD (uv's per-index credentials,
    whose names embed a user-chosen index name), and PIP_INDEX_URL /
    PIP_EXTRA_INDEX_URL / PIP_TRUSTED_HOST / PIPENV_PYPI_MIRROR.
  • Tags the statusline docker:…,registry.

No image/Dockerfile change — uv/pnpm already ship. pip/pipenv aren't
bundled (the image ships no Python by design); run them via uvx pipenv … or a
child image, and the forwarded config flows through to whichever pip executes.

Security posture

  • Default-deny + explicit opt-in, same as the other credential flags.
  • All mounts :ro — the container can't mutate host registry config, and a
    session can't persist registry credentials into the named volume.
  • ~/.netrc is deliberately NOT mounted. It's a machine-keyed store that
    routinely holds logins for hosts unrelated to the registry; forwarding the
    whole file into a full-egress container is too broad. UV_NETRC isn't
    forwarded either. Registry auth belongs in ~/.npmrc / pip.conf / the index
    URL / UV_INDEX_*_PASSWORD.
  • The dynamic UV_INDEX_* scan is scoped strictly to the _USERNAME/_PASSWORD
    suffixes — no blanket UV_* forward (avoids dragging in path-valued vars like
    UV_CACHE_DIR that would point at absent host paths).
  • --registry is registry-resolution config, not a network boundary — it
    narrows where the package managers resolve, but egress is unchanged.
  • Runtime-only: the image build still resolves its own tooling against
    public npm/PyPI regardless of host registry config, keeping builds
    reproducible from the committed pins.
  • ~/.npmrc / pip.conf are whole-file mounts, so a token-bearing file exposes
    every entry it holds — documented as a ⚠️ caution in the README.

🤖 Generated with Claude Code
✅ verified by carlovoSBP

@carlovoSBP carlovoSBP changed the title Artifact repo claude-docker: add --registry flag for private package registries (uv / pnpm / pip) Jun 25, 2026

@stefanwb stefanwb left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adds an opt-in --registry flag that surfaces the host's native package-manager registry config (~/.npmrc, uv.toml, platform-aware pip.conf + scoped env vars) read-only into the container. Faithfully mirrors the existing --aws/--gh/--glab/--tfe pattern.

Correctness — verified against surrounding code:

  • Arrays (ENV_ARGS/MOUNT_ARGS) initialized before the registry blocks; set -u/bash-3.2 guards preserved.
  • HOME=/root (entrypoint.sh:17) confirms mount targets are the paths the tools actually read.
  • compgen -e scan is pipefail-safe (process substitution) and correctly suffix-scoped to avoid the UV_CACHE_DIR foot-gun.
  • -xdev in the entrypoint chown prunes the new :ro mounts — no ownership conflict.

Security — well reasoned: default-deny, all mounts :ro, and the deliberate ~/.netrc exclusion (D9) is the right call. Whole-file exposure is honestly documented (⚠️) and the "resolution config, not egress boundary" framing is accurate. The no-mask decision (D6) is sound given RO mounts can't persist to the volume.

Suggestions (non-blocking):

  1. smoke/smoke.sh wasn't extended for --registry — it has structured coverage for aws/glab/tfe and this fits the same pattern. Worth adding to lock in the no-flag invariant.
  2. tasks.md has stale references: task 1.2 still says to mount ~/.netrc (contradicts shipped D9), and 3.6's "superseded by 5.5" points at a non-existent task. Cosmetic cleanup of archived artifacts.

TL;DR Thanks for this PR, it does LGTM. Could you consider implementing #1 as well? That would be appreciated, also fine to merge as-is.

@stefanwb
stefanwb merged commit 037572d into stefanwb:main Jul 13, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants