From c125c8d8373b7739bd9d4a89d5d28350ef107ae2 Mon Sep 17 00:00:00 2001 From: ilitteri Date: Wed, 27 May 2026 16:30:49 -0300 Subject: [PATCH 1/3] fix(l2): set Nix fetchurl User-Agent so crates.io stops 403ing the TDX image build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit crates.io now returns HTTP 403 to any request whose User-Agent contains the substring "curl/". Nix's fetchurl — used by rustPlatform.importCargoLock to vendor crates for the TDX quote-gen image — sends "curl/ Nixpkgs/", so every crate download during `make image.raw` fails. This breaks the "L2 TDX build" job on main and on every PR. fetchurl appends $NIX_CURL_FLAGS to its curl invocation (the last --user-agent wins) and whitelists it in impureEnvVars, so it reaches the sandboxed crate fixed-output derivations. Set it on the nix-build command to override the User-Agent with one crates.io accepts. It is set inline rather than via `export` because GNU Make's $(shell ...) does not inherit exported variables, and as a single space-free token because fetchurl word-splits the value. --- crates/l2/tee/quote-gen/Makefile | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/crates/l2/tee/quote-gen/Makefile b/crates/l2/tee/quote-gen/Makefile index 59776347992..9b30558c454 100644 --- a/crates/l2/tee/quote-gen/Makefile +++ b/crates/l2/tee/quote-gen/Makefile @@ -6,13 +6,22 @@ NIXPKGS_URL = https://github.com/NixOS/nixpkgs/archive/3fcbdcfc707e0aa42c541b774 GIT_REV := $(shell git rev-parse --short=7 HEAD) NIX_BUILD_ARGS = --no-out-link -I nixpkgs=$(NIXPKGS_URL) --argstr gitRev "$(GIT_REV)" +# crates.io returns HTTP 403 for any User-Agent containing "curl/", which is what +# Nix's fetchurl sends by default (`curl/ Nixpkgs/`). That breaks every +# crate download during the image build. fetchurl appends $NIX_CURL_FLAGS to its +# curl invocation (last --user-agent wins) and passes it into the fixed-output +# derivation sandbox via impureEnvVars, so we override the User-Agent with one +# crates.io accepts. Set inline on the nix-build command rather than via `export` +# because GNU Make's $(shell ...) does not inherit exported variables. +NIX_ENV = NIX_CURL_FLAGS="--user-agent ethrex-ci+https://github.com/lambdaclass/ethrex" + image.raw: - $(eval IMAGE := $(shell nix-build image.nix ${NIX_BUILD_ARGS})/${IMAGE_NAME}) + $(eval IMAGE := $(shell $(NIX_ENV) nix-build image.nix ${NIX_BUILD_ARGS})/${IMAGE_NAME}) cp $(IMAGE) image.raw chmod u+rw image.raw run: image.raw - $(eval RUN_QEMU := $(shell nix-build hypervisor.nix ${NIX_BUILD_ARGS})/bin/run-qemu) + $(eval RUN_QEMU := $(shell $(NIX_ENV) nix-build hypervisor.nix ${NIX_BUILD_ARGS})/bin/run-qemu) $(RUN_QEMU) image.raw clean: From 0e0663dbb4f80dd31d365fd249070b709b9af737 Mon Sep 17 00:00:00 2001 From: ilitteri Date: Wed, 27 May 2026 16:45:25 -0300 Subject: [PATCH 2/3] fix(l2): inject crates.io-friendly User-Agent into the Nix daemon, not the client MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous Makefile NIX_CURL_FLAGS override was inert: install-nix-action runs Nix in multi-user (daemon) mode, so the crate fixed-output derivations are built by the nix-daemon, which does not inherit the caller's environment. The override never reached the crate downloads and they kept 403ing. crates.io returns HTTP 403 for any User-Agent containing the substring "curl/", which is what Nix's fetchurl sends by default ("curl/ Nixpkgs/"). Fix it at the daemon layer via Nix's `impure-env` setting (the documented mechanism for passing env into fixed-output derivations in a multi-user install — its canonical use is https_proxy for the daemon), set through install-nix-action's extra_nix_config in both workflows that build the TDX image. impure-env is honored because the runner is a trusted user. The User-Agent uses the `--user-agent=` form so it stays a single token through impure-env's space-separated parsing and fetchurl's unquoted word-split, and overrides fetchurl's default (curl honors the last --user-agent). Reverts the earlier Makefile change, which only helped single-user/local Nix. --- .github/workflows/pr-main_l2.yaml | 10 ++++++++++ .github/workflows/pr-main_l2_tdx_build.yaml | 10 ++++++++++ crates/l2/tee/quote-gen/Makefile | 13 ++----------- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/.github/workflows/pr-main_l2.yaml b/.github/workflows/pr-main_l2.yaml index 953fe016303..3c31f6e290f 100644 --- a/.github/workflows/pr-main_l2.yaml +++ b/.github/workflows/pr-main_l2.yaml @@ -530,6 +530,16 @@ jobs: - name: Set up Nix uses: cachix/install-nix-action@v31 + with: + # crates.io 403s any User-Agent containing "curl/", which is what Nix's + # fetchurl sends by default, breaking crate downloads during the image + # build. In multi-user (daemon) mode the FOD builds run under the + # nix-daemon and don't see the caller's environment, so override the + # User-Agent via impure-env (honored because the runner is a trusted + # user). Single token (=-form) so it survives word-splitting. + extra_nix_config: | + extra-experimental-features = configurable-impure-env + impure-env = NIX_CURL_FLAGS=--user-agent=ethrex-ci+https://github.com/lambdaclass/ethrex - name: Set up QEMU run: | diff --git a/.github/workflows/pr-main_l2_tdx_build.yaml b/.github/workflows/pr-main_l2_tdx_build.yaml index 4147581943a..41899c30d7b 100644 --- a/.github/workflows/pr-main_l2_tdx_build.yaml +++ b/.github/workflows/pr-main_l2_tdx_build.yaml @@ -49,6 +49,16 @@ jobs: - name: Set up Nix uses: cachix/install-nix-action@v31 + with: + # crates.io 403s any User-Agent containing "curl/", which is what Nix's + # fetchurl sends by default, breaking crate downloads during the image + # build. In multi-user (daemon) mode the FOD builds run under the + # nix-daemon and don't see the caller's environment, so override the + # User-Agent via impure-env (honored because the runner is a trusted + # user). Single token (=-form) so it survives word-splitting. + extra_nix_config: | + extra-experimental-features = configurable-impure-env + impure-env = NIX_CURL_FLAGS=--user-agent=ethrex-ci+https://github.com/lambdaclass/ethrex - name: Build image run: | diff --git a/crates/l2/tee/quote-gen/Makefile b/crates/l2/tee/quote-gen/Makefile index 9b30558c454..59776347992 100644 --- a/crates/l2/tee/quote-gen/Makefile +++ b/crates/l2/tee/quote-gen/Makefile @@ -6,22 +6,13 @@ NIXPKGS_URL = https://github.com/NixOS/nixpkgs/archive/3fcbdcfc707e0aa42c541b774 GIT_REV := $(shell git rev-parse --short=7 HEAD) NIX_BUILD_ARGS = --no-out-link -I nixpkgs=$(NIXPKGS_URL) --argstr gitRev "$(GIT_REV)" -# crates.io returns HTTP 403 for any User-Agent containing "curl/", which is what -# Nix's fetchurl sends by default (`curl/ Nixpkgs/`). That breaks every -# crate download during the image build. fetchurl appends $NIX_CURL_FLAGS to its -# curl invocation (last --user-agent wins) and passes it into the fixed-output -# derivation sandbox via impureEnvVars, so we override the User-Agent with one -# crates.io accepts. Set inline on the nix-build command rather than via `export` -# because GNU Make's $(shell ...) does not inherit exported variables. -NIX_ENV = NIX_CURL_FLAGS="--user-agent ethrex-ci+https://github.com/lambdaclass/ethrex" - image.raw: - $(eval IMAGE := $(shell $(NIX_ENV) nix-build image.nix ${NIX_BUILD_ARGS})/${IMAGE_NAME}) + $(eval IMAGE := $(shell nix-build image.nix ${NIX_BUILD_ARGS})/${IMAGE_NAME}) cp $(IMAGE) image.raw chmod u+rw image.raw run: image.raw - $(eval RUN_QEMU := $(shell $(NIX_ENV) nix-build hypervisor.nix ${NIX_BUILD_ARGS})/bin/run-qemu) + $(eval RUN_QEMU := $(shell nix-build hypervisor.nix ${NIX_BUILD_ARGS})/bin/run-qemu) $(RUN_QEMU) image.raw clean: From 3e5f68038265d3318b41c5795f4833af95dcf801 Mon Sep 17 00:00:00 2001 From: ilitteri Date: Wed, 27 May 2026 16:48:42 -0300 Subject: [PATCH 3/3] fix(l2): use curl glued -A form for the crates.io User-Agent override MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The impure-env override reached the daemon's crate fetches, but curl rejected the value: `curl: option --user-agent=ethrex-ci+...: is unknown`. curl does not accept the `--long=value` form — it requires a space — but impure-env splits on spaces, so the value cannot contain one. Use curl's glued short option `-A`, a single space-free token curl parses correctly, which still overrides fetchurl's default User-Agent (last occurrence wins). --- .github/workflows/pr-main_l2.yaml | 6 ++++-- .github/workflows/pr-main_l2_tdx_build.yaml | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/workflows/pr-main_l2.yaml b/.github/workflows/pr-main_l2.yaml index 3c31f6e290f..4f4f2712854 100644 --- a/.github/workflows/pr-main_l2.yaml +++ b/.github/workflows/pr-main_l2.yaml @@ -536,10 +536,12 @@ jobs: # build. In multi-user (daemon) mode the FOD builds run under the # nix-daemon and don't see the caller's environment, so override the # User-Agent via impure-env (honored because the runner is a trusted - # user). Single token (=-form) so it survives word-splitting. + # user). Use curl's glued short option `-A`: a single space-free + # token that survives impure-env's space-separated parsing and + # fetchurl's unquoted word-split (curl rejects the --user-agent=value form). extra_nix_config: | extra-experimental-features = configurable-impure-env - impure-env = NIX_CURL_FLAGS=--user-agent=ethrex-ci+https://github.com/lambdaclass/ethrex + impure-env = NIX_CURL_FLAGS=-Aethrex-ci+https://github.com/lambdaclass/ethrex - name: Set up QEMU run: | diff --git a/.github/workflows/pr-main_l2_tdx_build.yaml b/.github/workflows/pr-main_l2_tdx_build.yaml index 41899c30d7b..cb3c4ae54cf 100644 --- a/.github/workflows/pr-main_l2_tdx_build.yaml +++ b/.github/workflows/pr-main_l2_tdx_build.yaml @@ -55,10 +55,12 @@ jobs: # build. In multi-user (daemon) mode the FOD builds run under the # nix-daemon and don't see the caller's environment, so override the # User-Agent via impure-env (honored because the runner is a trusted - # user). Single token (=-form) so it survives word-splitting. + # user). Use curl's glued short option `-A`: a single space-free + # token that survives impure-env's space-separated parsing and + # fetchurl's unquoted word-split (curl rejects the --user-agent=value form). extra_nix_config: | extra-experimental-features = configurable-impure-env - impure-env = NIX_CURL_FLAGS=--user-agent=ethrex-ci+https://github.com/lambdaclass/ethrex + impure-env = NIX_CURL_FLAGS=-Aethrex-ci+https://github.com/lambdaclass/ethrex - name: Build image run: |