From 292ecc148843699bc0424486404e0956ed51cc64 Mon Sep 17 00:00:00 2001 From: Andrew Nesbitt Date: Fri, 6 Nov 2026 22:36:47 +0000 Subject: [PATCH 1/2] Correct package manager configuration examples --- README.md | 34 ++++++++++++++++++---------------- docs/configuration.md | 2 +- internal/server/dashboard.go | 27 ++++++++++----------------- 3 files changed, 29 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index be4f0eee..a43ae27d 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,7 @@ The proxy never uploads artifact bytes to a scanner. Each scanner is notified wi Cooldown requires publish timestamps in metadata. Registries without a "Yes" in the cooldown column either don't expose timestamps or haven't been wired up yet. -\* Hex cooldown requires disabling registry signature verification (`HEX_NO_VERIFY_REPO_ORIGIN=1`) since the proxy re-encodes the protobuf payload. +\* Hex cooldown requires disabling registry signature verification (`HEX_UNSAFE_REGISTRY=1`) since the proxy re-encodes the protobuf payload. Origin verification can stay enabled. † Go cooldown uses the time in each version's `.info`, which is the commit time of the tagged revision, not when the tag was pushed. @@ -288,10 +288,10 @@ The equivalent environment variables are `PROXY_UPSTREAM_HOMEBREW_API` and `PROX ### Hex (Elixir) -Configure in `~/.hex/hex.config`: +Configure the mirror: -```erlang -{default_url, <<"http://localhost:8080/hex">>}. +```bash +mix hex.config mirror_url http://localhost:8080/hex ``` Or set the environment variable: @@ -300,6 +300,14 @@ Or set the environment variable: export HEX_MIRROR=http://localhost:8080/hex ``` +When the proxy applies a cooldown, also set: + +```bash +export HEX_UNSAFE_REGISTRY=1 +``` + +Filtering releases removes the registry signature. The proxy preserves the package name and repository fields, so origin verification can stay enabled. Without a cooldown, leave signature verification enabled too. + ### pub.dev (Dart/Flutter) Set the PUB_HOSTED_URL environment variable: @@ -359,17 +367,15 @@ Configure in `settings.gradle.kts`: ```kotlin buildCache { - local { - enabled = false - } remote { url = uri("http://localhost:8080/gradle/") - isPush = System.getenv("CI") != null } } ``` -The proxy rejects uploads unless `gradle.build_cache.read_only` is set to `false`, see [docs/configuration.md](docs/configuration.md#gradle-build-cache). +Enable build caching with `org.gradle.caching=true` in `gradle.properties`, or pass `--build-cache` when running Gradle. The local cache stays enabled and remote uploads are disabled by default. + +To upload from CI, set `gradle.build_cache.read_only` to `false` on the proxy and add `isPush = System.getenv("CI") != null` inside the client's `remote` block. See [docs/configuration.md](docs/configuration.md#gradle-build-cache). ### NuGet @@ -459,8 +465,6 @@ Configure in `~/.condarc`: channels: - http://localhost:8080/conda/main - http://localhost:8080/conda/conda-forge -default_channels: - - http://localhost:8080/conda/main ``` Or set via command: @@ -716,16 +720,14 @@ indexes unchanged. To keep APT from selecting a denied version, configure ### RPM / Yum / DNF -Configure yum/dnf to use the proxy in `/etc/yum.repos.d/proxy.repo`: +In the `[fedora]` section of your existing repository file under `/etc/yum.repos.d/`, replace the `metalink` or `mirrorlist` entry with: ```ini -[proxy-fedora] -name=Fedora via Proxy baseurl=http://localhost:8080/rpm/releases/$releasever/Everything/$basearch/os/ -enabled=1 -gpgcheck=0 ``` +Keep the existing `gpgkey` and signature settings, including `gpgcheck=1`. The proxy serves RPM packages unchanged, so their signatures remain valid. + Then: ```bash diff --git a/docs/configuration.md b/docs/configuration.md index 63cc175d..accaefb1 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -1244,7 +1244,7 @@ With cooldown on, the proxy asks npm for full packuments, since the abbreviated Conda cooldown covers `repodata.json`, `current_repodata.json`, `repodata_from_packages.json` and sharded repodata (CEP 16). Other forms of the repodata, such as `repodata.json.zst`, `repodata.json.bz2` and `repodata.jlap` patches, would list versions still in cooldown, so with cooldown on they are answered 404 and conda and mamba fall back to `repodata.json`. With `cache_metadata`, `repodata.json` is read through the metadata cache as it is without cooldown: within `metadata_ttl` the stored copy is filtered as it is read from storage, after it the upstream is asked with its ETag, and while the upstream is down the stale copy is filtered. Once a document has been filtered, the proxy remembers the ETag of the result until the first entry it left out leaves cooldown, so a client revalidating with `If-None-Match` gets `304 Not Modified` without the document being filtered or sent again. The first response for each document has no ETag, as it is sent while it is filtered. Without `cache_metadata`, `repodata.json` is fetched and filtered on every request. Clients cache shards by the hash in the shard index, so with cooldown on the proxy serves a rewritten index whose shard hashes change every hour and filters each shard as it is fetched. Versions leaving cooldown show up within the hour, and clients fetch the shards they need again once an hour. If a channel's shard index points packages or shards somewhere the proxy doesn't route, the proxy answers 404 for it and clients fall back to `repodata.json`. -Note: Hex cooldown requires disabling registry signature verification since the proxy re-encodes the protobuf payload without the original signature. Set `HEX_NO_VERIFY_REPO_ORIGIN=1` or configure your repo with `no_verify: true`. +Hex cooldown requires `HEX_UNSAFE_REGISTRY=1` because filtering releases re-encodes the protobuf payload without the original signature. The proxy preserves the package name and repository fields, so origin verification can stay enabled. `HEX_NO_VERIFY_REPO_ORIGIN` controls origin verification and does not disable signature verification. Without a cooldown, leave signature verification enabled too. ## Version denylist diff --git a/internal/server/dashboard.go b/internal/server/dashboard.go index 217f0182..f566d551 100644 --- a/internal/server/dashboard.go +++ b/internal/server/dashboard.go @@ -324,11 +324,11 @@ bundle config mirror.https://rubygems.org ` + baseURL + `/gem`), Language: "Elixir", Endpoint: "/hex/", Instructions: template.HTML(`

Configure Hex to use the proxy:

-
# In ~/.hex/hex.config
-{default_url, <<"` + baseURL + `/hex">>}.
+
mix hex.config mirror_url ` + baseURL + `/hex
 
 # Or via environment variable
-export HEX_MIRROR=` + baseURL + `/hex
`), +export HEX_MIRROR=` + baseURL + `/hex
+

When the proxy applies a cooldown, also set HEX_UNSAFE_REGISTRY=1 to disable registry signature verification. Origin verification can stay enabled.

`), }, { ID: "pub", @@ -378,10 +378,10 @@ index-url = ` + baseURL + `/pypi/simple/`), buildCache { remote<HttpBuildCache> { url = uri("` + baseURL + `/gradle/") - isPush = System.getenv("CI") != null } } -

Uploads need gradle.build_cache.read_only: false on the proxy.

`), +

