integrations / integrations/terraform-provider-github
data "github_release_asset": download_file_contents uses browser_download_url, fails with fine-grained PATs on private repos
- Dominant language
- Go
- Stars
- 1.2k
- Forks
- 1k
- Avg merge
- 1d 14h
- Merged PRs (30d)
- 8
Description
### Description
The `data "github_release_asset"` data source with `download_file_contents = true` downloads files via `browser_download_url` (the web endpoint at `github.com/…`). Fine-grained personal access tokens (PATs) cannot authenticate against this web endpoint for **private** repositories, resulting in a 404.
The correct approach for authenticated asset downloads is to use the **API endpoint** (`api.github.com/repos/OWNER/REPO/releases/assets/ASSET_ID`) with `Accept: application/octet-stream`, which properly handles both classic and fine-grained PATs.
### Terraform Version
```
1.14.8
```
### Affected Resource(s)
- `data "github_release_asset"` (with `download_file_contents = true`)
### Expected Behavior
When configured with a fine-grained PAT that has `Contents: read` permission on a private repository, `data "github_release_asset"` with `download_file_contents = true` should successfully download the asset.
### Actual Behavior
The data source returns a 404 error because it fetches the asset using `browser_download_url` (`https://github.com/OWNER/REPO/releases/download/TAG/FILENAME`), which does not accept fine-grained PAT authentication for private repositories.
### Root Cause
In [`data_source_github_release_asset.go`](https://github.com/integrations/terraform-provider-github/blob/main/github/data_source_github_release_asset.go), the download path uses `asset.GetBrowserDownloadURL()`:
```go
downloadUrl := asset.GetBrowserDownloadURL()
```
This URL points to the web endpoint (`github.com/…`), not the REST API endpoint (`api.github.com/…`). Fine-grained tokens are not valid for the web endpoint on private repos.
### Suggested Fix
Use the REST API endpoint for the download instead. The API URL is available via `asset.GetURL()` and the download can be performed by sending an authenticated GET request with `Accept: application/octet-stream`.
### Workaround
We currently use `data "external"` with a shell script that calls curl against the API endpoint:
```bash
curl -fsSL \
-H "Authorization: token $TOKEN" \
-H "Accept: application/octet-stream" \
-o "$DEST" \
"$API_URL"
```
where `$API_URL` is `asset.url` from `data "github_release"` (the API endpoint), rather than `browser_download_url`.
Contributor guide
Assessment
This issue has not been assessed yet.