C1: close forge package leak at the fly edge

forge.eblu.me's package registry (/api/packages/* and /api/v1/packages/*)
served anonymous reads to the world even for private-repo releases —
Forgejo's per-user visibility treats packages as world-readable when
the owner's Visibility is Public, and we keep eblume Public so the
profile page stays open. The sdist downloads include full source
trees of private repos; that's the leak.

The fix is to keep the user public but block /api/packages/* and
/api/v1/packages/* at the proxy edge. forge.ops.eblu.me (tailnet) is
untouched, so CI workflows + gilbert's uv + the nix-container-builder
still work — they just need to use the tailnet hostname.

Three consumers updated to forge.ops.eblu.me:
  - containers/shower/default.nix (the FOD pip --extra-index-url)
  - ansible/roles/cv/defaults/main.yml (cv_release_url for generic package)
  - chezmoi-tracked fish dotfiles (devpi.fish + conf.d/pypi.fish) —
    edited in chezmoi source, user will apply separately

The blumeops repo had no other forge-pypi consumers (audited: workers,
runner-job-image, ansible roles, container builds). Doc references in
changelog fragments + comments left as-is — they describe history.

The proper long-term fix is to move private packages to a Limited-
visibility Forgejo org instead of relying on a proxy-side block (see
queued Todoist for the migration plan). Edge block stays as
defense in depth.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erich Blume 2026-05-11 13:06:48 -07:00
commit 2d38418e6e
3 changed files with 19 additions and 2 deletions

View file

@ -49,7 +49,7 @@ let
"$TMPDIR/venv/bin/pip" install \
--no-cache-dir \
--index-url=https://pypi.ops.eblu.me/root/pypi/+simple/ \
--extra-index-url=https://forge.eblu.me/api/packages/eblume/pypi/simple/ \
--extra-index-url=https://forge.ops.eblu.me/api/packages/eblume/pypi/simple/ \
"adelaide-baby-shower-app==${version}" \
gunicorn