Can't authenticate with Actions token for PR event

I’m trying to use GitHub Actions to push a container to the container registry on a pull request. However, push with the token (GITHUB_TOKEN) for GitHub Actions pull_request (or pull_request_target) event fails with the following error:

denied: installation not allowed to Write organization package

I’ve created a minimal reproducible repo in GitHub - ylemkimon/pull-request-container, and you can see it succeeds on push event, but fails on pull_request event.

Furthermore, it fails to pull the image with the specific tag with the following error:

pull access denied for ghcr.io/<org>/<name>, repository does not exist or may require 'docker login': denied: installation not allowed to Read organization package
4 Likes

Hi @ylemkimon,

Do you know if the following read also fails if you use pull_request_target ?

Yes, it fails: see Update README.md · ylemkimon/pull-request-container@7f995b1 · GitHub.

Correction: whether the tag is specified seems to not matter, rather the visibility of the package matters, i.e., it succeeds to pull a public container.

Thanks for the information. I’ll see if I can reproduce this!

i can reproduce it as well in my repositories. Back to using PAT unfortunately. Hope it can be fixed soon!

My issue is not exactly the same, but similar to the issue described here.

GitHub Actions triggered by a Pull Request fails to push container images to GitHub Container Registry (ghcr.io) with GITHUB_TOKEN. 403 Forbidden seems to be the cause (link).

However, GitHub Actions triggered by a commit directly to main branch successfully pushed the images to ghcr.io with GITHUB_TOKEN (link). I wonder why the two cases end with different results despite exactly the same code.

If I use PAT in GitHub Actions in Pull Request, pushing to ghcr.io is successfully finished.

FYI, the problem still persists even if packages: write permission is explicitly given with the new feature: GitHub Actions: Control permissions for GITHUB_TOKEN - GitHub Changelog.

Hi @ylemkimon,

This is a bit confusing, but permissions for ghcr.io is independent from this feature.

To allow a workflow token to push a ghcr.io image, you will need to use the Actions access setting of the container package. You can use this to grant a repository read or write access to your container package.

Could you try using this option to grant write access to your package and let me know how you get on?

The Actions access is already given. However, I’ve suspected that there may be an error in the default GitHub token permission logic and tried setting permissions manually. Nevertheless, as before, it didn’t work.

Hi @ylemkimon,

I’ve managed to reproduce this and think I know what’s going wrong.

  1. When a run is triggered by the pull_request event, the GITHUB_TOKEN has the read:packages scope but not the write:packages scope
  2. When a run is triggered by the pull_request event, secrets are available if the pull request originated from the local repository

As @oshothebig discovered, the workaround is to use a secret with a PAT that includes the write:packages scope. That way pull requests originating from the local repository are able to publish images to ghcr.io.

Does that make sense?

This wouldn’t be the case as it cannot even read (pull) a package:

pull access denied for ghcr.io/<org>/<name>, repository does not exist or may require 'docker login': denied: installation not allowed to Read organization package

Did the pull request originate from the local repository?

I tried cloning your example repo and opened a local pull request:

It looks like pulling the image was successful:

For me there’s a clear issue here. It’s not possible to use the GITHUB_TOKEN to push images to the ghcr.io when the workflow is triggered by a pull_request event.

I can reproduce it the same way as others have already reported here.

This could have been even intentional by design. Sometimes anyone can open a pull request and you don’t want the same permissions granted to the workflow in this case.

At the same time, it is perfectly expected that this could be addressed by explicitly assigning the “packages: write” permission in the workflow.

The documentation is strongly encouraging the use of GITHUB_TOKEN instead of PAT: Using GitHub Packages with GitHub Actions - GitHub Docs

I personally would like to see this fixed somehow. My best guess is by being able to manage the permissions in the yaml file itself as already pointed out.

An example of a use case:

  1. A workflow builds Docker images of each PR branch
  2. The built images are pushed to ghcr.io so they can be used on subsequent runs of the same branch, effectively using ghcr.io as a Docker cache.
  3. dependabot is setup to open PRs for dependency updates
  4. dependabot can’t use the workflow since it’s considered external

I don’t know what the solution is here. Adding dependabot as a collaborator on the private repo?

Regardless of dependabot, the pull_request event doesn’t even work when I, a repo owner, open a PR.

Thanks, I can confirm this. It seems pull_request and pull_request_target can’t read or write ghcr.io images.

I think the only workaround would be use use pull_request_target and store a secret with a read:packages or write:packages scoped PAT.

1 Like

@jcansdale This finding then is in conflict with the published documentation. If so, it may be appropriate to have warning/notice there to alert developers to the current limitations and that using a PAT is still necessary for private packages.

Hi @mroach,

I’ve been digging into this some more. Could you try deleting your container package and doing the first push using the built-in workflow token? If you do this, I think you’ll find it works (even for private images).

Please let me know how you get on!

@jcansdale That doesn’t work. I suspect part of the problem would be that since the package was deleted, there’s no longer an interface to set that the repository’s actions are granted write permission on it. So then I get a:

denied: installation not allowed to Create organization package

I can also confirm that it doesn’t working deleting the container package to let the first push happen from the workflow.

I would love to be proven wrong, but for me there’s no doubt there’s an issue here.

Should this be reported as an issue? if so, I’m happy to contribute.

The exact point in my workflow where I picked this issue can be found here: quarkus/ci.yml at bdcdea81bed6cc6647ddbb6adfc0cd2f4e2952d9 · juliaaano/quarkus · GitHub