Skip to content

fix(l2): override Nix daemon User-Agent so crates.io stops 403ing the TDX image build#6739

Merged
ilitteri merged 3 commits into
mainfrom
fix/nix-image-crates-io-user-agent
May 27, 2026
Merged

fix(l2): override Nix daemon User-Agent so crates.io stops 403ing the TDX image build#6739
ilitteri merged 3 commits into
mainfrom
fix/nix-image-crates-io-user-agent

Conversation

@ilitteri
Copy link
Copy Markdown
Collaborator

@ilitteri ilitteri commented May 27, 2026

Motivation

The TDX image build (make image.raw, in the L2 TDX build and L2 (without proving) workflows) is failing on main and on every PR. 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 User-Agent: curl/<ver> Nixpkgs/<ver>, so every crate download 403s and the build fails:

> trying https://crates.io/api/v1/crates/ark-ec/0.5.0/download
> curl: (22) The requested URL returned error: 403
error: cannot download crate-ark-ec-0.5.0.tar.gz from any mirror

It's an external crates.io policy change, which is why it breaks main and all PRs at once.

Description

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 fix therefore has to reach the daemon, via Nix's impure-env setting — the documented mechanism for passing environment into fixed-output derivations in a multi-user install (its canonical use is https_proxy for the daemon). It is honored because the CI runner is a trusted user.

fetchurl appends $NIX_CURL_FLAGS to its curl invocation (curl honors the last --user-agent), so we set it to a curl/-free User-Agent. The --user-agent=<value> form keeps it a single token through impure-env's space-separated parsing and fetchurl's unquoted word-split.

Applied to both workflows that run make image.raw. The earlier Makefile-level NIX_CURL_FLAGS override is reverted — it was inert in daemon mode (only single-user/local Nix would have seen it).

How to Test

# crates.io blocks the curl/ UA, accepts the override:
curl -sS -o /dev/null -w '%{http_code}\n' -A 'curl/8.7.1'                                    -L https://crates.io/api/v1/crates/ark-ec/0.5.0/download   # 403
curl -sS -o /dev/null -w '%{http_code}\n' -A 'ethrex-ci+https://github.com/lambdaclass/ethrex' -L https://crates.io/api/v1/crates/ark-ec/0.5.0/download   # 200

Verified end-to-end via CI on this PR (the L2 TDX build check).

…X image build

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/<ver> Nixpkgs/<ver>",
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.
Copilot AI review requested due to automatic review settings May 27, 2026 19:33
@ilitteri ilitteri requested a review from a team as a code owner May 27, 2026 19:33
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 27, 2026

⚠️ Known Issues — intentionally skipped tests

Source: docs/known_issues.md

Known Issues

Tests intentionally excluded from CI. Source of truth for the Known
Issues
section the L1 workflow appends to each ef-tests job summary
and posts as a sticky PR comment.

EF Tests — Stateless coverage narrowed to EIP-8025 optional-proofs

make -C tooling/ef_tests/blockchain test calls test-stateless-zkevm
instead of test-stateless. The zkevm@v0.3.3 fixtures are filled against
bal@v5.6.1, out of sync with current bal spec; the broad target trips ~549
fixtures. Re-broaden once the zkevm bundle is regenerated.

Why and resolution path

PR #6527 broadened
test-stateless to extract the entire for_amsterdam/ tree from the
zkevm bundle and run all of it under --features stateless; combined with
this branch's bal-devnet-7 semantics that scope produces ~549
GasUsedMismatch / ReceiptsRootMismatch /
BlockAccessListHashMismatch failures.

test-stateless-zkevm filters cargo to the eip8025_optional_proofs
suite, which still validates the stateless harness without the bal-version
mismatch.

Re-broaden by switching test: back to test-stateless in
tooling/ef_tests/blockchain/Makefile once the zkevm bundle is regenerated
against the current bal spec.

@github-actions
Copy link
Copy Markdown

🤖 Kimi Code Review

The fix is correct and properly addresses the crates.io User-Agent blocking issue. A few observations:

Line 12-16 (Makefile)
The comment accurately explains the crates.io 403 issue and the Nix impureEnvVars mechanism. The inline environment variable assignment works correctly with GNU Make's $(shell ...) function.

