Skip to content

fix(github): avoid auth on release asset downloads#9060

Merged
jdx merged 1 commit intojdx:mainfrom
risu729:fix/github-release-asset-auth
Apr 17, 2026
Merged

fix(github): avoid auth on release asset downloads#9060
jdx merged 1 commit intojdx:mainfrom
risu729:fix/github-release-asset-auth

Conversation

@risu729
Copy link
Copy Markdown
Contributor

@risu729 risu729 commented Apr 12, 2026

Summary

  • skip GitHub token lookup for signed release asset CDN hosts (objects.githubusercontent.com, objects-origin.githubusercontent.com, and release-assets.githubusercontent.com)
  • keep auth for supported GitHub content hosts such as raw.githubusercontent.com
  • add regression coverage for release asset hosts with GITHUB_TOKEN set

Refs #8865

Tests

  • mise run format
  • cargo test github::tests

This PR description was AI-generated.

@risu729 risu729 marked this pull request as draft April 12, 2026 04:20
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request refactors GitHub host handling to exclude specific release asset hosts, such as objects.githubusercontent.com, from receiving authentication tokens. It introduces helper functions is_githubusercontent_auth_host and is_github_release_asset_host to distinguish between hosts that require authentication and those that do not. The changes also include new unit tests and a thread-safe test helper for environment variable manipulation. I have no feedback to provide.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 12, 2026

Greptile Summary

This PR fixes a bug where GitHub auth tokens were being forwarded to release-asset CDN hosts (objects.githubusercontent.com, objects-origin.githubusercontent.com, release-assets.githubusercontent.com) that use signed URLs for access control and don't expect — or tolerate — Authorization headers. The fix introduces is_github_release_asset_host and the public is_githubusercontent_auth_host predicate, plumbs the latter into http.rs, and adds an early-return guard in resolve_token. A new with_github_token test helper properly saves and restores the three relevant env vars, and two new unit tests verify both the host classification logic and the header-emission behaviour.

Confidence Score: 5/5

Safe to merge — the core fix is correct and well-tested; the only finding is a minor test-infrastructure concern.

The production logic is sound: CDN hosts are correctly excluded from token lookup in both resolve_token and host_auth_headers, and the existing raw.githubusercontent.com behaviour is preserved. The only finding is a P2 test-helper panic-safety gap that does not affect production code or the correctness of the new tests under normal conditions.

No files require special attention for merge readiness.

Important Files Changed

Filename Overview
src/github.rs Adds is_github_release_asset_host / is_githubusercontent_auth_host predicates, adds early-return in resolve_token, and introduces with_github_token test helper — env-var restoration is correct for the happy path but not panic-safe.
src/http.rs Replaces ends_with(".githubusercontent.com") with is_githubusercontent_auth_host in host_auth_headers, correctly excluding CDN hosts from the GitHub auth path.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[HTTP request URL] --> B{host_auth_headers}
    B --> C{is_github?}
    C -->|host == github.com / api.github.com| D[get_headers → resolve_token]
    C -->|is_githubusercontent_auth_host| D
    C -->|is_gh_host| D
    C -->|objects.githubusercontent.com\nobjects-origin.githubusercontent.com\nrelease-assets.githubusercontent.com| E[No auth headers ✓]
    C -->|other| F[Non-GitHub auth or none]
    D --> G{resolve_token}
    G -->|is_github_release_asset_host| H[return None — no token]
    G -->|github.com / api.github.com\nraw.githubusercontent.com etc.| I[Token lookup → Bearer header]
Loading

Reviews (2): Last reviewed commit: "fix(github): avoid auth on release asset..." | Re-trigger Greptile

Comment thread src/github.rs
@risu729 risu729 force-pushed the fix/github-release-asset-auth branch from 29effa2 to 61b4be5 Compare April 12, 2026 20:13
@risu729 risu729 marked this pull request as ready for review April 12, 2026 20:22
@Khaled-El-Mansoury-EG
Copy link
Copy Markdown

Hi @jdx,
I appreciate you are busy, but if you get a chance, please could you review this PR?
I'm unable to use any mise releases beyond v2026.3.14 as tools from the GitHub backend fail to download. Thank you.

@jdx jdx merged commit 1be12e0 into jdx:main Apr 17, 2026
34 checks passed
@risu729 risu729 deleted the fix/github-release-asset-auth branch April 17, 2026 18:47
jdx pushed a commit that referenced this pull request Apr 18, 2026
### 🐛 Bug Fixes