Enable build caching with org.gradle.caching=true in gradle.properties, or pass --build-cache when running Gradle. The local cache stays enabled and remote uploads are disabled by default.

+

To upload from CI, set gradle.build_cache.read_only: false on the proxy and add isPush = System.getenv("CI") != null inside the client's remote<HttpBuildCache> block.

`), }, { ID: "nuget", @@ -448,8 +448,6 @@ conan remote disable conancenter`), channels: - ` + baseURL + `/conda/main - ` + baseURL + `/conda/conda-forge -default_channels: - - ` + baseURL + `/conda/main # Or via command conda config --add channels ` + baseURL + `/conda/main`), @@ -523,17 +521,12 @@ sudo apt update`), { ID: "rpm", Name: "RPM/Yum", - Language: "Fedora/RHEL", + Language: "Fedora", Endpoint: "/rpm/", - Instructions: template.HTML(`

Configure yum/dnf to use the proxy:

-
# In /etc/yum.repos.d/proxy.repo
-[proxy-fedora]
-name=Fedora via Proxy
-baseurl=` + baseURL + `/rpm/releases/$releasever/Everything/$basearch/os/
-enabled=1
-gpgcheck=0
-
-# Then run:
+			Instructions: template.HTML(`

In the [fedora] section of your existing repository file under /etc/yum.repos.d/, replace the metalink or mirrorlist entry with:

+
baseurl=` + baseURL + `/rpm/releases/$releasever/Everything/$basearch/os/
+

Keep the existing gpgkey and signature settings, including gpgcheck=1. The proxy serves RPM packages unchanged.

+
# Then run:
 sudo dnf clean all
 sudo dnf update
`), }, From f153a83b3a286b9e3c9f9c04559bd3b674763389 Mon Sep 17 00:00:00 2001 From: Andrew Nesbitt Date: Sat, 7 Nov 2026 09:46:54 +0000 Subject: [PATCH 2/2] Cover Fedora updates and Conda defaults in setup docs --- README.md | 11 +++++++++++ internal/server/dashboard.go | 36 +++++++++++++++++++++++------------- 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index a43ae27d..7739645c 100644 --- a/README.md +++ b/README.md @@ -465,12 +465,17 @@ Configure in `~/.condarc`: channels: - http://localhost:8080/conda/main - http://localhost:8080/conda/conda-forge +default_channels: + - http://localhost:8080/conda/main ``` +`default_channels` also routes requests for `defaults` through the proxy, including `-c defaults` and `environment.yml` files that name it. + Or set via command: ```bash conda config --add channels http://localhost:8080/conda/main +conda config --add default_channels http://localhost:8080/conda/main ``` pixi and other rattler-based clients use sharded repodata ([CEP 16](https://github.com/conda/ceps/blob/main/cep-0016.md)) where a channel offers it, as conda-forge does. Point them at the same channel URLs, for example `pixi init -c http://localhost:8080/conda/conda-forge`. The shard index and shards are cached as metadata when `cache_metadata` is on. @@ -726,6 +731,12 @@ In the `[fedora]` section of your existing repository file under `/etc/yum.repos baseurl=http://localhost:8080/rpm/releases/$releasever/Everything/$basearch/os/ ``` +In the `[updates]` section of `fedora-updates.repo`, replace its `metalink` or `mirrorlist` entry with: + +```ini +baseurl=http://localhost:8080/rpm/updates/$releasever/Everything/$basearch/ +``` + Keep the existing `gpgkey` and signature settings, including `gpgcheck=1`. The proxy serves RPM packages unchanged, so their signatures remain valid. Then: diff --git a/internal/server/dashboard.go b/internal/server/dashboard.go index f566d551..604a4bf0 100644 --- a/internal/server/dashboard.go +++ b/internal/server/dashboard.go @@ -448,9 +448,13 @@ conan remote disable conancenter
`), channels: - ` + baseURL + `/conda/main - ` + baseURL + `/conda/conda-forge +default_channels: + - ` + baseURL + `/conda/main # Or via command -conda config --add channels ` + baseURL + `/conda/main`), +conda config --add channels ` + baseURL + `/conda/main +conda config --add default_channels ` + baseURL + `/conda/main +