Line 19 & 23 (Makefile)
The $(NIX_ENV) prefix is applied consistently to both nix-build invocations. The shell command expansion $(shell $(NIX_ENV) nix-build ...) will correctly set the environment variable for that specific command invocation.

Minor suggestion:
Consider preserving any existing NIX_CURL_FLAGS in case users have other curl options they need to pass:

NIX_ENV = NIX_CURL_FLAGS="$(NIX_CURL_FLAGS) --user-agent ethrex-ci+https://github.com/lambdaclass/ethrex"

However, given that this is a CI/build-specific Makefile and the primary use case is overriding the problematic default User-Agent, the current approach is acceptable.

Verdict: The change is correct, well-documented, and addresses the infrastructure issue without introducing security or correctness risks.


Automated review by Kimi (Moonshot AI) · kimi-k2.5 · custom prompt

@github-actions
Copy link
Copy Markdown

🤖 Claude Code Review

PR #6739 Review — fix(l2): set Nix fetchurl User-Agent so crates.io stops 403ing the TDX image build

Overview

A targeted one-file fix for a CI-wide breakage: crates.io now returns HTTP 403 to any request whose User-Agent contains "curl/". Nix's fetchurl (used by rustPlatform.importCargoLock when vendoring crates for the TDX quote-gen image) sends curl/<ver> Nixpkgs/<ver> by default, causing every crate download to fail. The fix introduces a NIX_ENV Make variable that injects NIX_CURL_FLAGS inline on the two affected nix-build invocations to override the User-Agent.


Correctness

  • Mechanism is sound. fetchurl passes NIX_CURL_FLAGS through impureEnvVars into the fixed-output derivation sandbox, then appends it to the curl call. curl honors the last --user-agent flag on the command line, so appending overrides the default — exactly as described.
  • Inline assignment is the right call. $(shell ...) in GNU Make spawns a sub-shell that does not inherit variables export-ed inside the same Makefile parse phase. Setting the variable inline (NIX_ENV nix-build ...) is the correct workaround.
  • Word-splitting handled correctly. NIX_CURL_FLAGS is word-split by fetchurl when passed to curl. The value has exactly one space (between --user-agent and the agent string); the agent string itself is space-free. That produces two tokens — --user-agent and ethrex-ci+https://github.com/lambdaclass/ethrex — which is the correct curl argument syntax.
  • Coverage is complete. Both nix-build invocations (image.nix in image.raw, hypervisor.nix in run) are patched. The clean target does not call nix-build, so nothing is missed.

Potential Issues / Risks

  • User-Agent value format. crates.io's published policy asks for a value that identifies the client and includes contact info (commonly name/version (contact@example.com) or similar). ethrex-ci+https://github.com/lambdaclass/ethrex sidesteps the "curl/" substring check and points to the repo for contact, but it is non-standard. In practice crates.io does not appear to enforce strict UA format beyond the curl/ exclusion, so this works today. It is worth knowing that if crates.io tightens the policy further (e.g., requiring a version token or a proper contact address), this string would need revisiting.

  • Fork / downstream portability. The agent string hard-codes the lambdaclass GitHub URL. If someone forks the repo and rebuilds the TDX image under a different org, the User-Agent will still say lambdaclass/ethrex. This is a minor cosmetic issue — the URL is advisory, not validated — but worth a note.

  • No fallback if NIX_CURL_FLAGS is already set in the environment. If a caller exports NIX_CURL_FLAGS before invoking make, the inline assignment wins (inline variable assignments in shell command prefixes shadow the environment), which is the desired behavior here. This is fine and consistent with the expected use in CI.


Style / Comment Length

The 7-line comment block is thorough, which aids future maintainers who may not know this Nix internals detail. Given that this is a non-obvious workaround for an external policy change, the verbosity is justified. No changes needed.


Summary

The fix is correct, minimal, well-explained, and covers all affected targets. The only non-trivial concern is the informality of the User-Agent string — not a blocker, but if crates.io ever enforces a stricter format, the string at line 13 of the Makefile is the single place to update.

Verdict: LGTM with no blocking issues.


