Skip to content

data "github_release_asset": download_file_contents uses browser_download_url, fails with fine-grained PATs on private repos #3324

@TheRealWaldo

Description

@TheRealWaldo

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, the download path uses asset.GetBrowserDownloadURL():

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:

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions