8000 [bug] Fix header parsing by adam-singer · Pull Request #649 · bazeltools/rules_minidock_tools · GitHub
[go: up one dir, main page]

Skip to content

[bug] Fix header parsing - #649

Merged
adam-singer merged 2 commits into
mainfrom
adamsinger/2026-07-15-fix-header-parsing-bug
Jul 15, 2026
Merged

adam-singer merged 2 commits into
mainfrom
adamsinger/2026-07-15-fix-header-parsing-bug

Conversation

@adam-singer
@adam-singer adam-singer commented Jul 15, 2026 •
Copy link
Copy Markdown
Contributor

Problem

puller-app failed to authenticate against gcr.io with an "Invalid auth header" error, even though the exact same code worked fine against Docker Hub.

The root cause is in BearerConfig::from_auth_header (src/registry/http/http_cli/private_impl.rs), which parses the WWW-Authenticate: Bearer ... challenge header returned on a 401. The original implementation split the header into a flat list of tokens using the regex (".*?"|[^",\s]+), then paired up tokens two-at-a-time assuming every key=value pair produces exactly one key= token followed by one "value" token.

That assumption only holds when values are quoted. Docker Hub quotes both realm and service:

Bearer realm="https://auth.docker.io/token",service="registry.docker.io"

gcr.io, however, leaves service unquoted:

Bearer realm="https://gcr.io/v2/token",service=gcr.io

Since there's no quote or comma to stop it, service=gcr.io matches as a single token instead of splitting into service= and gcr.io. This produces an odd-length token list, which trips the pairs.len() % 2 != 0 check and fails with "Invalid auth header" before puller-app ever gets a chance to authenticate.

Fix

Replace the split-then-pair logic with a regex that matches each key=value pair directly: ([a-zA-Z_][a-zA-Z0-9_]*)=("[^"]*"|[^,]*). This correctly handles quoted values, unquoted values, and any mix of the two within the same header, without relying on token-count parity.

Tests

Added coverage in private_impl.rs for the real-world header shapes registries send, in addition to the existing Docker Hub case:

  • gcr.io's unquoted service
  • quoted scope containing a comma (e.g. pull,push)
  • Azure ACR's space-after-comma formatting
  • fully unquoted header (neither realm nor service quoted)
  • fields out of order (service before realm)
  • extra error= param present (RFC 6750 §3)
  • missing service / missing realm (should error)
  • non-Bearer scheme (should error)

All pass via cargo test --lib private_impl, and the full crate test suite (cargo test) shows no regressions.

Manual testing

Build puller-app and run it against gcr.io directly to confirm the auth handshake now succeeds end-to-end:

# one-time toolchain setup if cargo/rustc aren't installed
sudo apt-get install -y cargo && source "$HOME/.cargo/env"

cd rules_minidock_tools
cargo build --release --bin puller-app

./target/release/puller-app --registry gcr.io --repository bazel-public/bazel \
  --digest sha256:08434856d8196632b936dd082b8e03bae0b41346299aedf60a0d481ab427a69f \
  --architecture amd64

Before the fix, this fails with Invalid auth header. After the fix, it succeeds and prints Connected to registry https://gcr.io/ before proceeding to pull the manifest/layers.

To just exercise the parser without building the full binary:

cargo test --lib private_impl

@adam-singer
adam-singer requested a review from non July 15, 2026 21:06
@adam-singer
adam-singer marked this pull request as ready for review July 15, 2026 21:09
These were leftover output from manually running puller-app/merge-app
against gcr.io during verification and were accidentally committed
with the header-parsing fix.
@adam-singer
adam-singer merged commit ce5ffbf into main Jul 15, 2026
3 checks passed
@adam-singer
adam-singer deleted the adamsinger/2026-07-15-fix-header-parsing-bug branch July 15, 2026 21:21
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.

1 participant

0