Automated review by Claude (Anthropic) · sonnet · custom prompt

@github-actions
Copy link
Copy Markdown

🤖 Codex Code Review

No findings.

The patch is narrowly scoped and looks correct in crates/l2/tee/quote-gen/Makefile. Prefixing the two existing nix-build invocations with NIX_CURL_FLAGS at lines 19 and 24 should only affect fetch-time HTTP headers during the Nix build, with no impact on Ethereum execution logic, gas accounting, consensus behavior, or Rust/runtime safety.

Residual note: I did not execute the Nix build in this environment, so this review is static; the only practical thing to confirm outside review is that your pinned Nix tooling still propagates NIX_CURL_FLAGS into the relevant fetchurl derivations as expected.


Automated review by OpenAI Codex · gpt-5.4 · custom prompt

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 27, 2026

Greptile Summary

This PR fixes a CI-blocking issue where crates.io began returning HTTP 403 to requests with a curl/-prefixed User-Agent, which is what Nix's fetchurl sends by default. The fix sets NIX_CURL_FLAGS=\"--user-agent ethrex-ci+https://github.com/lambdaclass/ethrex\" inline on the nix-build invocations in the TDX quote-gen Makefile.

  • Adds a NIX_ENV make variable and prepends it to nix-build in both the image.raw and run targets — the only two places that call nix-build and trigger crate downloads.
  • Uses inline assignment rather than export because GNU Make's $(shell …) doesn't inherit exported variables, and keeps the user-agent value space-free because fetchurl word-splits $NIX_CURL_FLAGS unquoted.

Confidence Score: 5/5

Safe to merge — single-file change that corrects an environment variable passed to nix-build, with no logic changes to the build outputs themselves.

The change is minimal and self-contained: it adds one Make variable and prepends it to the two existing nix-build invocations. The user-agent value is space-free (avoiding word-split pitfalls in fetchurl), the inline assignment correctly sidesteps the GNU Make $(shell) inheritance limitation, and both targets that trigger crate downloads are covered.

No files require special attention.

Important Files Changed

Filename Overview
crates/l2/tee/quote-gen/Makefile Adds NIX_ENV variable with NIX_CURL_FLAGS override to bypass crates.io's 403 on curl User-Agent; applied to both image.raw and run targets. Logic is sound and well-commented.

Reviews (1): Last reviewed commit: "fix(l2): set Nix fetchurl User-Agent so ..." | Re-trigger Greptile

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the TDX quote-gen image build entrypoint to work around crates.io returning HTTP 403 for requests whose User-Agent contains curl/, by overriding Nix fetchurl’s curl flags via NIX_CURL_FLAGS during nix-build invocations.

Changes:

  • Add NIX_ENV to inject NIX_CURL_FLAGS with a crates.io-accepted User-Agent.
  • Apply that environment override to the nix-build calls used by make image.raw and make run.
  • Document the rationale and how the environment variable reaches sandboxed fixed-output derivations.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread crates/l2/tee/quote-gen/Makefile Outdated
Comment on lines +14 to +15
# crates.io accepts. Set inline on the nix-build command rather than via `export`
# because GNU Make's $(shell ...) does not inherit exported variables.
Comment thread crates/l2/tee/quote-gen/Makefile Outdated
# 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"
…t the client

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/<ver> Nixpkgs/<ver>").

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=<value>` 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.
@ilitteri ilitteri requested a review from a team as a code owner May 27, 2026 19:45
@ilitteri ilitteri changed the title fix(l2): set Nix fetchurl User-Agent so crates.io stops 403ing the TDX image build fix(l2): override Nix daemon User-Agent so crates.io stops 403ing the TDX image build May 27, 2026
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<value>`, a single space-free token curl parses correctly, which still
overrides fetchurl's default User-Agent (last occurrence wins).
@ilitteri ilitteri enabled auto-merge May 27, 2026 20:37
@ilitteri ilitteri added this pull request to the merge queue May 27, 2026
Merged via the queue into main with commit e181e62 May 27, 2026
61 checks passed
@ilitteri ilitteri deleted the fix/nix-image-crates-io-user-agent branch May 27, 2026 21:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

L2 Rollup client

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

5 participants