- **(backend)** respect install_before in latest lookup by @risu729 in
[#9193](#9193)
- **(backend)** route explicit latest through stable lookup by @risu729
in [#9228](#9228)
- **(backends)** deprecate b shorthand by @risu729 in
[#9234](#9234)
- **(config)** warn for deprecated env keys by @risu729 in
[#9205](#9205)
- **(config)** treat enable_tools empty as disable-all by @risu729 in
[#9108](#9108)
- **(github)** avoid auth on release asset downloads by @risu729 in
[#9060](#9060)
- **(gitlab)** warn when glab OAuth2 token is expired by @stanhu in
[#9195](#9195)
- **(npm)** honor install_before without day drift by @risu729 in
[#9157](#9157)
- **(npm)** warn on old bun and pnpm for install_before by @risu729 in
[#9232](#9232)
- **(pipx)** honor install_before for uv and pipx installs by @risu729
in [#9190](#9190)
- **(registry)** allow shfmt on Windows by @zeitlinger in
[#9191](#9191)

### 🚜 Refactor

- **(backend)** remove unused rolling release helper by @risu729 in
[#9175](#9175)
- **(backend)** use file util for removals by @risu729 in
[#9206](#9206)

### 📚 Documentation

- **(config)** clarify always_keep_download behavior by @risu729 in
[#9235](#9235)
- **(configuration)** add rust to idiomatic version files by @jjt in
[#9233](#9233)
- **(contributing)** expand contribution guide introduction by
@marianwolf in [#9208](#9208)
- **(github)** document multiple release assets workaround by @risu729
in [#9236](#9236)

### 📦️ Dependency Updates

- update actions/setup-node action to v6 by @renovate[bot] in
[#9183](#9183)
- update dependency @types/node to v25 by @renovate[bot] in
[#9187](#9187)
- update crazy-max/ghaction-import-gpg action to v7 by @renovate[bot] in
[#9186](#9186)
- update actions/cache action to v5 by @renovate[bot] in
[#9181](#9181)
- update amannn/action-semantic-pull-request action to v6 by
@renovate[bot] in [#9184](#9184)
- update apple-actions/import-codesign-certs action to v6 by
@renovate[bot] in [#9185](#9185)
- update dependency eslint to v10 by @renovate[bot] in
[#9200](#9200)
- update dependency toml to v4 by @renovate[bot] in
[#9201](#9201)
- update rust crate reqwest to 0.13 by @renovate[bot] in
[#9171](#9171)
- update ghcr.io/jdx/mise:deb docker digest to 523d826 by @renovate[bot]
in [#9198](#9198)
- update ghcr.io/jdx/mise:alpine docker digest to 05617e0 by
@renovate[bot] in [#9196](#9196)
- update ghcr.io/jdx/mise:rpm docker digest to c1992f9 by @renovate[bot]
in [#9199](#9199)
- update ghcr.io/jdx/mise:copr docker digest to 90db6cd by
@renovate[bot] in [#9197](#9197)
- update taiki-e/install-action digest to 58e8625 by @renovate[bot] in
[#9209](#9209)
- update fedora docker tag to v45 by @renovate[bot] in
[#9213](#9213)
- update docker/setup-buildx-action action to v4 by @renovate[bot] in
[#9212](#9212)
- update docker/metadata-action action to v6 by @renovate[bot] in
[#9211](#9211)
- update docker/login-action action to v4 by @renovate[bot] in
[#9210](#9210)
- update dependency typescript to v6 by @renovate[bot] in
[#9202](#9202)
- update docker/build-push-action action to v7 by @renovate[bot] in
[#9203](#9203)
- update github artifact actions (major) by @renovate[bot] in
[#9215](#9215)
- update rust crate duct to v1 by @renovate[bot] in
[#9220](#9220)
- update rust crate demand to v2 by @renovate[bot] in
[#9219](#9219)
- update rust crate clx to v2 by @renovate[bot] in
[#9218](#9218)
- update nick-fields/retry action to v4 by @renovate[bot] in
[#9217](#9217)
- update jdx/mise-action action to v4 by @renovate[bot] in
[#9216](#9216)
- update rust crate self_update to 0.44 by @renovate[bot] in
[#9174](#9174)
- migrate eslint config to flat format for v10 compat by @jdx in
[#9222](#9222)
- update actions/checkout action to v6 by @renovate[bot] in
[#9182](#9182)
- update rust crate toml to v1 by @renovate[bot] in
[#9225](#9225)
- update rust crate versions to v7 by @renovate[bot] in
[#9226](#9226)
- update rust crate which to v8 by @renovate[bot] in
[#9227](#9227)
- update rust crate rmcp to v1 by @renovate[bot] in
[#9221](#9221)

### 📦 Registry

- add sheldon by @3w36zj6 in
[#9104](#9104)
- add pocketbase by @ranfdev in
[#9123](#9123)
- add worktrunk ([aqua:max-sixty/worktrunk,
cargo:worktrunk](https://github.com/max-sixty/worktrunk,
cargo:worktrunk))#1 by @edouardr in
[#8796](#8796)
- add dependency-check
([aqua:dependency-check/DependencyCheck](https://github.com/dependency-check/DependencyCheck))
by @kapitoshka438 in [#9204](#9204)
- add janet by @ranfdev in
[#9241](#9241)

### New Contributors

- @ranfdev made their first contribution in
[#9241](#9241)
- @jjt made their first contribution in
[#9233](#9233)
- @marianwolf made their first contribution in
[#9208](#9208)
- @edouardr made their first contribution in
[#8796](#8796)

## 📦 Aqua Registry Updates

#### New Packages (3)

- [`LargeModGames/spotatui`](https://github.com/LargeModGames/spotatui)
-
[`android-sms-gateway/cli`](https://github.com/android-sms-gateway/cli)
- [`velero-io/velero`](https://github.com/velero-io/velero)

#### Updated Packages (1)

- [`skim-rs/skim`](https://github.com/skim-rs/skim)
jdx pushed a commit that referenced this pull request Apr 21, 2026
## Summary

- Stop adding GitHub `Authorization` and `X-GitHub-Api-Version` headers
to non-API GitHub URLs, including `github.com` release browser downloads
and `*.githubusercontent.com` content/CDN hosts.
- Keep GitHub auth/version headers for REST API URLs: `api.github.com`,
GHES-style `HOSTNAME/api/v3`, and GHE.com data-residency
`api.SUBDOMAIN.ghe.com`.
- Remove the stale `is_gh_host` HTTP routing branch so GitHub header
generation is reached only for URLs classified as GitHub REST API URLs.
- Preserve API asset downloads by keeping `Accept:
application/octet-stream` on `/releases/assets/` API URLs only.
- Add regression coverage for browser/download hosts, GitHub API URLs,
GHES API paths, GHE.com data-residency API hosts, and GHES/GHE.com
browser URLs that must not receive auth headers.

## Root Cause

The token/header policy added for GitHub-related hosts was too broad.
Public release browser URLs on `github.com` can reject requests when a
GitHub token is attached, which forces mise to fall back to the API
asset URL. That fallback still works, but it loses the clearer browser
download URL/filename path and increases API usage, which earlier work
tried to avoid.

## GHE Notes

- GitHub Enterprise Cloud without data residency uses the normal
GitHub.com REST API host.
- GitHub Enterprise Server uses `https://HOSTNAME/api/v3/...`, so this
keeps auth on non-`github.com` `/api/v3` URLs.
- GitHub Enterprise Cloud with data residency uses `SUBDOMAIN.ghe.com`
for the web host and `api.SUBDOMAIN.ghe.com` for REST API. Token lookup
tries `SUBDOMAIN.ghe.com` before `api.SUBDOMAIN.ghe.com`, matching the
platform hostname users authenticate with, while still not sending
headers to the web/download host.
- GHE.com web hosts are explicitly excluded from the GHES `/api/v3` path
matcher; only `api.SUBDOMAIN.ghe.com` is treated as a GHE.com REST API
host.

## Review Follow-up

- Addressed review feedback to remove the redundant `is_gh_host` branch
from `src/http.rs` now that `github::get_headers` and
`is_github_api_url` enforce API-only header behavior.
- Addressed review feedback to exclude `.ghe.com` web hosts from the
GHES `/api/v3` path arm.
- Added the missing GHES browser download no-auth regression case.
- Left `MISE_GITHUB_ENTERPRISE_TOKEN` precedence unchanged for
non-`github.com` API hosts, including `api.SUBDOMAIN.ghe.com`, because
this PR is scoped to header destination safety and the existing token
precedence treats non-`github.com` GitHub Enterprise hosts as enterprise
hosts.

## References

- Fixes #8865
- Follow-up to #9060
- Rebalances host matching added in
#8692
- Preserves the API fallback behavior from
#6496
- Private release browser URLs still require API asset downloads:
https://github.com/orgs/community/discussions/47453
- GitHub release asset API/browser behavior:
https://docs.github.com/en/rest/releases/assets?apiVersion=2022-11-28#get-a-release-asset
- GitHub API version header scope/defaults:
https://docs.github.com/en/rest/about-the-rest-api/api-versions
- GHES REST API base URL:
https://docs.github.com/en/enterprise-server@3.17/rest/using-the-rest-api/getting-started-with-the-rest-api
- GHE.com data-residency API and network details:
https://docs.github.com/en/enterprise-cloud@latest/admin/data-residency/about-github-enterprise-cloud-with-data-residency
and
https://docs.github.com/en/enterprise-cloud@latest/admin/data-residency/network-details-for-ghecom

## Tests

- `cargo fmt --all`
- `cargo test --all-features github::tests`
- `git diff --check`
- `curl -sSIL` on the reported `github.com/cuotos/ecs-exec-pf` asset URL
returns `200` and redirects to `release-assets.githubusercontent.com`
without auth headers.

Notes: `mise run format` did not discover tasks in this checkout, so I
ran `cargo fmt --all` directly. Broad `cargo clippy --all-features --
-Dwarnings` and `cargo clippy -p mise --all-features --no-deps --
-Dwarnings` currently fail on unrelated pre-existing clippy warnings
outside this change.

*This PR description was AI-generated.*
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.

3 participants