default_channels also routes requests for defaults through the proxy, including -c defaults and environment.yml files that name it.

`), }, { ID: "cran", @@ -518,18 +522,7 @@ deb ` + baseURL + `/debian stable main contrib # Then run: sudo apt update`), }, - { - ID: "rpm", - Name: "RPM/Yum", - Language: "Fedora", - Endpoint: "/rpm/", - Instructions: template.HTML(`

In the [fedora] section of your existing repository file under /etc/yum.repos.d/, replace the metalink or mirrorlist entry with:

-
baseurl=` + baseURL + `/rpm/releases/$releasever/Everything/$basearch/os/
-

Keep the existing gpgkey and signature settings, including gpgcheck=1. The proxy serves RPM packages unchanged.

-
# Then run:
-sudo dnf clean all
-sudo dnf update
`), - }, + rpmRegistryConfig(baseURL), { ID: "apk", Name: "Alpine APK", @@ -559,6 +552,23 @@ pacman -Syu`), } } +func rpmRegistryConfig(baseURL string) RegistryConfig { + return RegistryConfig{ + ID: "rpm", + Name: "RPM/Yum", + Language: "Fedora", + Endpoint: "/rpm/", + Instructions: template.HTML(`

In the [fedora] section of your existing repository file under /etc/yum.repos.d/, replace the metalink or mirrorlist entry with:

+
baseurl=` + baseURL + `/rpm/releases/$releasever/Everything/$basearch/os/
+

In the [updates] section of fedora-updates.repo, replace its metalink or mirrorlist entry with:

+
baseurl=` + baseURL + `/rpm/updates/$releasever/Everything/$basearch/
+

Keep the existing gpgkey and signature settings, including gpgcheck=1. The proxy serves RPM packages unchanged.

+
# Then run:
+sudo dnf clean all
+sudo dnf update
`), + } +} + // freebsdRegistryConfig describes the FreeBSD pkg endpoint for the dashboard. func freebsdRegistryConfig(baseURL string) RegistryConfig { return RegistryConfig{